Completed
Branch EDTR/master (e76d36)
by
unknown
10:43 queued 42s
created
core/helpers/EEH_Template.helper.php 2 patches
Indentation   +962 added lines, -962 removed lines patch added patch discarded remove patch
@@ -5,35 +5,35 @@  discard block
 block discarded – undo
5 5
 use EventEspresso\core\services\loaders\LoaderFactory;
6 6
 
7 7
 if (! function_exists('espresso_get_template_part')) {
8
-    /**
9
-     * espresso_get_template_part
10
-     * 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
11
-     * so not a very useful function at all except that it adds familiarity PLUS filtering based off of the entire template part name
12
-     *
13
-     * @param string $slug The slug name for the generic template.
14
-     * @param string $name The name of the specialised template.
15
-     * @return string        the html output for the formatted money value
16
-     */
17
-    function espresso_get_template_part($slug = null, $name = null)
18
-    {
19
-        EEH_Template::get_template_part($slug, $name);
20
-    }
8
+	/**
9
+	 * espresso_get_template_part
10
+	 * 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
11
+	 * so not a very useful function at all except that it adds familiarity PLUS filtering based off of the entire template part name
12
+	 *
13
+	 * @param string $slug The slug name for the generic template.
14
+	 * @param string $name The name of the specialised template.
15
+	 * @return string        the html output for the formatted money value
16
+	 */
17
+	function espresso_get_template_part($slug = null, $name = null)
18
+	{
19
+		EEH_Template::get_template_part($slug, $name);
20
+	}
21 21
 }
22 22
 
23 23
 
24 24
 if (! function_exists('espresso_get_object_css_class')) {
25
-    /**
26
-     * espresso_get_object_css_class - attempts to generate a css class based on the type of EE object passed
27
-     *
28
-     * @param EE_Base_Class $object the EE object the css class is being generated for
29
-     * @param  string       $prefix added to the beginning of the generated class
30
-     * @param  string       $suffix added to the end of the generated class
31
-     * @return string
32
-     */
33
-    function espresso_get_object_css_class($object = null, $prefix = '', $suffix = '')
34
-    {
35
-        return EEH_Template::get_object_css_class($object, $prefix, $suffix);
36
-    }
25
+	/**
26
+	 * espresso_get_object_css_class - attempts to generate a css class based on the type of EE object passed
27
+	 *
28
+	 * @param EE_Base_Class $object the EE object the css class is being generated for
29
+	 * @param  string       $prefix added to the beginning of the generated class
30
+	 * @param  string       $suffix added to the end of the generated class
31
+	 * @return string
32
+	 */
33
+	function espresso_get_object_css_class($object = null, $prefix = '', $suffix = '')
34
+	{
35
+		return EEH_Template::get_object_css_class($object, $prefix, $suffix);
36
+	}
37 37
 }
38 38
 
39 39
 
@@ -48,672 +48,672 @@  discard block
 block discarded – undo
48 48
 class EEH_Template
49 49
 {
50 50
 
51
-    private static $_espresso_themes = array();
52
-
53
-
54
-    /**
55
-     *    is_espresso_theme - returns TRUE or FALSE on whether the currently active WP theme is an espresso theme
56
-     *
57
-     * @return boolean
58
-     */
59
-    public static function is_espresso_theme()
60
-    {
61
-        return wp_get_theme()->get('TextDomain') == 'event_espresso' ? true : false;
62
-    }
63
-
64
-    /**
65
-     *    load_espresso_theme_functions - if current theme is an espresso theme, or uses ee theme template parts, then
66
-     *    load it's functions.php file ( if not already loaded )
67
-     *
68
-     * @return void
69
-     */
70
-    public static function load_espresso_theme_functions()
71
-    {
72
-        if (! defined('EE_THEME_FUNCTIONS_LOADED')) {
73
-            if (is_readable(EE_PUBLIC . EE_Config::get_current_theme() . '/functions.php')) {
74
-                require_once(EE_PUBLIC . EE_Config::get_current_theme() . '/functions.php');
75
-            }
76
-        }
77
-    }
78
-
79
-
80
-    /**
81
-     *    get_espresso_themes - returns an array of Espresso Child themes located in the /templates/ directory
82
-     *
83
-     * @return array
84
-     */
85
-    public static function get_espresso_themes()
86
-    {
87
-        if (empty(EEH_Template::$_espresso_themes)) {
88
-            $espresso_themes = glob(EE_PUBLIC . '*', GLOB_ONLYDIR);
89
-            if (empty($espresso_themes)) {
90
-                return array();
91
-            }
92
-            if (($key = array_search('global_assets', $espresso_themes)) !== false) {
93
-                unset($espresso_themes[ $key ]);
94
-            }
95
-            EEH_Template::$_espresso_themes = array();
96
-            foreach ($espresso_themes as $espresso_theme) {
97
-                EEH_Template::$_espresso_themes[ basename($espresso_theme) ] = $espresso_theme;
98
-            }
99
-        }
100
-        return EEH_Template::$_espresso_themes;
101
-    }
102
-
103
-
104
-    /**
105
-     * EEH_Template::get_template_part
106
-     * basically a copy of the WordPress get_template_part() function but uses EEH_Template::locate_template() instead,
107
-     * and doesn't add base versions of files so not a very useful function at all except that it adds familiarity PLUS
108
-     * filtering based off of the entire template part name
109
-     *
110
-     * @param string $slug The slug name for the generic template.
111
-     * @param string $name The name of the specialised template.
112
-     * @param array  $template_args
113
-     * @param bool   $return_string
114
-     * @return string        the html output for the formatted money value
115
-     */
116
-    public static function get_template_part(
117
-        $slug = null,
118
-        $name = null,
119
-        $template_args = array(),
120
-        $return_string = false
121
-    ) {
122
-        do_action("get_template_part_{$slug}-{$name}", $slug, $name);
123
-        $templates = array();
124
-        $name      = (string) $name;
125
-        if ($name != '') {
126
-            $templates[] = "{$slug}-{$name}.php";
127
-        }
128
-        // allow template parts to be turned off via something like: add_filter( 'FHEE__content_espresso_events_tickets_template__display_datetimes', '__return_false' );
129
-        if (apply_filters("FHEE__EEH_Template__get_template_part__display__{$slug}_{$name}", true)) {
130
-            EEH_Template::locate_template($templates, $template_args, true, $return_string);
131
-        }
132
-    }
133
-
134
-
135
-    /**
136
-     *    locate_template
137
-     *    locate a template file by looking in the following places, in the following order:
138
-     *        <server path up to>/wp-content/themes/<current active WordPress theme>/
139
-     *        <assumed full absolute server path>
140
-     *        <server path up to>/wp-content/uploads/espresso/templates/<current EE theme>/
141
-     *        <server path up to>/wp-content/uploads/espresso/templates/
142
-     *        <server path up to>/wp-content/plugins/<EE4 folder>/public/<current EE theme>/
143
-     *        <server path up to>/wp-content/plugins/<EE4 folder>/core/templates/<current EE theme>/
144
-     *        <server path up to>/wp-content/plugins/<EE4 folder>/
145
-     *    as soon as the template is found in one of these locations, it will be returned or loaded
146
-     *        Example:
147
-     *          You are using the WordPress Twenty Sixteen theme,
148
-     *        and you want to customize the "some-event.template.php" template,
149
-     *          which is located in the "/relative/path/to/" folder relative to the main EE plugin folder.
150
-     *          Assuming WP is installed on your server in the "/home/public_html/" folder,
151
-     *        EEH_Template::locate_template() will look at the following paths in order until the template is found:
152
-     *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
153
-     *        /relative/path/to/some-event.template.php
154
-     *        /home/public_html/wp-content/uploads/espresso/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
155
-     *        /home/public_html/wp-content/uploads/espresso/templates/relative/path/to/some-event.template.php
156
-     *        /home/public_html/wp-content/plugins/event-espresso-core-reg/public/Espresso_Arabica_2014/relative/path/to/some-event.template.php
157
-     *        /home/public_html/wp-content/plugins/event-espresso-core-reg/core/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
158
-     *        /home/public_html/wp-content/plugins/event-espresso-core-reg/relative/path/to/some-event.template.php
159
-     *          Had you passed an absolute path to your template that was in some other location,
160
-     *        ie: "/absolute/path/to/some-event.template.php"
161
-     *          then the search would have been :
162
-     *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
163
-     *        /absolute/path/to/some-event.template.php
164
-     *          and stopped there upon finding it in the second location
165
-     *
166
-     * @param array|string $templates       array of template file names including extension (or just a single string)
167
-     * @param  array       $template_args   an array of arguments to be extracted for use in the template
168
-     * @param  boolean     $load            whether to pass the located template path on to the
169
-     *                                      EEH_Template::display_template() method or simply return it
170
-     * @param  boolean     $return_string   whether to send output immediately to screen, or capture and return as a
171
-     *                                      string
172
-     * @param boolean      $check_if_custom If TRUE, this flags this method to return boolean for whether this will
173
-     *                                      generate a custom template or not. Used in places where you don't actually
174
-     *                                      load the template, you just want to know if there's a custom version of it.
175
-     * @return mixed
176
-     * @throws DomainException
177
-     * @throws InvalidArgumentException
178
-     * @throws InvalidDataTypeException
179
-     * @throws InvalidInterfaceException
180
-     */
181
-    public static function locate_template(
182
-        $templates = array(),
183
-        $template_args = array(),
184
-        $load = true,
185
-        $return_string = true,
186
-        $check_if_custom = false
187
-    ) {
188
-        // first use WP locate_template to check for template in the current theme folder
189
-        $template_path = locate_template($templates);
190
-
191
-        if ($check_if_custom && ! empty($template_path)) {
192
-            return true;
193
-        }
194
-
195
-        // not in the theme
196
-        if (empty($template_path)) {
197
-            // not even a template to look for ?
198
-            if (empty($templates)) {
199
-                // get post_type
200
-                $post_type = EE_Registry::instance()->REQ->get('post_type');
201
-                /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
202
-                $custom_post_types = LoaderFactory::getLoader()->getShared(
203
-                    'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
204
-                );
205
-                // get array of EE Custom Post Types
206
-                $EE_CPTs = $custom_post_types->getDefinitions();
207
-                // build template name based on request
208
-                if (isset($EE_CPTs[ $post_type ])) {
209
-                    $archive_or_single = is_archive() ? 'archive' : '';
210
-                    $archive_or_single = is_single() ? 'single' : $archive_or_single;
211
-                    $templates         = $archive_or_single . '-' . $post_type . '.php';
212
-                }
213
-            }
214
-            // currently active EE template theme
215
-            $current_theme = EE_Config::get_current_theme();
216
-
217
-            // array of paths to folders that may contain templates
218
-            $template_folder_paths = array(
219
-                // first check the /wp-content/uploads/espresso/templates/(current EE theme)/  folder for an EE theme template file
220
-                EVENT_ESPRESSO_TEMPLATE_DIR . $current_theme,
221
-                // then in the root of the /wp-content/uploads/espresso/templates/ folder
222
-                EVENT_ESPRESSO_TEMPLATE_DIR,
223
-            );
224
-
225
-            // add core plugin folders for checking only if we're not $check_if_custom
226
-            if (! $check_if_custom) {
227
-                $core_paths            = array(
228
-                    // in the  /wp-content/plugins/(EE4 folder)/public/(current EE theme)/ folder within the plugin
229
-                    EE_PUBLIC . $current_theme,
230
-                    // in the  /wp-content/plugins/(EE4 folder)/core/templates/(current EE theme)/ folder within the plugin
231
-                    EE_TEMPLATES . $current_theme,
232
-                    // or maybe relative from the plugin root: /wp-content/plugins/(EE4 folder)/
233
-                    EE_PLUGIN_DIR_PATH,
234
-                );
235
-                $template_folder_paths = array_merge($template_folder_paths, $core_paths);
236
-            }
237
-
238
-            // now filter that array
239
-            $template_folder_paths = apply_filters(
240
-                'FHEE__EEH_Template__locate_template__template_folder_paths',
241
-                $template_folder_paths
242
-            );
243
-            $templates             = is_array($templates) ? $templates : array($templates);
244
-            $template_folder_paths = is_array($template_folder_paths) ? $template_folder_paths : array($template_folder_paths);
245
-            // array to hold all possible template paths
246
-            $full_template_paths = array();
247
-
248
-            // loop through $templates
249
-            foreach ($templates as $template) {
250
-                // normalize directory separators
251
-                $template                      = EEH_File::standardise_directory_separators($template);
252
-                $file_name                     = basename($template);
253
-                $template_path_minus_file_name = substr($template, 0, (strlen($file_name) * -1));
254
-                // while looping through all template folder paths
255
-                foreach ($template_folder_paths as $template_folder_path) {
256
-                    // normalize directory separators
257
-                    $template_folder_path = EEH_File::standardise_directory_separators($template_folder_path);
258
-                    // determine if any common base path exists between the two paths
259
-                    $common_base_path = EEH_Template::_find_common_base_path(
260
-                        array($template_folder_path, $template_path_minus_file_name)
261
-                    );
262
-                    if ($common_base_path !== '') {
263
-                        // both paths have a common base, so just tack the filename onto our search path
264
-                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $file_name;
265
-                    } else {
266
-                        // no common base path, so let's just concatenate
267
-                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $template;
268
-                    }
269
-                    // build up our template locations array by adding our resolved paths
270
-                    $full_template_paths[] = $resolved_path;
271
-                }
272
-                // if $template is an absolute path, then we'll tack it onto the start of our array so that it gets searched first
273
-                array_unshift($full_template_paths, $template);
274
-                // path to the directory of the current theme: /wp-content/themes/(current WP theme)/
275
-                array_unshift($full_template_paths, get_stylesheet_directory() . '/' . $file_name);
276
-            }
277
-            // filter final array of full template paths
278
-            $full_template_paths = apply_filters(
279
-                'FHEE__EEH_Template__locate_template__full_template_paths',
280
-                $full_template_paths,
281
-                $file_name
282
-            );
283
-            // now loop through our final array of template location paths and check each location
284
-            foreach ((array) $full_template_paths as $full_template_path) {
285
-                if (is_readable($full_template_path)) {
286
-                    $template_path = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $full_template_path);
287
-                    break;
288
-                }
289
-            }
290
-        }
291
-
292
-        // hook that can be used to display the full template path that will be used
293
-        do_action('AHEE__EEH_Template__locate_template__full_template_path', $template_path);
294
-
295
-        // if we got it and you want to see it...
296
-        if ($template_path && $load && ! $check_if_custom) {
297
-            if ($return_string) {
298
-                return EEH_Template::display_template($template_path, $template_args, true);
299
-            } else {
300
-                EEH_Template::display_template($template_path, $template_args, false);
301
-            }
302
-        }
303
-        return $check_if_custom && ! empty($template_path) ? true : $template_path;
304
-    }
305
-
306
-
307
-    /**
308
-     * _find_common_base_path
309
-     * given two paths, this determines if there is a common base path between the two
310
-     *
311
-     * @param array $paths
312
-     * @return string
313
-     */
314
-    protected static function _find_common_base_path($paths)
315
-    {
316
-        $last_offset      = 0;
317
-        $common_base_path = '';
318
-        while (($index = strpos($paths[0], '/', $last_offset)) !== false) {
319
-            $dir_length = $index - $last_offset + 1;
320
-            $directory  = substr($paths[0], $last_offset, $dir_length);
321
-            foreach ($paths as $path) {
322
-                if (substr($path, $last_offset, $dir_length) != $directory) {
323
-                    return $common_base_path;
324
-                }
325
-            }
326
-            $common_base_path .= $directory;
327
-            $last_offset = $index + 1;
328
-        }
329
-        return substr($common_base_path, 0, -1);
330
-    }
331
-
332
-
333
-    /**
334
-     * load and display a template
335
-     *
336
-     * @param bool|string $template_path server path to the file to be loaded, including file name and extension
337
-     * @param  array      $template_args an array of arguments to be extracted for use in the template
338
-     * @param  boolean    $return_string whether to send output immediately to screen, or capture and return as a string
339
-     * @param bool        $throw_exceptions if set to true, will throw an exception if the template is either
340
-     *                                      not found or is not readable
341
-     * @return mixed string
342
-     * @throws \DomainException
343
-     */
344
-    public static function display_template(
345
-        $template_path = false,
346
-        $template_args = array(),
347
-        $return_string = false,
348
-        $throw_exceptions = false
349
-    ) {
350
-
351
-        /**
352
-         * These two filters are intended for last minute changes to templates being loaded and/or template arg
353
-         * modifications.  NOTE... modifying these things can cause breakage as most templates running through
354
-         * the display_template method are templates we DON'T want modified (usually because of js
355
-         * dependencies etc).  So unless you know what you are doing, do NOT filter templates or template args
356
-         * using this.
357
-         *
358
-         * @since 4.6.0
359
-         */
360
-        $template_path = (string) apply_filters('FHEE__EEH_Template__display_template__template_path', $template_path);
361
-        $template_args = (array) apply_filters('FHEE__EEH_Template__display_template__template_args', $template_args);
362
-
363
-        // you gimme nuttin - YOU GET NUTTIN !!
364
-        if (! $template_path || ! is_readable($template_path)) {
365
-            return '';
366
-        }
367
-        // if $template_args are not in an array, then make it so
368
-        if (! is_array($template_args) && ! is_object($template_args)) {
369
-            $template_args = array($template_args);
370
-        }
371
-        extract($template_args, EXTR_SKIP);
372
-        // ignore whether template is accessible ?
373
-        if ($throw_exceptions && ! is_readable($template_path)) {
374
-            throw new \DomainException(
375
-                esc_html__(
376
-                    'Invalid, unreadable, or missing file.',
377
-                    'event_espresso'
378
-                )
379
-            );
380
-        }
381
-
382
-
383
-        if ($return_string) {
384
-            // because we want to return a string, we are going to capture the output
385
-            ob_start();
386
-            include($template_path);
387
-            return ob_get_clean();
388
-        } else {
389
-            include($template_path);
390
-        }
391
-        return '';
392
-    }
393
-
394
-
395
-    /**
396
-     * get_object_css_class - attempts to generate a css class based on the type of EE object passed
397
-     *
398
-     * @param EE_Base_Class $object the EE object the css class is being generated for
399
-     * @param  string       $prefix added to the beginning of the generated class
400
-     * @param  string       $suffix added to the end of the generated class
401
-     * @return string
402
-     */
403
-    public static function get_object_css_class($object = null, $prefix = '', $suffix = '')
404
-    {
405
-        // in the beginning...
406
-        $prefix = ! empty($prefix) ? rtrim($prefix, '-') . '-' : '';
407
-        // da muddle
408
-        $class = '';
409
-        // the end
410
-        $suffix = ! empty($suffix) ? '-' . ltrim($suffix, '-') : '';
411
-        // is the passed object an EE object ?
412
-        if ($object instanceof EE_Base_Class) {
413
-            // grab the exact type of object
414
-            $obj_class = get_class($object);
415
-            // depending on the type of object...
416
-            switch ($obj_class) {
417
-                // no specifics just yet...
418
-                default:
419
-                    $class = strtolower(str_replace('_', '-', $obj_class));
420
-                    $class .= method_exists($obj_class, 'name') ? '-' . sanitize_title($object->name()) : '';
421
-            }
422
-        }
423
-        return $prefix . $class . $suffix;
424
-    }
425
-
426
-
427
-
428
-    /**
429
-     * EEH_Template::format_currency
430
-     * This helper takes a raw float value and formats it according to the default config country currency settings, or
431
-     * the country currency settings from the supplied country ISO code
432
-     *
433
-     * @param  float   $amount       raw money value
434
-     * @param  boolean $return_raw   whether to return the formatted float value only with no currency sign or code
435
-     * @param  boolean $display_code whether to display the country code (USD). Default = TRUE
436
-     * @param string   $CNT_ISO      2 letter ISO code for a country
437
-     * @param string   $cur_code_span_class
438
-     * @return string        the html output for the formatted money value
439
-     * @throws \EE_Error
440
-     */
441
-    public static function format_currency(
442
-        $amount = null,
443
-        $return_raw = false,
444
-        $display_code = true,
445
-        $CNT_ISO = '',
446
-        $cur_code_span_class = 'currency-code'
447
-    ) {
448
-        // ensure amount was received
449
-        if ($amount === null) {
450
-            $msg = __('In order to format currency, an amount needs to be passed.', 'event_espresso');
451
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
452
-            return '';
453
-        }
454
-        // ensure amount is float
455
-        $amount  = apply_filters('FHEE__EEH_Template__format_currency__raw_amount', (float) $amount);
456
-        $CNT_ISO = apply_filters('FHEE__EEH_Template__format_currency__CNT_ISO', $CNT_ISO, $amount);
457
-        // filter raw amount (allows 0.00 to be changed to "free" for example)
458
-        $amount_formatted = apply_filters('FHEE__EEH_Template__format_currency__amount', $amount, $return_raw);
459
-        // still a number or was amount converted to a string like "free" ?
460
-        if (is_float($amount_formatted)) {
461
-            // was a country ISO code passed ? if so generate currency config object for that country
462
-            $mny = $CNT_ISO !== '' ? new EE_Currency_Config($CNT_ISO) : null;
463
-            // verify results
464
-            if (! $mny instanceof EE_Currency_Config) {
465
-                // set default config country currency settings
466
-                $mny = EE_Registry::instance()->CFG->currency instanceof EE_Currency_Config
467
-                    ? EE_Registry::instance()->CFG->currency
468
-                    : new EE_Currency_Config();
469
-            }
470
-            // format float
471
-            $amount_formatted = number_format($amount, $mny->dec_plc, $mny->dec_mrk, $mny->thsnds);
472
-            // add formatting ?
473
-            if (! $return_raw) {
474
-                // add currency sign
475
-                if ($mny->sign_b4) {
476
-                    if ($amount >= 0) {
477
-                        $amount_formatted = $mny->sign . $amount_formatted;
478
-                    } else {
479
-                        $amount_formatted = '-' . $mny->sign . str_replace('-', '', $amount_formatted);
480
-                    }
481
-                } else {
482
-                    $amount_formatted = $amount_formatted . $mny->sign;
483
-                }
484
-
485
-                // filter to allow global setting of display_code
486
-                $display_code = apply_filters('FHEE__EEH_Template__format_currency__display_code', $display_code);
487
-
488
-                // add currency code ?
489
-                $amount_formatted = $display_code ? $amount_formatted . ' <span class="' . $cur_code_span_class . '">(' . $mny->code . ')</span>' : $amount_formatted;
490
-            }
491
-            // filter results
492
-            $amount_formatted = apply_filters(
493
-                'FHEE__EEH_Template__format_currency__amount_formatted',
494
-                $amount_formatted,
495
-                $mny,
496
-                $return_raw
497
-            );
498
-        }
499
-        // clean up vars
500
-        unset($mny);
501
-        // return formatted currency amount
502
-        return $amount_formatted;
503
-    }
504
-
505
-
506
-    /**
507
-     * This function is used for outputting the localized label for a given status id in the schema requested (and
508
-     * possibly plural).  The intended use of this function is only for cases where wanting a label outside of a
509
-     * related status model or model object (i.e. in documentation etc.)
510
-     *
511
-     * @param  string  $status_id Status ID matching a registered status in the esp_status table.  If there is no
512
-     *                            match, then 'Unknown' will be returned.
513
-     * @param  boolean $plural    Whether to return plural or not
514
-     * @param  string  $schema    'UPPER', 'lower', or 'Sentence'
515
-     * @return string             The localized label for the status id.
516
-     */
517
-    public static function pretty_status($status_id, $plural = false, $schema = 'upper')
518
-    {
519
-        /** @type EEM_Status $EEM_Status */
520
-        $EEM_Status = EE_Registry::instance()->load_model('Status');
521
-        $status     = $EEM_Status->localized_status(
522
-            array($status_id => __('unknown', 'event_espresso')),
523
-            $plural,
524
-            $schema
525
-        );
526
-        return $status[ $status_id ];
527
-    }
528
-
529
-
530
-    /**
531
-     * This helper just returns a button or link for the given parameters
532
-     *
533
-     * @param  string $url   the url for the link, note that `esc_url` will be called on it
534
-     * @param  string $label What is the label you want displayed for the button
535
-     * @param  string $class what class is used for the button (defaults to 'button-primary')
536
-     * @param string  $icon
537
-     * @param string  $title
538
-     * @return string the html output for the button
539
-     */
540
-    public static function get_button_or_link($url, $label, $class = 'button-primary', $icon = '', $title = '')
541
-    {
542
-        $icon_html = '';
543
-        if (! empty($icon)) {
544
-            $dashicons = preg_split("(ee-icon |dashicons )", $icon);
545
-            $dashicons = array_filter($dashicons);
546
-            $count     = count($dashicons);
547
-            $icon_html .= $count > 1 ? '<span class="ee-composite-dashicon">' : '';
548
-            foreach ($dashicons as $dashicon) {
549
-                $type = strpos($dashicon, 'ee-icon') !== false ? 'ee-icon ' : 'dashicons ';
550
-                $icon_html .= '<span class="' . $type . $dashicon . '"></span>';
551
-            }
552
-            $icon_html .= $count > 1 ? '</span>' : '';
553
-        }
554
-        $label  = ! empty($icon) ? $icon_html . $label : $label;
555
-        $button = '<a id="' . sanitize_title_with_dashes($label) . '" href="' . esc_url($url) . '" class="' . $class . '" title="' . $title . '">' . $label . '</a>';
556
-        return $button;
557
-    }
558
-
559
-
560
-    /**
561
-     * This returns a generated link that will load the related help tab on admin pages.
562
-     *
563
-     * @param  string     $help_tab_id the id for the connected help tab
564
-     * @param bool|string $page        The page identifier for the page the help tab is on
565
-     * @param bool|string $action      The action (route) for the admin page the help tab is on.
566
-     * @param bool|string $icon_style  (optional) include css class for the style you want to use for the help icon.
567
-     * @param bool|string $help_text   (optional) send help text you want to use for the link if default not to be used
568
-     * @return string              generated link
569
-     */
570
-    public static function get_help_tab_link(
571
-        $help_tab_id,
572
-        $page = false,
573
-        $action = false,
574
-        $icon_style = false,
575
-        $help_text = false
576
-    ) {
577
-
578
-        if (! $page) {
579
-            $page = isset($_REQUEST['page']) && ! empty($_REQUEST['page']) ? sanitize_key($_REQUEST['page']) : $page;
580
-        }
581
-
582
-        if (! $action) {
583
-            $action = isset($_REQUEST['action']) && ! empty($_REQUEST['action']) ? sanitize_key($_REQUEST['action']) : $action;
584
-        }
585
-
586
-        $action = empty($action) ? 'default' : $action;
587
-
588
-
589
-        $help_tab_lnk = $page . '-' . $action . '-' . $help_tab_id;
590
-        $icon         = ! $icon_style ? ' dashicons-editor-help' : $icon_style;
591
-        $help_text    = ! $help_text ? '' : $help_text;
592
-        return '<a id="' . $help_tab_lnk . '" class="ee-clickable dashicons espresso-help-tab-lnk ee-icon-size-22' . $icon . '" title="' . esc_attr__(
593
-            'Click to open the \'Help\' tab for more information about this feature.',
594
-            'event_espresso'
595
-        ) . '" > ' . $help_text . ' </a>';
596
-    }
597
-
598
-
599
-    /**
600
-     * This helper generates the html structure for the jquery joyride plugin with the given params.
601
-     *
602
-     * @link http://zurb.com/playground/jquery-joyride-feature-tour-plugin
603
-     * @see  EE_Admin_Page->_stop_callback() for the construct expected for the $stops param.
604
-     * @param EE_Help_Tour
605
-     * @return string         html
606
-     */
607
-    public static function help_tour_stops_generator(EE_Help_Tour $tour)
608
-    {
609
-        $id    = $tour->get_slug();
610
-        $stops = $tour->get_stops();
611
-
612
-        $content = '<ol style="display:none" id="' . $id . '">';
613
-
614
-        foreach ($stops as $stop) {
615
-            $data_id    = ! empty($stop['id']) ? ' data-id="' . $stop['id'] . '"' : '';
616
-            $data_class = empty($data_id) && ! empty($stop['class']) ? ' data-class="' . $stop['class'] . '"' : '';
617
-
618
-            // if container is set to modal then let's make sure we set the options accordingly
619
-            if (empty($data_id) && empty($data_class)) {
620
-                $stop['options']['modal']  = true;
621
-                $stop['options']['expose'] = true;
622
-            }
623
-
624
-            $custom_class  = ! empty($stop['custom_class']) ? ' class="' . $stop['custom_class'] . '"' : '';
625
-            $button_text   = ! empty($stop['button_text']) ? ' data-button="' . $stop['button_text'] . '"' : '';
626
-            $inner_content = isset($stop['content']) ? $stop['content'] : '';
627
-
628
-            // options
629
-            if (isset($stop['options']) && is_array($stop['options'])) {
630
-                $options = ' data-options="';
631
-                foreach ($stop['options'] as $option => $value) {
632
-                    $options .= $option . ':' . $value . ';';
633
-                }
634
-                $options .= '"';
635
-            } else {
636
-                $options = '';
637
-            }
638
-
639
-            // let's put all together
640
-            $content .= '<li' . $data_id . $data_class . $custom_class . $button_text . $options . '>' . $inner_content . '</li>';
641
-        }
642
-
643
-        $content .= '</ol>';
644
-        return $content;
645
-    }
646
-
647
-
648
-    /**
649
-     * This is a helper method to generate a status legend for a given status array.
650
-     * Note this will only work if the incoming statuses have a key in the EEM_Status->localized_status() methods
651
-     * status_array.
652
-     *
653
-     * @param  array  $status_array  array of statuses that will make up the legend. In format:
654
-     *                               array(
655
-     *                               'status_item' => 'status_name'
656
-     *                               )
657
-     * @param  string $active_status This is used to indicate what the active status is IF that is to be highlighted in
658
-     *                               the legend.
659
-     * @throws EE_Error
660
-     * @return string               html structure for status.
661
-     */
662
-    public static function status_legend($status_array, $active_status = '')
663
-    {
664
-        if (! is_array($status_array)) {
665
-            throw new EE_Error(esc_html__(
666
-                'The EEH_Template::status_legend helper required the incoming status_array argument to be an array!',
667
-                'event_espresso'
668
-            ));
669
-        }
670
-
671
-        $setup_array = array();
672
-        foreach ($status_array as $item => $status) {
673
-            $setup_array[ $item ] = array(
674
-                'class'  => 'ee-status-legend ee-status-legend-' . $status,
675
-                'desc'   => EEH_Template::pretty_status($status, false, 'sentence'),
676
-                'status' => $status,
677
-            );
678
-        }
679
-
680
-        $content = '<div class="ee-list-table-legend-container">' . "\n";
681
-        $content .= '<h4 class="status-legend-title">' . esc_html__('Status Legend', 'event_espresso') . '</h4>' . "\n";
682
-        $content .= '<dl class="ee-list-table-legend">' . "\n\t";
683
-        foreach ($setup_array as $item => $details) {
684
-            $active_class = $active_status == $details['status'] ? ' class="ee-is-active-status"' : '';
685
-            $content .= '<dt id="ee-legend-item-tooltip-' . $item . '"' . $active_class . '>' . "\n\t\t";
686
-            $content .= '<span class="ee-legend-item-wrap"><span class="' . $details['class'] . '"></span></span>' . "\n\t\t";
687
-            $content .= '<span class="ee-legend-description">' . $details['desc'] . '</span>' . "\n\t";
688
-            $content .= '</dt>' . "\n";
689
-        }
690
-        $content .= '</dl>' . "\n";
691
-        $content .= '</div>' . "\n";
692
-        return $content;
693
-    }
694
-
695
-
696
-    /**
697
-     * Gets HTML for laying out a deeply-nested array (and objects) in a format
698
-     * that's nice for presenting in the wp admin
699
-     *
700
-     * @param mixed $data
701
-     * @return string
702
-     */
703
-    public static function layout_array_as_table($data)
704
-    {
705
-        if (is_object($data) || $data instanceof __PHP_Incomplete_Class) {
706
-            $data = (array) $data;
707
-        }
708
-        ob_start();
709
-        if (is_array($data)) {
710
-            if (EEH_Array::is_associative_array($data)) {
711
-                ?>
51
+	private static $_espresso_themes = array();
52
+
53
+
54
+	/**
55
+	 *    is_espresso_theme - returns TRUE or FALSE on whether the currently active WP theme is an espresso theme
56
+	 *
57
+	 * @return boolean
58
+	 */
59
+	public static function is_espresso_theme()
60
+	{
61
+		return wp_get_theme()->get('TextDomain') == 'event_espresso' ? true : false;
62
+	}
63
+
64
+	/**
65
+	 *    load_espresso_theme_functions - if current theme is an espresso theme, or uses ee theme template parts, then
66
+	 *    load it's functions.php file ( if not already loaded )
67
+	 *
68
+	 * @return void
69
+	 */
70
+	public static function load_espresso_theme_functions()
71
+	{
72
+		if (! defined('EE_THEME_FUNCTIONS_LOADED')) {
73
+			if (is_readable(EE_PUBLIC . EE_Config::get_current_theme() . '/functions.php')) {
74
+				require_once(EE_PUBLIC . EE_Config::get_current_theme() . '/functions.php');
75
+			}
76
+		}
77
+	}
78
+
79
+
80
+	/**
81
+	 *    get_espresso_themes - returns an array of Espresso Child themes located in the /templates/ directory
82
+	 *
83
+	 * @return array
84
+	 */
85
+	public static function get_espresso_themes()
86
+	{
87
+		if (empty(EEH_Template::$_espresso_themes)) {
88
+			$espresso_themes = glob(EE_PUBLIC . '*', GLOB_ONLYDIR);
89
+			if (empty($espresso_themes)) {
90
+				return array();
91
+			}
92
+			if (($key = array_search('global_assets', $espresso_themes)) !== false) {
93
+				unset($espresso_themes[ $key ]);
94
+			}
95
+			EEH_Template::$_espresso_themes = array();
96
+			foreach ($espresso_themes as $espresso_theme) {
97
+				EEH_Template::$_espresso_themes[ basename($espresso_theme) ] = $espresso_theme;
98
+			}
99
+		}
100
+		return EEH_Template::$_espresso_themes;
101
+	}
102
+
103
+
104
+	/**
105
+	 * EEH_Template::get_template_part
106
+	 * basically a copy of the WordPress get_template_part() function but uses EEH_Template::locate_template() instead,
107
+	 * and doesn't add base versions of files so not a very useful function at all except that it adds familiarity PLUS
108
+	 * filtering based off of the entire template part name
109
+	 *
110
+	 * @param string $slug The slug name for the generic template.
111
+	 * @param string $name The name of the specialised template.
112
+	 * @param array  $template_args
113
+	 * @param bool   $return_string
114
+	 * @return string        the html output for the formatted money value
115
+	 */
116
+	public static function get_template_part(
117
+		$slug = null,
118
+		$name = null,
119
+		$template_args = array(),
120
+		$return_string = false
121
+	) {
122
+		do_action("get_template_part_{$slug}-{$name}", $slug, $name);
123
+		$templates = array();
124
+		$name      = (string) $name;
125
+		if ($name != '') {
126
+			$templates[] = "{$slug}-{$name}.php";
127
+		}
128
+		// allow template parts to be turned off via something like: add_filter( 'FHEE__content_espresso_events_tickets_template__display_datetimes', '__return_false' );
129
+		if (apply_filters("FHEE__EEH_Template__get_template_part__display__{$slug}_{$name}", true)) {
130
+			EEH_Template::locate_template($templates, $template_args, true, $return_string);
131
+		}
132
+	}
133
+
134
+
135
+	/**
136
+	 *    locate_template
137
+	 *    locate a template file by looking in the following places, in the following order:
138
+	 *        <server path up to>/wp-content/themes/<current active WordPress theme>/
139
+	 *        <assumed full absolute server path>
140
+	 *        <server path up to>/wp-content/uploads/espresso/templates/<current EE theme>/
141
+	 *        <server path up to>/wp-content/uploads/espresso/templates/
142
+	 *        <server path up to>/wp-content/plugins/<EE4 folder>/public/<current EE theme>/
143
+	 *        <server path up to>/wp-content/plugins/<EE4 folder>/core/templates/<current EE theme>/
144
+	 *        <server path up to>/wp-content/plugins/<EE4 folder>/
145
+	 *    as soon as the template is found in one of these locations, it will be returned or loaded
146
+	 *        Example:
147
+	 *          You are using the WordPress Twenty Sixteen theme,
148
+	 *        and you want to customize the "some-event.template.php" template,
149
+	 *          which is located in the "/relative/path/to/" folder relative to the main EE plugin folder.
150
+	 *          Assuming WP is installed on your server in the "/home/public_html/" folder,
151
+	 *        EEH_Template::locate_template() will look at the following paths in order until the template is found:
152
+	 *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
153
+	 *        /relative/path/to/some-event.template.php
154
+	 *        /home/public_html/wp-content/uploads/espresso/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
155
+	 *        /home/public_html/wp-content/uploads/espresso/templates/relative/path/to/some-event.template.php
156
+	 *        /home/public_html/wp-content/plugins/event-espresso-core-reg/public/Espresso_Arabica_2014/relative/path/to/some-event.template.php
157
+	 *        /home/public_html/wp-content/plugins/event-espresso-core-reg/core/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
158
+	 *        /home/public_html/wp-content/plugins/event-espresso-core-reg/relative/path/to/some-event.template.php
159
+	 *          Had you passed an absolute path to your template that was in some other location,
160
+	 *        ie: "/absolute/path/to/some-event.template.php"
161
+	 *          then the search would have been :
162
+	 *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
163
+	 *        /absolute/path/to/some-event.template.php
164
+	 *          and stopped there upon finding it in the second location
165
+	 *
166
+	 * @param array|string $templates       array of template file names including extension (or just a single string)
167
+	 * @param  array       $template_args   an array of arguments to be extracted for use in the template
168
+	 * @param  boolean     $load            whether to pass the located template path on to the
169
+	 *                                      EEH_Template::display_template() method or simply return it
170
+	 * @param  boolean     $return_string   whether to send output immediately to screen, or capture and return as a
171
+	 *                                      string
172
+	 * @param boolean      $check_if_custom If TRUE, this flags this method to return boolean for whether this will
173
+	 *                                      generate a custom template or not. Used in places where you don't actually
174
+	 *                                      load the template, you just want to know if there's a custom version of it.
175
+	 * @return mixed
176
+	 * @throws DomainException
177
+	 * @throws InvalidArgumentException
178
+	 * @throws InvalidDataTypeException
179
+	 * @throws InvalidInterfaceException
180
+	 */
181
+	public static function locate_template(
182
+		$templates = array(),
183
+		$template_args = array(),
184
+		$load = true,
185
+		$return_string = true,
186
+		$check_if_custom = false
187
+	) {
188
+		// first use WP locate_template to check for template in the current theme folder
189
+		$template_path = locate_template($templates);
190
+
191
+		if ($check_if_custom && ! empty($template_path)) {
192
+			return true;
193
+		}
194
+
195
+		// not in the theme
196
+		if (empty($template_path)) {
197
+			// not even a template to look for ?
198
+			if (empty($templates)) {
199
+				// get post_type
200
+				$post_type = EE_Registry::instance()->REQ->get('post_type');
201
+				/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
202
+				$custom_post_types = LoaderFactory::getLoader()->getShared(
203
+					'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
204
+				);
205
+				// get array of EE Custom Post Types
206
+				$EE_CPTs = $custom_post_types->getDefinitions();
207
+				// build template name based on request
208
+				if (isset($EE_CPTs[ $post_type ])) {
209
+					$archive_or_single = is_archive() ? 'archive' : '';
210
+					$archive_or_single = is_single() ? 'single' : $archive_or_single;
211
+					$templates         = $archive_or_single . '-' . $post_type . '.php';
212
+				}
213
+			}
214
+			// currently active EE template theme
215
+			$current_theme = EE_Config::get_current_theme();
216
+
217
+			// array of paths to folders that may contain templates
218
+			$template_folder_paths = array(
219
+				// first check the /wp-content/uploads/espresso/templates/(current EE theme)/  folder for an EE theme template file
220
+				EVENT_ESPRESSO_TEMPLATE_DIR . $current_theme,
221
+				// then in the root of the /wp-content/uploads/espresso/templates/ folder
222
+				EVENT_ESPRESSO_TEMPLATE_DIR,
223
+			);
224
+
225
+			// add core plugin folders for checking only if we're not $check_if_custom
226
+			if (! $check_if_custom) {
227
+				$core_paths            = array(
228
+					// in the  /wp-content/plugins/(EE4 folder)/public/(current EE theme)/ folder within the plugin
229
+					EE_PUBLIC . $current_theme,
230
+					// in the  /wp-content/plugins/(EE4 folder)/core/templates/(current EE theme)/ folder within the plugin
231
+					EE_TEMPLATES . $current_theme,
232
+					// or maybe relative from the plugin root: /wp-content/plugins/(EE4 folder)/
233
+					EE_PLUGIN_DIR_PATH,
234
+				);
235
+				$template_folder_paths = array_merge($template_folder_paths, $core_paths);
236
+			}
237
+
238
+			// now filter that array
239
+			$template_folder_paths = apply_filters(
240
+				'FHEE__EEH_Template__locate_template__template_folder_paths',
241
+				$template_folder_paths
242
+			);
243
+			$templates             = is_array($templates) ? $templates : array($templates);
244
+			$template_folder_paths = is_array($template_folder_paths) ? $template_folder_paths : array($template_folder_paths);
245
+			// array to hold all possible template paths
246
+			$full_template_paths = array();
247
+
248
+			// loop through $templates
249
+			foreach ($templates as $template) {
250
+				// normalize directory separators
251
+				$template                      = EEH_File::standardise_directory_separators($template);
252
+				$file_name                     = basename($template);
253
+				$template_path_minus_file_name = substr($template, 0, (strlen($file_name) * -1));
254
+				// while looping through all template folder paths
255
+				foreach ($template_folder_paths as $template_folder_path) {
256
+					// normalize directory separators
257
+					$template_folder_path = EEH_File::standardise_directory_separators($template_folder_path);
258
+					// determine if any common base path exists between the two paths
259
+					$common_base_path = EEH_Template::_find_common_base_path(
260
+						array($template_folder_path, $template_path_minus_file_name)
261
+					);
262
+					if ($common_base_path !== '') {
263
+						// both paths have a common base, so just tack the filename onto our search path
264
+						$resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $file_name;
265
+					} else {
266
+						// no common base path, so let's just concatenate
267
+						$resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $template;
268
+					}
269
+					// build up our template locations array by adding our resolved paths
270
+					$full_template_paths[] = $resolved_path;
271
+				}
272
+				// if $template is an absolute path, then we'll tack it onto the start of our array so that it gets searched first
273
+				array_unshift($full_template_paths, $template);
274
+				// path to the directory of the current theme: /wp-content/themes/(current WP theme)/
275
+				array_unshift($full_template_paths, get_stylesheet_directory() . '/' . $file_name);
276
+			}
277
+			// filter final array of full template paths
278
+			$full_template_paths = apply_filters(
279
+				'FHEE__EEH_Template__locate_template__full_template_paths',
280
+				$full_template_paths,
281
+				$file_name
282
+			);
283
+			// now loop through our final array of template location paths and check each location
284
+			foreach ((array) $full_template_paths as $full_template_path) {
285
+				if (is_readable($full_template_path)) {
286
+					$template_path = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $full_template_path);
287
+					break;
288
+				}
289
+			}
290
+		}
291
+
292
+		// hook that can be used to display the full template path that will be used
293
+		do_action('AHEE__EEH_Template__locate_template__full_template_path', $template_path);
294
+
295
+		// if we got it and you want to see it...
296
+		if ($template_path && $load && ! $check_if_custom) {
297
+			if ($return_string) {
298
+				return EEH_Template::display_template($template_path, $template_args, true);
299
+			} else {
300
+				EEH_Template::display_template($template_path, $template_args, false);
301
+			}
302
+		}
303
+		return $check_if_custom && ! empty($template_path) ? true : $template_path;
304
+	}
305
+
306
+
307
+	/**
308
+	 * _find_common_base_path
309
+	 * given two paths, this determines if there is a common base path between the two
310
+	 *
311
+	 * @param array $paths
312
+	 * @return string
313
+	 */
314
+	protected static function _find_common_base_path($paths)
315
+	{
316
+		$last_offset      = 0;
317
+		$common_base_path = '';
318
+		while (($index = strpos($paths[0], '/', $last_offset)) !== false) {
319
+			$dir_length = $index - $last_offset + 1;
320
+			$directory  = substr($paths[0], $last_offset, $dir_length);
321
+			foreach ($paths as $path) {
322
+				if (substr($path, $last_offset, $dir_length) != $directory) {
323
+					return $common_base_path;
324
+				}
325
+			}
326
+			$common_base_path .= $directory;
327
+			$last_offset = $index + 1;
328
+		}
329
+		return substr($common_base_path, 0, -1);
330
+	}
331
+
332
+
333
+	/**
334
+	 * load and display a template
335
+	 *
336
+	 * @param bool|string $template_path server path to the file to be loaded, including file name and extension
337
+	 * @param  array      $template_args an array of arguments to be extracted for use in the template
338
+	 * @param  boolean    $return_string whether to send output immediately to screen, or capture and return as a string
339
+	 * @param bool        $throw_exceptions if set to true, will throw an exception if the template is either
340
+	 *                                      not found or is not readable
341
+	 * @return mixed string
342
+	 * @throws \DomainException
343
+	 */
344
+	public static function display_template(
345
+		$template_path = false,
346
+		$template_args = array(),
347
+		$return_string = false,
348
+		$throw_exceptions = false
349
+	) {
350
+
351
+		/**
352
+		 * These two filters are intended for last minute changes to templates being loaded and/or template arg
353
+		 * modifications.  NOTE... modifying these things can cause breakage as most templates running through
354
+		 * the display_template method are templates we DON'T want modified (usually because of js
355
+		 * dependencies etc).  So unless you know what you are doing, do NOT filter templates or template args
356
+		 * using this.
357
+		 *
358
+		 * @since 4.6.0
359
+		 */
360
+		$template_path = (string) apply_filters('FHEE__EEH_Template__display_template__template_path', $template_path);
361
+		$template_args = (array) apply_filters('FHEE__EEH_Template__display_template__template_args', $template_args);
362
+
363
+		// you gimme nuttin - YOU GET NUTTIN !!
364
+		if (! $template_path || ! is_readable($template_path)) {
365
+			return '';
366
+		}
367
+		// if $template_args are not in an array, then make it so
368
+		if (! is_array($template_args) && ! is_object($template_args)) {
369
+			$template_args = array($template_args);
370
+		}
371
+		extract($template_args, EXTR_SKIP);
372
+		// ignore whether template is accessible ?
373
+		if ($throw_exceptions && ! is_readable($template_path)) {
374
+			throw new \DomainException(
375
+				esc_html__(
376
+					'Invalid, unreadable, or missing file.',
377
+					'event_espresso'
378
+				)
379
+			);
380
+		}
381
+
382
+
383
+		if ($return_string) {
384
+			// because we want to return a string, we are going to capture the output
385
+			ob_start();
386
+			include($template_path);
387
+			return ob_get_clean();
388
+		} else {
389
+			include($template_path);
390
+		}
391
+		return '';
392
+	}
393
+
394
+
395
+	/**
396
+	 * get_object_css_class - attempts to generate a css class based on the type of EE object passed
397
+	 *
398
+	 * @param EE_Base_Class $object the EE object the css class is being generated for
399
+	 * @param  string       $prefix added to the beginning of the generated class
400
+	 * @param  string       $suffix added to the end of the generated class
401
+	 * @return string
402
+	 */
403
+	public static function get_object_css_class($object = null, $prefix = '', $suffix = '')
404
+	{
405
+		// in the beginning...
406
+		$prefix = ! empty($prefix) ? rtrim($prefix, '-') . '-' : '';
407
+		// da muddle
408
+		$class = '';
409
+		// the end
410
+		$suffix = ! empty($suffix) ? '-' . ltrim($suffix, '-') : '';
411
+		// is the passed object an EE object ?
412
+		if ($object instanceof EE_Base_Class) {
413
+			// grab the exact type of object
414
+			$obj_class = get_class($object);
415
+			// depending on the type of object...
416
+			switch ($obj_class) {
417
+				// no specifics just yet...
418
+				default:
419
+					$class = strtolower(str_replace('_', '-', $obj_class));
420
+					$class .= method_exists($obj_class, 'name') ? '-' . sanitize_title($object->name()) : '';
421
+			}
422
+		}
423
+		return $prefix . $class . $suffix;
424
+	}
425
+
426
+
427
+
428
+	/**
429
+	 * EEH_Template::format_currency
430
+	 * This helper takes a raw float value and formats it according to the default config country currency settings, or
431
+	 * the country currency settings from the supplied country ISO code
432
+	 *
433
+	 * @param  float   $amount       raw money value
434
+	 * @param  boolean $return_raw   whether to return the formatted float value only with no currency sign or code
435
+	 * @param  boolean $display_code whether to display the country code (USD). Default = TRUE
436
+	 * @param string   $CNT_ISO      2 letter ISO code for a country
437
+	 * @param string   $cur_code_span_class
438
+	 * @return string        the html output for the formatted money value
439
+	 * @throws \EE_Error
440
+	 */
441
+	public static function format_currency(
442
+		$amount = null,
443
+		$return_raw = false,
444
+		$display_code = true,
445
+		$CNT_ISO = '',
446
+		$cur_code_span_class = 'currency-code'
447
+	) {
448
+		// ensure amount was received
449
+		if ($amount === null) {
450
+			$msg = __('In order to format currency, an amount needs to be passed.', 'event_espresso');
451
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
452
+			return '';
453
+		}
454
+		// ensure amount is float
455
+		$amount  = apply_filters('FHEE__EEH_Template__format_currency__raw_amount', (float) $amount);
456
+		$CNT_ISO = apply_filters('FHEE__EEH_Template__format_currency__CNT_ISO', $CNT_ISO, $amount);
457
+		// filter raw amount (allows 0.00 to be changed to "free" for example)
458
+		$amount_formatted = apply_filters('FHEE__EEH_Template__format_currency__amount', $amount, $return_raw);
459
+		// still a number or was amount converted to a string like "free" ?
460
+		if (is_float($amount_formatted)) {
461
+			// was a country ISO code passed ? if so generate currency config object for that country
462
+			$mny = $CNT_ISO !== '' ? new EE_Currency_Config($CNT_ISO) : null;
463
+			// verify results
464
+			if (! $mny instanceof EE_Currency_Config) {
465
+				// set default config country currency settings
466
+				$mny = EE_Registry::instance()->CFG->currency instanceof EE_Currency_Config
467
+					? EE_Registry::instance()->CFG->currency
468
+					: new EE_Currency_Config();
469
+			}
470
+			// format float
471
+			$amount_formatted = number_format($amount, $mny->dec_plc, $mny->dec_mrk, $mny->thsnds);
472
+			// add formatting ?
473
+			if (! $return_raw) {
474
+				// add currency sign
475
+				if ($mny->sign_b4) {
476
+					if ($amount >= 0) {
477
+						$amount_formatted = $mny->sign . $amount_formatted;
478
+					} else {
479
+						$amount_formatted = '-' . $mny->sign . str_replace('-', '', $amount_formatted);
480
+					}
481
+				} else {
482
+					$amount_formatted = $amount_formatted . $mny->sign;
483
+				}
484
+
485
+				// filter to allow global setting of display_code
486
+				$display_code = apply_filters('FHEE__EEH_Template__format_currency__display_code', $display_code);
487
+
488
+				// add currency code ?
489
+				$amount_formatted = $display_code ? $amount_formatted . ' <span class="' . $cur_code_span_class . '">(' . $mny->code . ')</span>' : $amount_formatted;
490
+			}
491
+			// filter results
492
+			$amount_formatted = apply_filters(
493
+				'FHEE__EEH_Template__format_currency__amount_formatted',
494
+				$amount_formatted,
495
+				$mny,
496
+				$return_raw
497
+			);
498
+		}
499
+		// clean up vars
500
+		unset($mny);
501
+		// return formatted currency amount
502
+		return $amount_formatted;
503
+	}
504
+
505
+
506
+	/**
507
+	 * This function is used for outputting the localized label for a given status id in the schema requested (and
508
+	 * possibly plural).  The intended use of this function is only for cases where wanting a label outside of a
509
+	 * related status model or model object (i.e. in documentation etc.)
510
+	 *
511
+	 * @param  string  $status_id Status ID matching a registered status in the esp_status table.  If there is no
512
+	 *                            match, then 'Unknown' will be returned.
513
+	 * @param  boolean $plural    Whether to return plural or not
514
+	 * @param  string  $schema    'UPPER', 'lower', or 'Sentence'
515
+	 * @return string             The localized label for the status id.
516
+	 */
517
+	public static function pretty_status($status_id, $plural = false, $schema = 'upper')
518
+	{
519
+		/** @type EEM_Status $EEM_Status */
520
+		$EEM_Status = EE_Registry::instance()->load_model('Status');
521
+		$status     = $EEM_Status->localized_status(
522
+			array($status_id => __('unknown', 'event_espresso')),
523
+			$plural,
524
+			$schema
525
+		);
526
+		return $status[ $status_id ];
527
+	}
528
+
529
+
530
+	/**
531
+	 * This helper just returns a button or link for the given parameters
532
+	 *
533
+	 * @param  string $url   the url for the link, note that `esc_url` will be called on it
534
+	 * @param  string $label What is the label you want displayed for the button
535
+	 * @param  string $class what class is used for the button (defaults to 'button-primary')
536
+	 * @param string  $icon
537
+	 * @param string  $title
538
+	 * @return string the html output for the button
539
+	 */
540
+	public static function get_button_or_link($url, $label, $class = 'button-primary', $icon = '', $title = '')
541
+	{
542
+		$icon_html = '';
543
+		if (! empty($icon)) {
544
+			$dashicons = preg_split("(ee-icon |dashicons )", $icon);
545
+			$dashicons = array_filter($dashicons);
546
+			$count     = count($dashicons);
547
+			$icon_html .= $count > 1 ? '<span class="ee-composite-dashicon">' : '';
548
+			foreach ($dashicons as $dashicon) {
549
+				$type = strpos($dashicon, 'ee-icon') !== false ? 'ee-icon ' : 'dashicons ';
550
+				$icon_html .= '<span class="' . $type . $dashicon . '"></span>';
551
+			}
552
+			$icon_html .= $count > 1 ? '</span>' : '';
553
+		}
554
+		$label  = ! empty($icon) ? $icon_html . $label : $label;
555
+		$button = '<a id="' . sanitize_title_with_dashes($label) . '" href="' . esc_url($url) . '" class="' . $class . '" title="' . $title . '">' . $label . '</a>';
556
+		return $button;
557
+	}
558
+
559
+
560
+	/**
561
+	 * This returns a generated link that will load the related help tab on admin pages.
562
+	 *
563
+	 * @param  string     $help_tab_id the id for the connected help tab
564
+	 * @param bool|string $page        The page identifier for the page the help tab is on
565
+	 * @param bool|string $action      The action (route) for the admin page the help tab is on.
566
+	 * @param bool|string $icon_style  (optional) include css class for the style you want to use for the help icon.
567
+	 * @param bool|string $help_text   (optional) send help text you want to use for the link if default not to be used
568
+	 * @return string              generated link
569
+	 */
570
+	public static function get_help_tab_link(
571
+		$help_tab_id,
572
+		$page = false,
573
+		$action = false,
574
+		$icon_style = false,
575
+		$help_text = false
576
+	) {
577
+
578
+		if (! $page) {
579
+			$page = isset($_REQUEST['page']) && ! empty($_REQUEST['page']) ? sanitize_key($_REQUEST['page']) : $page;
580
+		}
581
+
582
+		if (! $action) {
583
+			$action = isset($_REQUEST['action']) && ! empty($_REQUEST['action']) ? sanitize_key($_REQUEST['action']) : $action;
584
+		}
585
+
586
+		$action = empty($action) ? 'default' : $action;
587
+
588
+
589
+		$help_tab_lnk = $page . '-' . $action . '-' . $help_tab_id;
590
+		$icon         = ! $icon_style ? ' dashicons-editor-help' : $icon_style;
591
+		$help_text    = ! $help_text ? '' : $help_text;
592
+		return '<a id="' . $help_tab_lnk . '" class="ee-clickable dashicons espresso-help-tab-lnk ee-icon-size-22' . $icon . '" title="' . esc_attr__(
593
+			'Click to open the \'Help\' tab for more information about this feature.',
594
+			'event_espresso'
595
+		) . '" > ' . $help_text . ' </a>';
596
+	}
597
+
598
+
599
+	/**
600
+	 * This helper generates the html structure for the jquery joyride plugin with the given params.
601
+	 *
602
+	 * @link http://zurb.com/playground/jquery-joyride-feature-tour-plugin
603
+	 * @see  EE_Admin_Page->_stop_callback() for the construct expected for the $stops param.
604
+	 * @param EE_Help_Tour
605
+	 * @return string         html
606
+	 */
607
+	public static function help_tour_stops_generator(EE_Help_Tour $tour)
608
+	{
609
+		$id    = $tour->get_slug();
610
+		$stops = $tour->get_stops();
611
+
612
+		$content = '<ol style="display:none" id="' . $id . '">';
613
+
614
+		foreach ($stops as $stop) {
615
+			$data_id    = ! empty($stop['id']) ? ' data-id="' . $stop['id'] . '"' : '';
616
+			$data_class = empty($data_id) && ! empty($stop['class']) ? ' data-class="' . $stop['class'] . '"' : '';
617
+
618
+			// if container is set to modal then let's make sure we set the options accordingly
619
+			if (empty($data_id) && empty($data_class)) {
620
+				$stop['options']['modal']  = true;
621
+				$stop['options']['expose'] = true;
622
+			}
623
+
624
+			$custom_class  = ! empty($stop['custom_class']) ? ' class="' . $stop['custom_class'] . '"' : '';
625
+			$button_text   = ! empty($stop['button_text']) ? ' data-button="' . $stop['button_text'] . '"' : '';
626
+			$inner_content = isset($stop['content']) ? $stop['content'] : '';
627
+
628
+			// options
629
+			if (isset($stop['options']) && is_array($stop['options'])) {
630
+				$options = ' data-options="';
631
+				foreach ($stop['options'] as $option => $value) {
632
+					$options .= $option . ':' . $value . ';';
633
+				}
634
+				$options .= '"';
635
+			} else {
636
+				$options = '';
637
+			}
638
+
639
+			// let's put all together
640
+			$content .= '<li' . $data_id . $data_class . $custom_class . $button_text . $options . '>' . $inner_content . '</li>';
641
+		}
642
+
643
+		$content .= '</ol>';
644
+		return $content;
645
+	}
646
+
647
+
648
+	/**
649
+	 * This is a helper method to generate a status legend for a given status array.
650
+	 * Note this will only work if the incoming statuses have a key in the EEM_Status->localized_status() methods
651
+	 * status_array.
652
+	 *
653
+	 * @param  array  $status_array  array of statuses that will make up the legend. In format:
654
+	 *                               array(
655
+	 *                               'status_item' => 'status_name'
656
+	 *                               )
657
+	 * @param  string $active_status This is used to indicate what the active status is IF that is to be highlighted in
658
+	 *                               the legend.
659
+	 * @throws EE_Error
660
+	 * @return string               html structure for status.
661
+	 */
662
+	public static function status_legend($status_array, $active_status = '')
663
+	{
664
+		if (! is_array($status_array)) {
665
+			throw new EE_Error(esc_html__(
666
+				'The EEH_Template::status_legend helper required the incoming status_array argument to be an array!',
667
+				'event_espresso'
668
+			));
669
+		}
670
+
671
+		$setup_array = array();
672
+		foreach ($status_array as $item => $status) {
673
+			$setup_array[ $item ] = array(
674
+				'class'  => 'ee-status-legend ee-status-legend-' . $status,
675
+				'desc'   => EEH_Template::pretty_status($status, false, 'sentence'),
676
+				'status' => $status,
677
+			);
678
+		}
679
+
680
+		$content = '<div class="ee-list-table-legend-container">' . "\n";
681
+		$content .= '<h4 class="status-legend-title">' . esc_html__('Status Legend', 'event_espresso') . '</h4>' . "\n";
682
+		$content .= '<dl class="ee-list-table-legend">' . "\n\t";
683
+		foreach ($setup_array as $item => $details) {
684
+			$active_class = $active_status == $details['status'] ? ' class="ee-is-active-status"' : '';
685
+			$content .= '<dt id="ee-legend-item-tooltip-' . $item . '"' . $active_class . '>' . "\n\t\t";
686
+			$content .= '<span class="ee-legend-item-wrap"><span class="' . $details['class'] . '"></span></span>' . "\n\t\t";
687
+			$content .= '<span class="ee-legend-description">' . $details['desc'] . '</span>' . "\n\t";
688
+			$content .= '</dt>' . "\n";
689
+		}
690
+		$content .= '</dl>' . "\n";
691
+		$content .= '</div>' . "\n";
692
+		return $content;
693
+	}
694
+
695
+
696
+	/**
697
+	 * Gets HTML for laying out a deeply-nested array (and objects) in a format
698
+	 * that's nice for presenting in the wp admin
699
+	 *
700
+	 * @param mixed $data
701
+	 * @return string
702
+	 */
703
+	public static function layout_array_as_table($data)
704
+	{
705
+		if (is_object($data) || $data instanceof __PHP_Incomplete_Class) {
706
+			$data = (array) $data;
707
+		}
708
+		ob_start();
709
+		if (is_array($data)) {
710
+			if (EEH_Array::is_associative_array($data)) {
711
+				?>
712 712
                 <table class="widefat">
713 713
                     <tbody>
714 714
                     <?php
715
-                    foreach ($data as $data_key => $data_values) {
716
-                        ?>
715
+					foreach ($data as $data_key => $data_values) {
716
+						?>
717 717
                         <tr>
718 718
                             <td>
719 719
                                 <?php echo $data_key; ?>
@@ -723,291 +723,291 @@  discard block
 block discarded – undo
723 723
                             </td>
724 724
                         </tr>
725 725
                         <?php
726
-                    } ?>
726
+					} ?>
727 727
                     </tbody>
728 728
                 </table>
729 729
                 <?php
730
-            } else {
731
-                ?>
730
+			} else {
731
+				?>
732 732
                 <ul>
733 733
                     <?php
734
-                    foreach ($data as $datum) {
735
-                        echo "<li>";
736
-                        echo self::layout_array_as_table($datum);
737
-                        echo "</li>";
738
-                    } ?>
734
+					foreach ($data as $datum) {
735
+						echo "<li>";
736
+						echo self::layout_array_as_table($datum);
737
+						echo "</li>";
738
+					} ?>
739 739
                 </ul>
740 740
                 <?php
741
-            }
742
-        } else {
743
-            // simple value
744
-            echo esc_html($data);
745
-        }
746
-        return ob_get_clean();
747
-    }
748
-
749
-
750
-    /**
751
-     * wrapper for self::get_paging_html() that simply echos the generated paging html
752
-     *
753
-     * @since 4.4.0
754
-     * @see   self:get_paging_html() for argument docs.
755
-     * @param        $total_items
756
-     * @param        $current
757
-     * @param        $per_page
758
-     * @param        $url
759
-     * @param bool   $show_num_field
760
-     * @param string $paged_arg_name
761
-     * @param array  $items_label
762
-     * @return string
763
-     */
764
-    public static function paging_html(
765
-        $total_items,
766
-        $current,
767
-        $per_page,
768
-        $url,
769
-        $show_num_field = true,
770
-        $paged_arg_name = 'paged',
771
-        $items_label = array()
772
-    ) {
773
-        echo self::get_paging_html(
774
-            $total_items,
775
-            $current,
776
-            $per_page,
777
-            $url,
778
-            $show_num_field,
779
-            $paged_arg_name,
780
-            $items_label
781
-        );
782
-    }
783
-
784
-
785
-    /**
786
-     * A method for generating paging similar to WP_List_Table
787
-     *
788
-     * @since    4.4.0
789
-     * @see      wp-admin/includes/class-wp-list-table.php WP_List_Table::pagination()
790
-     * @param  integer $total_items     How many total items there are to page.
791
-     * @param  integer $current         What the current page is.
792
-     * @param  integer $per_page        How many items per page.
793
-     * @param  string  $url             What the base url for page links is.
794
-     * @param  boolean $show_num_field  Whether to show the input for changing page number.
795
-     * @param  string  $paged_arg_name  The name of the key for the paged query argument.
796
-     * @param  array   $items_label     An array of singular/plural values for the items label:
797
-     *                                  array(
798
-     *                                  'single' => 'item',
799
-     *                                  'plural' => 'items'
800
-     *                                  )
801
-     * @return  string
802
-     */
803
-    public static function get_paging_html(
804
-        $total_items,
805
-        $current,
806
-        $per_page,
807
-        $url,
808
-        $show_num_field = true,
809
-        $paged_arg_name = 'paged',
810
-        $items_label = array()
811
-    ) {
812
-        $page_links     = array();
813
-        $disable_first  = $disable_last = '';
814
-        $total_items    = (int) $total_items;
815
-        $per_page       = (int) $per_page;
816
-        $current        = (int) $current;
817
-        $paged_arg_name = empty($paged_arg_name) ? 'paged' : sanitize_key($paged_arg_name);
818
-
819
-        // filter items_label
820
-        $items_label = apply_filters(
821
-            'FHEE__EEH_Template__get_paging_html__items_label',
822
-            $items_label
823
-        );
824
-
825
-        if (empty($items_label)
826
-            || ! is_array($items_label)
827
-            || ! isset($items_label['single'])
828
-            || ! isset($items_label['plural'])
829
-        ) {
830
-            $items_label = array(
831
-                'single' => __('1 item', 'event_espresso'),
832
-                'plural' => __('%s items', 'event_espresso'),
833
-            );
834
-        } else {
835
-            $items_label = array(
836
-                'single' => '1 ' . esc_html($items_label['single']),
837
-                'plural' => '%s ' . esc_html($items_label['plural']),
838
-            );
839
-        }
840
-
841
-        $total_pages = ceil($total_items / $per_page);
842
-
843
-        if ($total_pages <= 1) {
844
-            return '';
845
-        }
846
-
847
-        $item_label = $total_items > 1 ? sprintf($items_label['plural'], $total_items) : $items_label['single'];
848
-
849
-        $output = '<span class="displaying-num">' . $item_label . '</span>';
850
-
851
-        if ($current === 1) {
852
-            $disable_first = ' disabled';
853
-        }
854
-        if ($current == $total_pages) {
855
-            $disable_last = ' disabled';
856
-        }
857
-
858
-        $page_links[] = sprintf(
859
-            "<a class='%s' title='%s' href='%s'>%s</a>",
860
-            'first-page' . $disable_first,
861
-            esc_attr__('Go to the first page', 'event_espresso'),
862
-            esc_url(remove_query_arg($paged_arg_name, $url)),
863
-            '&laquo;'
864
-        );
865
-
866
-        $page_links[] = sprintf(
867
-            '<a class="%s" title="%s" href="%s">%s</a>',
868
-            'prev-page' . $disable_first,
869
-            esc_attr__('Go to the previous page', 'event_espresso'),
870
-            esc_url(add_query_arg($paged_arg_name, max(1, $current - 1), $url)),
871
-            '&lsaquo;'
872
-        );
873
-
874
-        if (! $show_num_field) {
875
-            $html_current_page = $current;
876
-        } else {
877
-            $html_current_page = sprintf(
878
-                "<input class='current-page' title='%s' type='text' name=$paged_arg_name value='%s' size='%d' />",
879
-                esc_attr__('Current page', 'event_espresso'),
880
-                $current,
881
-                strlen($total_pages)
882
-            );
883
-        }
884
-
885
-        $html_total_pages = sprintf(
886
-            '<span class="total-pages">%s</span>',
887
-            number_format_i18n($total_pages)
888
-        );
889
-        $page_links[]     = sprintf(
890
-            _x('%3$s%1$s of %2$s%4$s', 'paging', 'event_espresso'),
891
-            $html_current_page,
892
-            $html_total_pages,
893
-            '<span class="paging-input">',
894
-            '</span>'
895
-        );
896
-
897
-        $page_links[] = sprintf(
898
-            '<a class="%s" title="%s" href="%s">%s</a>',
899
-            'next-page' . $disable_last,
900
-            esc_attr__('Go to the next page', 'event_espresso'),
901
-            esc_url(add_query_arg($paged_arg_name, min($total_pages, $current + 1), $url)),
902
-            '&rsaquo;'
903
-        );
904
-
905
-        $page_links[] = sprintf(
906
-            '<a class="%s" title="%s" href="%s">%s</a>',
907
-            'last-page' . $disable_last,
908
-            esc_attr__('Go to the last page', 'event_espresso'),
909
-            esc_url(add_query_arg($paged_arg_name, $total_pages, $url)),
910
-            '&raquo;'
911
-        );
912
-
913
-        $output .= "\n" . '<span class="pagination-links">' . join("\n", $page_links) . '</span>';
914
-        // set page class
915
-        if ($total_pages) {
916
-            $page_class = $total_pages < 2 ? ' one-page' : '';
917
-        } else {
918
-            $page_class = ' no-pages';
919
-        }
920
-
921
-        return '<div class="tablenav"><div class="tablenav-pages' . $page_class . '">' . $output . '</div></div>';
922
-    }
923
-
924
-
925
-    /**
926
-     * @param string $wrap_class
927
-     * @param string $wrap_id
928
-     * @return string
929
-     */
930
-    public static function powered_by_event_espresso($wrap_class = '', $wrap_id = '', array $query_args = array())
931
-    {
932
-        $admin = is_admin() && ! (defined('DOING_AJAX') && DOING_AJAX);
933
-        if (! $admin &&
934
-            ! apply_filters(
935
-                'FHEE__EEH_Template__powered_by_event_espresso__show_reg_footer',
936
-                EE_Registry::instance()->CFG->admin->show_reg_footer
937
-            )
938
-        ) {
939
-            return '';
940
-        }
941
-        $tag        = $admin ? 'span' : 'div';
942
-        $attributes = ! empty($wrap_id) ? " id=\"{$wrap_id}\"" : '';
943
-        $wrap_class = $admin ? "{$wrap_class} float-left" : $wrap_class;
944
-        $attributes .= ! empty($wrap_class)
945
-            ? " class=\"{$wrap_class} powered-by-event-espresso-credit\""
946
-            : ' class="powered-by-event-espresso-credit"';
947
-        $query_args = array_merge(
948
-            array(
949
-                'ap_id'        => EE_Registry::instance()->CFG->admin->affiliate_id(),
950
-                'utm_source'   => 'powered_by_event_espresso',
951
-                'utm_medium'   => 'link',
952
-                'utm_campaign' => 'powered_by',
953
-            ),
954
-            $query_args
955
-        );
956
-        $powered_by = apply_filters(
957
-            'FHEE__EEH_Template__powered_by_event_espresso_text',
958
-            $admin ? 'Event Espresso - ' . EVENT_ESPRESSO_VERSION : 'Event Espresso'
959
-        );
960
-        $url        = add_query_arg($query_args, 'https://eventespresso.com/');
961
-        $url        = apply_filters('FHEE__EEH_Template__powered_by_event_espresso__url', $url);
962
-        return (string) apply_filters(
963
-            'FHEE__EEH_Template__powered_by_event_espresso__html',
964
-            sprintf(
965
-                esc_html_x(
966
-                    '%3$s%1$sOnline event registration and ticketing powered by %2$s%3$s',
967
-                    'Online event registration and ticketing powered by [link to eventespresso.com]',
968
-                    'event_espresso'
969
-                ),
970
-                "<{$tag}{$attributes}>",
971
-                "<a href=\"{$url}\" target=\"_blank\" rel=\"nofollow\">{$powered_by}</a></{$tag}>",
972
-                $admin ? '' : '<br />'
973
-            ),
974
-            $wrap_class,
975
-            $wrap_id
976
-        );
977
-    }
741
+			}
742
+		} else {
743
+			// simple value
744
+			echo esc_html($data);
745
+		}
746
+		return ob_get_clean();
747
+	}
748
+
749
+
750
+	/**
751
+	 * wrapper for self::get_paging_html() that simply echos the generated paging html
752
+	 *
753
+	 * @since 4.4.0
754
+	 * @see   self:get_paging_html() for argument docs.
755
+	 * @param        $total_items
756
+	 * @param        $current
757
+	 * @param        $per_page
758
+	 * @param        $url
759
+	 * @param bool   $show_num_field
760
+	 * @param string $paged_arg_name
761
+	 * @param array  $items_label
762
+	 * @return string
763
+	 */
764
+	public static function paging_html(
765
+		$total_items,
766
+		$current,
767
+		$per_page,
768
+		$url,
769
+		$show_num_field = true,
770
+		$paged_arg_name = 'paged',
771
+		$items_label = array()
772
+	) {
773
+		echo self::get_paging_html(
774
+			$total_items,
775
+			$current,
776
+			$per_page,
777
+			$url,
778
+			$show_num_field,
779
+			$paged_arg_name,
780
+			$items_label
781
+		);
782
+	}
783
+
784
+
785
+	/**
786
+	 * A method for generating paging similar to WP_List_Table
787
+	 *
788
+	 * @since    4.4.0
789
+	 * @see      wp-admin/includes/class-wp-list-table.php WP_List_Table::pagination()
790
+	 * @param  integer $total_items     How many total items there are to page.
791
+	 * @param  integer $current         What the current page is.
792
+	 * @param  integer $per_page        How many items per page.
793
+	 * @param  string  $url             What the base url for page links is.
794
+	 * @param  boolean $show_num_field  Whether to show the input for changing page number.
795
+	 * @param  string  $paged_arg_name  The name of the key for the paged query argument.
796
+	 * @param  array   $items_label     An array of singular/plural values for the items label:
797
+	 *                                  array(
798
+	 *                                  'single' => 'item',
799
+	 *                                  'plural' => 'items'
800
+	 *                                  )
801
+	 * @return  string
802
+	 */
803
+	public static function get_paging_html(
804
+		$total_items,
805
+		$current,
806
+		$per_page,
807
+		$url,
808
+		$show_num_field = true,
809
+		$paged_arg_name = 'paged',
810
+		$items_label = array()
811
+	) {
812
+		$page_links     = array();
813
+		$disable_first  = $disable_last = '';
814
+		$total_items    = (int) $total_items;
815
+		$per_page       = (int) $per_page;
816
+		$current        = (int) $current;
817
+		$paged_arg_name = empty($paged_arg_name) ? 'paged' : sanitize_key($paged_arg_name);
818
+
819
+		// filter items_label
820
+		$items_label = apply_filters(
821
+			'FHEE__EEH_Template__get_paging_html__items_label',
822
+			$items_label
823
+		);
824
+
825
+		if (empty($items_label)
826
+			|| ! is_array($items_label)
827
+			|| ! isset($items_label['single'])
828
+			|| ! isset($items_label['plural'])
829
+		) {
830
+			$items_label = array(
831
+				'single' => __('1 item', 'event_espresso'),
832
+				'plural' => __('%s items', 'event_espresso'),
833
+			);
834
+		} else {
835
+			$items_label = array(
836
+				'single' => '1 ' . esc_html($items_label['single']),
837
+				'plural' => '%s ' . esc_html($items_label['plural']),
838
+			);
839
+		}
840
+
841
+		$total_pages = ceil($total_items / $per_page);
842
+
843
+		if ($total_pages <= 1) {
844
+			return '';
845
+		}
846
+
847
+		$item_label = $total_items > 1 ? sprintf($items_label['plural'], $total_items) : $items_label['single'];
848
+
849
+		$output = '<span class="displaying-num">' . $item_label . '</span>';
850
+
851
+		if ($current === 1) {
852
+			$disable_first = ' disabled';
853
+		}
854
+		if ($current == $total_pages) {
855
+			$disable_last = ' disabled';
856
+		}
857
+
858
+		$page_links[] = sprintf(
859
+			"<a class='%s' title='%s' href='%s'>%s</a>",
860
+			'first-page' . $disable_first,
861
+			esc_attr__('Go to the first page', 'event_espresso'),
862
+			esc_url(remove_query_arg($paged_arg_name, $url)),
863
+			'&laquo;'
864
+		);
865
+
866
+		$page_links[] = sprintf(
867
+			'<a class="%s" title="%s" href="%s">%s</a>',
868
+			'prev-page' . $disable_first,
869
+			esc_attr__('Go to the previous page', 'event_espresso'),
870
+			esc_url(add_query_arg($paged_arg_name, max(1, $current - 1), $url)),
871
+			'&lsaquo;'
872
+		);
873
+
874
+		if (! $show_num_field) {
875
+			$html_current_page = $current;
876
+		} else {
877
+			$html_current_page = sprintf(
878
+				"<input class='current-page' title='%s' type='text' name=$paged_arg_name value='%s' size='%d' />",
879
+				esc_attr__('Current page', 'event_espresso'),
880
+				$current,
881
+				strlen($total_pages)
882
+			);
883
+		}
884
+
885
+		$html_total_pages = sprintf(
886
+			'<span class="total-pages">%s</span>',
887
+			number_format_i18n($total_pages)
888
+		);
889
+		$page_links[]     = sprintf(
890
+			_x('%3$s%1$s of %2$s%4$s', 'paging', 'event_espresso'),
891
+			$html_current_page,
892
+			$html_total_pages,
893
+			'<span class="paging-input">',
894
+			'</span>'
895
+		);
896
+
897
+		$page_links[] = sprintf(
898
+			'<a class="%s" title="%s" href="%s">%s</a>',
899
+			'next-page' . $disable_last,
900
+			esc_attr__('Go to the next page', 'event_espresso'),
901
+			esc_url(add_query_arg($paged_arg_name, min($total_pages, $current + 1), $url)),
902
+			'&rsaquo;'
903
+		);
904
+
905
+		$page_links[] = sprintf(
906
+			'<a class="%s" title="%s" href="%s">%s</a>',
907
+			'last-page' . $disable_last,
908
+			esc_attr__('Go to the last page', 'event_espresso'),
909
+			esc_url(add_query_arg($paged_arg_name, $total_pages, $url)),
910
+			'&raquo;'
911
+		);
912
+
913
+		$output .= "\n" . '<span class="pagination-links">' . join("\n", $page_links) . '</span>';
914
+		// set page class
915
+		if ($total_pages) {
916
+			$page_class = $total_pages < 2 ? ' one-page' : '';
917
+		} else {
918
+			$page_class = ' no-pages';
919
+		}
920
+
921
+		return '<div class="tablenav"><div class="tablenav-pages' . $page_class . '">' . $output . '</div></div>';
922
+	}
923
+
924
+
925
+	/**
926
+	 * @param string $wrap_class
927
+	 * @param string $wrap_id
928
+	 * @return string
929
+	 */
930
+	public static function powered_by_event_espresso($wrap_class = '', $wrap_id = '', array $query_args = array())
931
+	{
932
+		$admin = is_admin() && ! (defined('DOING_AJAX') && DOING_AJAX);
933
+		if (! $admin &&
934
+			! apply_filters(
935
+				'FHEE__EEH_Template__powered_by_event_espresso__show_reg_footer',
936
+				EE_Registry::instance()->CFG->admin->show_reg_footer
937
+			)
938
+		) {
939
+			return '';
940
+		}
941
+		$tag        = $admin ? 'span' : 'div';
942
+		$attributes = ! empty($wrap_id) ? " id=\"{$wrap_id}\"" : '';
943
+		$wrap_class = $admin ? "{$wrap_class} float-left" : $wrap_class;
944
+		$attributes .= ! empty($wrap_class)
945
+			? " class=\"{$wrap_class} powered-by-event-espresso-credit\""
946
+			: ' class="powered-by-event-espresso-credit"';
947
+		$query_args = array_merge(
948
+			array(
949
+				'ap_id'        => EE_Registry::instance()->CFG->admin->affiliate_id(),
950
+				'utm_source'   => 'powered_by_event_espresso',
951
+				'utm_medium'   => 'link',
952
+				'utm_campaign' => 'powered_by',
953
+			),
954
+			$query_args
955
+		);
956
+		$powered_by = apply_filters(
957
+			'FHEE__EEH_Template__powered_by_event_espresso_text',
958
+			$admin ? 'Event Espresso - ' . EVENT_ESPRESSO_VERSION : 'Event Espresso'
959
+		);
960
+		$url        = add_query_arg($query_args, 'https://eventespresso.com/');
961
+		$url        = apply_filters('FHEE__EEH_Template__powered_by_event_espresso__url', $url);
962
+		return (string) apply_filters(
963
+			'FHEE__EEH_Template__powered_by_event_espresso__html',
964
+			sprintf(
965
+				esc_html_x(
966
+					'%3$s%1$sOnline event registration and ticketing powered by %2$s%3$s',
967
+					'Online event registration and ticketing powered by [link to eventespresso.com]',
968
+					'event_espresso'
969
+				),
970
+				"<{$tag}{$attributes}>",
971
+				"<a href=\"{$url}\" target=\"_blank\" rel=\"nofollow\">{$powered_by}</a></{$tag}>",
972
+				$admin ? '' : '<br />'
973
+			),
974
+			$wrap_class,
975
+			$wrap_id
976
+		);
977
+	}
978 978
 }
979 979
 
980 980
 
981 981
 
982 982
 
983 983
 if (! function_exists('espresso_pagination')) {
984
-    /**
985
-     *    espresso_pagination
986
-     *
987
-     * @access    public
988
-     * @return    void
989
-     */
990
-    function espresso_pagination()
991
-    {
992
-        global $wp_query;
993
-        $big        = 999999999; // need an unlikely integer
994
-        $pagination = paginate_links(
995
-            array(
996
-                'base'         => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
997
-                'format'       => '?paged=%#%',
998
-                'current'      => max(1, get_query_var('paged')),
999
-                'total'        => $wp_query->max_num_pages,
1000
-                'show_all'     => true,
1001
-                'end_size'     => 10,
1002
-                'mid_size'     => 6,
1003
-                'prev_next'    => true,
1004
-                'prev_text'    => __('&lsaquo; PREV', 'event_espresso'),
1005
-                'next_text'    => __('NEXT &rsaquo;', 'event_espresso'),
1006
-                'type'         => 'plain',
1007
-                'add_args'     => false,
1008
-                'add_fragment' => '',
1009
-            )
1010
-        );
1011
-        echo ! empty($pagination) ? '<div class="ee-pagination-dv ee-clear-float">' . $pagination . '</div>' : '';
1012
-    }
984
+	/**
985
+	 *    espresso_pagination
986
+	 *
987
+	 * @access    public
988
+	 * @return    void
989
+	 */
990
+	function espresso_pagination()
991
+	{
992
+		global $wp_query;
993
+		$big        = 999999999; // need an unlikely integer
994
+		$pagination = paginate_links(
995
+			array(
996
+				'base'         => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
997
+				'format'       => '?paged=%#%',
998
+				'current'      => max(1, get_query_var('paged')),
999
+				'total'        => $wp_query->max_num_pages,
1000
+				'show_all'     => true,
1001
+				'end_size'     => 10,
1002
+				'mid_size'     => 6,
1003
+				'prev_next'    => true,
1004
+				'prev_text'    => __('&lsaquo; PREV', 'event_espresso'),
1005
+				'next_text'    => __('NEXT &rsaquo;', 'event_espresso'),
1006
+				'type'         => 'plain',
1007
+				'add_args'     => false,
1008
+				'add_fragment' => '',
1009
+			)
1010
+		);
1011
+		echo ! empty($pagination) ? '<div class="ee-pagination-dv ee-clear-float">' . $pagination . '</div>' : '';
1012
+	}
1013 1013
 }
1014 1014
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +74 added lines, -74 removed lines patch added patch discarded remove patch
@@ -4,7 +4,7 @@  discard block
 block discarded – undo
4 4
 use EventEspresso\core\exceptions\InvalidInterfaceException;
5 5
 use EventEspresso\core\services\loaders\LoaderFactory;
6 6
 
7
-if (! function_exists('espresso_get_template_part')) {
7
+if ( ! function_exists('espresso_get_template_part')) {
8 8
     /**
9 9
      * espresso_get_template_part
10 10
      * 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
@@ -21,7 +21,7 @@  discard block
 block discarded – undo
21 21
 }
22 22
 
23 23
 
24
-if (! function_exists('espresso_get_object_css_class')) {
24
+if ( ! function_exists('espresso_get_object_css_class')) {
25 25
     /**
26 26
      * espresso_get_object_css_class - attempts to generate a css class based on the type of EE object passed
27 27
      *
@@ -69,9 +69,9 @@  discard block
 block discarded – undo
69 69
      */
70 70
     public static function load_espresso_theme_functions()
71 71
     {
72
-        if (! defined('EE_THEME_FUNCTIONS_LOADED')) {
73
-            if (is_readable(EE_PUBLIC . EE_Config::get_current_theme() . '/functions.php')) {
74
-                require_once(EE_PUBLIC . EE_Config::get_current_theme() . '/functions.php');
72
+        if ( ! defined('EE_THEME_FUNCTIONS_LOADED')) {
73
+            if (is_readable(EE_PUBLIC.EE_Config::get_current_theme().'/functions.php')) {
74
+                require_once(EE_PUBLIC.EE_Config::get_current_theme().'/functions.php');
75 75
             }
76 76
         }
77 77
     }
@@ -85,16 +85,16 @@  discard block
 block discarded – undo
85 85
     public static function get_espresso_themes()
86 86
     {
87 87
         if (empty(EEH_Template::$_espresso_themes)) {
88
-            $espresso_themes = glob(EE_PUBLIC . '*', GLOB_ONLYDIR);
88
+            $espresso_themes = glob(EE_PUBLIC.'*', GLOB_ONLYDIR);
89 89
             if (empty($espresso_themes)) {
90 90
                 return array();
91 91
             }
92 92
             if (($key = array_search('global_assets', $espresso_themes)) !== false) {
93
-                unset($espresso_themes[ $key ]);
93
+                unset($espresso_themes[$key]);
94 94
             }
95 95
             EEH_Template::$_espresso_themes = array();
96 96
             foreach ($espresso_themes as $espresso_theme) {
97
-                EEH_Template::$_espresso_themes[ basename($espresso_theme) ] = $espresso_theme;
97
+                EEH_Template::$_espresso_themes[basename($espresso_theme)] = $espresso_theme;
98 98
             }
99 99
         }
100 100
         return EEH_Template::$_espresso_themes;
@@ -205,10 +205,10 @@  discard block
 block discarded – undo
205 205
                 // get array of EE Custom Post Types
206 206
                 $EE_CPTs = $custom_post_types->getDefinitions();
207 207
                 // build template name based on request
208
-                if (isset($EE_CPTs[ $post_type ])) {
208
+                if (isset($EE_CPTs[$post_type])) {
209 209
                     $archive_or_single = is_archive() ? 'archive' : '';
210 210
                     $archive_or_single = is_single() ? 'single' : $archive_or_single;
211
-                    $templates         = $archive_or_single . '-' . $post_type . '.php';
211
+                    $templates         = $archive_or_single.'-'.$post_type.'.php';
212 212
                 }
213 213
             }
214 214
             // currently active EE template theme
@@ -217,18 +217,18 @@  discard block
 block discarded – undo
217 217
             // array of paths to folders that may contain templates
218 218
             $template_folder_paths = array(
219 219
                 // first check the /wp-content/uploads/espresso/templates/(current EE theme)/  folder for an EE theme template file
220
-                EVENT_ESPRESSO_TEMPLATE_DIR . $current_theme,
220
+                EVENT_ESPRESSO_TEMPLATE_DIR.$current_theme,
221 221
                 // then in the root of the /wp-content/uploads/espresso/templates/ folder
222 222
                 EVENT_ESPRESSO_TEMPLATE_DIR,
223 223
             );
224 224
 
225 225
             // add core plugin folders for checking only if we're not $check_if_custom
226
-            if (! $check_if_custom) {
227
-                $core_paths            = array(
226
+            if ( ! $check_if_custom) {
227
+                $core_paths = array(
228 228
                     // in the  /wp-content/plugins/(EE4 folder)/public/(current EE theme)/ folder within the plugin
229
-                    EE_PUBLIC . $current_theme,
229
+                    EE_PUBLIC.$current_theme,
230 230
                     // in the  /wp-content/plugins/(EE4 folder)/core/templates/(current EE theme)/ folder within the plugin
231
-                    EE_TEMPLATES . $current_theme,
231
+                    EE_TEMPLATES.$current_theme,
232 232
                     // or maybe relative from the plugin root: /wp-content/plugins/(EE4 folder)/
233 233
                     EE_PLUGIN_DIR_PATH,
234 234
                 );
@@ -261,10 +261,10 @@  discard block
 block discarded – undo
261 261
                     );
262 262
                     if ($common_base_path !== '') {
263 263
                         // both paths have a common base, so just tack the filename onto our search path
264
-                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $file_name;
264
+                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path).$file_name;
265 265
                     } else {
266 266
                         // no common base path, so let's just concatenate
267
-                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $template;
267
+                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path).$template;
268 268
                     }
269 269
                     // build up our template locations array by adding our resolved paths
270 270
                     $full_template_paths[] = $resolved_path;
@@ -272,7 +272,7 @@  discard block
 block discarded – undo
272 272
                 // if $template is an absolute path, then we'll tack it onto the start of our array so that it gets searched first
273 273
                 array_unshift($full_template_paths, $template);
274 274
                 // path to the directory of the current theme: /wp-content/themes/(current WP theme)/
275
-                array_unshift($full_template_paths, get_stylesheet_directory() . '/' . $file_name);
275
+                array_unshift($full_template_paths, get_stylesheet_directory().'/'.$file_name);
276 276
             }
277 277
             // filter final array of full template paths
278 278
             $full_template_paths = apply_filters(
@@ -361,11 +361,11 @@  discard block
 block discarded – undo
361 361
         $template_args = (array) apply_filters('FHEE__EEH_Template__display_template__template_args', $template_args);
362 362
 
363 363
         // you gimme nuttin - YOU GET NUTTIN !!
364
-        if (! $template_path || ! is_readable($template_path)) {
364
+        if ( ! $template_path || ! is_readable($template_path)) {
365 365
             return '';
366 366
         }
367 367
         // if $template_args are not in an array, then make it so
368
-        if (! is_array($template_args) && ! is_object($template_args)) {
368
+        if ( ! is_array($template_args) && ! is_object($template_args)) {
369 369
             $template_args = array($template_args);
370 370
         }
371 371
         extract($template_args, EXTR_SKIP);
@@ -403,11 +403,11 @@  discard block
 block discarded – undo
403 403
     public static function get_object_css_class($object = null, $prefix = '', $suffix = '')
404 404
     {
405 405
         // in the beginning...
406
-        $prefix = ! empty($prefix) ? rtrim($prefix, '-') . '-' : '';
406
+        $prefix = ! empty($prefix) ? rtrim($prefix, '-').'-' : '';
407 407
         // da muddle
408 408
         $class = '';
409 409
         // the end
410
-        $suffix = ! empty($suffix) ? '-' . ltrim($suffix, '-') : '';
410
+        $suffix = ! empty($suffix) ? '-'.ltrim($suffix, '-') : '';
411 411
         // is the passed object an EE object ?
412 412
         if ($object instanceof EE_Base_Class) {
413 413
             // grab the exact type of object
@@ -417,10 +417,10 @@  discard block
 block discarded – undo
417 417
                 // no specifics just yet...
418 418
                 default:
419 419
                     $class = strtolower(str_replace('_', '-', $obj_class));
420
-                    $class .= method_exists($obj_class, 'name') ? '-' . sanitize_title($object->name()) : '';
420
+                    $class .= method_exists($obj_class, 'name') ? '-'.sanitize_title($object->name()) : '';
421 421
             }
422 422
         }
423
-        return $prefix . $class . $suffix;
423
+        return $prefix.$class.$suffix;
424 424
     }
425 425
 
426 426
 
@@ -461,7 +461,7 @@  discard block
 block discarded – undo
461 461
             // was a country ISO code passed ? if so generate currency config object for that country
462 462
             $mny = $CNT_ISO !== '' ? new EE_Currency_Config($CNT_ISO) : null;
463 463
             // verify results
464
-            if (! $mny instanceof EE_Currency_Config) {
464
+            if ( ! $mny instanceof EE_Currency_Config) {
465 465
                 // set default config country currency settings
466 466
                 $mny = EE_Registry::instance()->CFG->currency instanceof EE_Currency_Config
467 467
                     ? EE_Registry::instance()->CFG->currency
@@ -470,23 +470,23 @@  discard block
 block discarded – undo
470 470
             // format float
471 471
             $amount_formatted = number_format($amount, $mny->dec_plc, $mny->dec_mrk, $mny->thsnds);
472 472
             // add formatting ?
473
-            if (! $return_raw) {
473
+            if ( ! $return_raw) {
474 474
                 // add currency sign
475 475
                 if ($mny->sign_b4) {
476 476
                     if ($amount >= 0) {
477
-                        $amount_formatted = $mny->sign . $amount_formatted;
477
+                        $amount_formatted = $mny->sign.$amount_formatted;
478 478
                     } else {
479
-                        $amount_formatted = '-' . $mny->sign . str_replace('-', '', $amount_formatted);
479
+                        $amount_formatted = '-'.$mny->sign.str_replace('-', '', $amount_formatted);
480 480
                     }
481 481
                 } else {
482
-                    $amount_formatted = $amount_formatted . $mny->sign;
482
+                    $amount_formatted = $amount_formatted.$mny->sign;
483 483
                 }
484 484
 
485 485
                 // filter to allow global setting of display_code
486 486
                 $display_code = apply_filters('FHEE__EEH_Template__format_currency__display_code', $display_code);
487 487
 
488 488
                 // add currency code ?
489
-                $amount_formatted = $display_code ? $amount_formatted . ' <span class="' . $cur_code_span_class . '">(' . $mny->code . ')</span>' : $amount_formatted;
489
+                $amount_formatted = $display_code ? $amount_formatted.' <span class="'.$cur_code_span_class.'">('.$mny->code.')</span>' : $amount_formatted;
490 490
             }
491 491
             // filter results
492 492
             $amount_formatted = apply_filters(
@@ -523,7 +523,7 @@  discard block
 block discarded – undo
523 523
             $plural,
524 524
             $schema
525 525
         );
526
-        return $status[ $status_id ];
526
+        return $status[$status_id];
527 527
     }
528 528
 
529 529
 
@@ -540,19 +540,19 @@  discard block
 block discarded – undo
540 540
     public static function get_button_or_link($url, $label, $class = 'button-primary', $icon = '', $title = '')
541 541
     {
542 542
         $icon_html = '';
543
-        if (! empty($icon)) {
543
+        if ( ! empty($icon)) {
544 544
             $dashicons = preg_split("(ee-icon |dashicons )", $icon);
545 545
             $dashicons = array_filter($dashicons);
546 546
             $count     = count($dashicons);
547 547
             $icon_html .= $count > 1 ? '<span class="ee-composite-dashicon">' : '';
548 548
             foreach ($dashicons as $dashicon) {
549 549
                 $type = strpos($dashicon, 'ee-icon') !== false ? 'ee-icon ' : 'dashicons ';
550
-                $icon_html .= '<span class="' . $type . $dashicon . '"></span>';
550
+                $icon_html .= '<span class="'.$type.$dashicon.'"></span>';
551 551
             }
552 552
             $icon_html .= $count > 1 ? '</span>' : '';
553 553
         }
554
-        $label  = ! empty($icon) ? $icon_html . $label : $label;
555
-        $button = '<a id="' . sanitize_title_with_dashes($label) . '" href="' . esc_url($url) . '" class="' . $class . '" title="' . $title . '">' . $label . '</a>';
554
+        $label  = ! empty($icon) ? $icon_html.$label : $label;
555
+        $button = '<a id="'.sanitize_title_with_dashes($label).'" href="'.esc_url($url).'" class="'.$class.'" title="'.$title.'">'.$label.'</a>';
556 556
         return $button;
557 557
     }
558 558
 
@@ -575,24 +575,24 @@  discard block
 block discarded – undo
575 575
         $help_text = false
576 576
     ) {
577 577
 
578
-        if (! $page) {
578
+        if ( ! $page) {
579 579
             $page = isset($_REQUEST['page']) && ! empty($_REQUEST['page']) ? sanitize_key($_REQUEST['page']) : $page;
580 580
         }
581 581
 
582
-        if (! $action) {
582
+        if ( ! $action) {
583 583
             $action = isset($_REQUEST['action']) && ! empty($_REQUEST['action']) ? sanitize_key($_REQUEST['action']) : $action;
584 584
         }
585 585
 
586 586
         $action = empty($action) ? 'default' : $action;
587 587
 
588 588
 
589
-        $help_tab_lnk = $page . '-' . $action . '-' . $help_tab_id;
589
+        $help_tab_lnk = $page.'-'.$action.'-'.$help_tab_id;
590 590
         $icon         = ! $icon_style ? ' dashicons-editor-help' : $icon_style;
591 591
         $help_text    = ! $help_text ? '' : $help_text;
592
-        return '<a id="' . $help_tab_lnk . '" class="ee-clickable dashicons espresso-help-tab-lnk ee-icon-size-22' . $icon . '" title="' . esc_attr__(
592
+        return '<a id="'.$help_tab_lnk.'" class="ee-clickable dashicons espresso-help-tab-lnk ee-icon-size-22'.$icon.'" title="'.esc_attr__(
593 593
             'Click to open the \'Help\' tab for more information about this feature.',
594 594
             'event_espresso'
595
-        ) . '" > ' . $help_text . ' </a>';
595
+        ).'" > '.$help_text.' </a>';
596 596
     }
597 597
 
598 598
 
@@ -609,11 +609,11 @@  discard block
 block discarded – undo
609 609
         $id    = $tour->get_slug();
610 610
         $stops = $tour->get_stops();
611 611
 
612
-        $content = '<ol style="display:none" id="' . $id . '">';
612
+        $content = '<ol style="display:none" id="'.$id.'">';
613 613
 
614 614
         foreach ($stops as $stop) {
615
-            $data_id    = ! empty($stop['id']) ? ' data-id="' . $stop['id'] . '"' : '';
616
-            $data_class = empty($data_id) && ! empty($stop['class']) ? ' data-class="' . $stop['class'] . '"' : '';
615
+            $data_id    = ! empty($stop['id']) ? ' data-id="'.$stop['id'].'"' : '';
616
+            $data_class = empty($data_id) && ! empty($stop['class']) ? ' data-class="'.$stop['class'].'"' : '';
617 617
 
618 618
             // if container is set to modal then let's make sure we set the options accordingly
619 619
             if (empty($data_id) && empty($data_class)) {
@@ -621,15 +621,15 @@  discard block
 block discarded – undo
621 621
                 $stop['options']['expose'] = true;
622 622
             }
623 623
 
624
-            $custom_class  = ! empty($stop['custom_class']) ? ' class="' . $stop['custom_class'] . '"' : '';
625
-            $button_text   = ! empty($stop['button_text']) ? ' data-button="' . $stop['button_text'] . '"' : '';
624
+            $custom_class  = ! empty($stop['custom_class']) ? ' class="'.$stop['custom_class'].'"' : '';
625
+            $button_text   = ! empty($stop['button_text']) ? ' data-button="'.$stop['button_text'].'"' : '';
626 626
             $inner_content = isset($stop['content']) ? $stop['content'] : '';
627 627
 
628 628
             // options
629 629
             if (isset($stop['options']) && is_array($stop['options'])) {
630 630
                 $options = ' data-options="';
631 631
                 foreach ($stop['options'] as $option => $value) {
632
-                    $options .= $option . ':' . $value . ';';
632
+                    $options .= $option.':'.$value.';';
633 633
                 }
634 634
                 $options .= '"';
635 635
             } else {
@@ -637,7 +637,7 @@  discard block
 block discarded – undo
637 637
             }
638 638
 
639 639
             // let's put all together
640
-            $content .= '<li' . $data_id . $data_class . $custom_class . $button_text . $options . '>' . $inner_content . '</li>';
640
+            $content .= '<li'.$data_id.$data_class.$custom_class.$button_text.$options.'>'.$inner_content.'</li>';
641 641
         }
642 642
 
643 643
         $content .= '</ol>';
@@ -661,7 +661,7 @@  discard block
 block discarded – undo
661 661
      */
662 662
     public static function status_legend($status_array, $active_status = '')
663 663
     {
664
-        if (! is_array($status_array)) {
664
+        if ( ! is_array($status_array)) {
665 665
             throw new EE_Error(esc_html__(
666 666
                 'The EEH_Template::status_legend helper required the incoming status_array argument to be an array!',
667 667
                 'event_espresso'
@@ -670,25 +670,25 @@  discard block
 block discarded – undo
670 670
 
671 671
         $setup_array = array();
672 672
         foreach ($status_array as $item => $status) {
673
-            $setup_array[ $item ] = array(
674
-                'class'  => 'ee-status-legend ee-status-legend-' . $status,
673
+            $setup_array[$item] = array(
674
+                'class'  => 'ee-status-legend ee-status-legend-'.$status,
675 675
                 'desc'   => EEH_Template::pretty_status($status, false, 'sentence'),
676 676
                 'status' => $status,
677 677
             );
678 678
         }
679 679
 
680
-        $content = '<div class="ee-list-table-legend-container">' . "\n";
681
-        $content .= '<h4 class="status-legend-title">' . esc_html__('Status Legend', 'event_espresso') . '</h4>' . "\n";
682
-        $content .= '<dl class="ee-list-table-legend">' . "\n\t";
680
+        $content = '<div class="ee-list-table-legend-container">'."\n";
681
+        $content .= '<h4 class="status-legend-title">'.esc_html__('Status Legend', 'event_espresso').'</h4>'."\n";
682
+        $content .= '<dl class="ee-list-table-legend">'."\n\t";
683 683
         foreach ($setup_array as $item => $details) {
684 684
             $active_class = $active_status == $details['status'] ? ' class="ee-is-active-status"' : '';
685
-            $content .= '<dt id="ee-legend-item-tooltip-' . $item . '"' . $active_class . '>' . "\n\t\t";
686
-            $content .= '<span class="ee-legend-item-wrap"><span class="' . $details['class'] . '"></span></span>' . "\n\t\t";
687
-            $content .= '<span class="ee-legend-description">' . $details['desc'] . '</span>' . "\n\t";
688
-            $content .= '</dt>' . "\n";
685
+            $content .= '<dt id="ee-legend-item-tooltip-'.$item.'"'.$active_class.'>'."\n\t\t";
686
+            $content .= '<span class="ee-legend-item-wrap"><span class="'.$details['class'].'"></span></span>'."\n\t\t";
687
+            $content .= '<span class="ee-legend-description">'.$details['desc'].'</span>'."\n\t";
688
+            $content .= '</dt>'."\n";
689 689
         }
690
-        $content .= '</dl>' . "\n";
691
-        $content .= '</div>' . "\n";
690
+        $content .= '</dl>'."\n";
691
+        $content .= '</div>'."\n";
692 692
         return $content;
693 693
     }
694 694
 
@@ -833,8 +833,8 @@  discard block
 block discarded – undo
833 833
             );
834 834
         } else {
835 835
             $items_label = array(
836
-                'single' => '1 ' . esc_html($items_label['single']),
837
-                'plural' => '%s ' . esc_html($items_label['plural']),
836
+                'single' => '1 '.esc_html($items_label['single']),
837
+                'plural' => '%s '.esc_html($items_label['plural']),
838 838
             );
839 839
         }
840 840
 
@@ -846,7 +846,7 @@  discard block
 block discarded – undo
846 846
 
847 847
         $item_label = $total_items > 1 ? sprintf($items_label['plural'], $total_items) : $items_label['single'];
848 848
 
849
-        $output = '<span class="displaying-num">' . $item_label . '</span>';
849
+        $output = '<span class="displaying-num">'.$item_label.'</span>';
850 850
 
851 851
         if ($current === 1) {
852 852
             $disable_first = ' disabled';
@@ -857,7 +857,7 @@  discard block
 block discarded – undo
857 857
 
858 858
         $page_links[] = sprintf(
859 859
             "<a class='%s' title='%s' href='%s'>%s</a>",
860
-            'first-page' . $disable_first,
860
+            'first-page'.$disable_first,
861 861
             esc_attr__('Go to the first page', 'event_espresso'),
862 862
             esc_url(remove_query_arg($paged_arg_name, $url)),
863 863
             '&laquo;'
@@ -865,13 +865,13 @@  discard block
 block discarded – undo
865 865
 
866 866
         $page_links[] = sprintf(
867 867
             '<a class="%s" title="%s" href="%s">%s</a>',
868
-            'prev-page' . $disable_first,
868
+            'prev-page'.$disable_first,
869 869
             esc_attr__('Go to the previous page', 'event_espresso'),
870 870
             esc_url(add_query_arg($paged_arg_name, max(1, $current - 1), $url)),
871 871
             '&lsaquo;'
872 872
         );
873 873
 
874
-        if (! $show_num_field) {
874
+        if ( ! $show_num_field) {
875 875
             $html_current_page = $current;
876 876
         } else {
877 877
             $html_current_page = sprintf(
@@ -886,7 +886,7 @@  discard block
 block discarded – undo
886 886
             '<span class="total-pages">%s</span>',
887 887
             number_format_i18n($total_pages)
888 888
         );
889
-        $page_links[]     = sprintf(
889
+        $page_links[] = sprintf(
890 890
             _x('%3$s%1$s of %2$s%4$s', 'paging', 'event_espresso'),
891 891
             $html_current_page,
892 892
             $html_total_pages,
@@ -896,7 +896,7 @@  discard block
 block discarded – undo
896 896
 
897 897
         $page_links[] = sprintf(
898 898
             '<a class="%s" title="%s" href="%s">%s</a>',
899
-            'next-page' . $disable_last,
899
+            'next-page'.$disable_last,
900 900
             esc_attr__('Go to the next page', 'event_espresso'),
901 901
             esc_url(add_query_arg($paged_arg_name, min($total_pages, $current + 1), $url)),
902 902
             '&rsaquo;'
@@ -904,13 +904,13 @@  discard block
 block discarded – undo
904 904
 
905 905
         $page_links[] = sprintf(
906 906
             '<a class="%s" title="%s" href="%s">%s</a>',
907
-            'last-page' . $disable_last,
907
+            'last-page'.$disable_last,
908 908
             esc_attr__('Go to the last page', 'event_espresso'),
909 909
             esc_url(add_query_arg($paged_arg_name, $total_pages, $url)),
910 910
             '&raquo;'
911 911
         );
912 912
 
913
-        $output .= "\n" . '<span class="pagination-links">' . join("\n", $page_links) . '</span>';
913
+        $output .= "\n".'<span class="pagination-links">'.join("\n", $page_links).'</span>';
914 914
         // set page class
915 915
         if ($total_pages) {
916 916
             $page_class = $total_pages < 2 ? ' one-page' : '';
@@ -918,7 +918,7 @@  discard block
 block discarded – undo
918 918
             $page_class = ' no-pages';
919 919
         }
920 920
 
921
-        return '<div class="tablenav"><div class="tablenav-pages' . $page_class . '">' . $output . '</div></div>';
921
+        return '<div class="tablenav"><div class="tablenav-pages'.$page_class.'">'.$output.'</div></div>';
922 922
     }
923 923
 
924 924
 
@@ -930,7 +930,7 @@  discard block
 block discarded – undo
930 930
     public static function powered_by_event_espresso($wrap_class = '', $wrap_id = '', array $query_args = array())
931 931
     {
932 932
         $admin = is_admin() && ! (defined('DOING_AJAX') && DOING_AJAX);
933
-        if (! $admin &&
933
+        if ( ! $admin &&
934 934
             ! apply_filters(
935 935
                 'FHEE__EEH_Template__powered_by_event_espresso__show_reg_footer',
936 936
                 EE_Registry::instance()->CFG->admin->show_reg_footer
@@ -955,7 +955,7 @@  discard block
 block discarded – undo
955 955
         );
956 956
         $powered_by = apply_filters(
957 957
             'FHEE__EEH_Template__powered_by_event_espresso_text',
958
-            $admin ? 'Event Espresso - ' . EVENT_ESPRESSO_VERSION : 'Event Espresso'
958
+            $admin ? 'Event Espresso - '.EVENT_ESPRESSO_VERSION : 'Event Espresso'
959 959
         );
960 960
         $url        = add_query_arg($query_args, 'https://eventespresso.com/');
961 961
         $url        = apply_filters('FHEE__EEH_Template__powered_by_event_espresso__url', $url);
@@ -980,7 +980,7 @@  discard block
 block discarded – undo
980 980
 
981 981
 
982 982
 
983
-if (! function_exists('espresso_pagination')) {
983
+if ( ! function_exists('espresso_pagination')) {
984 984
     /**
985 985
      *    espresso_pagination
986 986
      *
@@ -1008,6 +1008,6 @@  discard block
 block discarded – undo
1008 1008
                 'add_fragment' => '',
1009 1009
             )
1010 1010
         );
1011
-        echo ! empty($pagination) ? '<div class="ee-pagination-dv ee-clear-float">' . $pagination . '</div>' : '';
1011
+        echo ! empty($pagination) ? '<div class="ee-pagination-dv ee-clear-float">'.$pagination.'</div>' : '';
1012 1012
     }
1013 1013
 }
1014 1014
\ No newline at end of file
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page.core.php 2 patches
Indentation   +4140 added lines, -4140 removed lines patch added patch discarded remove patch
@@ -17,4208 +17,4208 @@
 block discarded – undo
17 17
 abstract class EE_Admin_Page extends EE_Base implements InterminableInterface
18 18
 {
19 19
 
20
-    /**
21
-     * @var LoaderInterface $loader
22
-     */
23
-    protected $loader;
20
+	/**
21
+	 * @var LoaderInterface $loader
22
+	 */
23
+	protected $loader;
24 24
 
25
-    // set in _init_page_props()
26
-    public $page_slug;
25
+	// set in _init_page_props()
26
+	public $page_slug;
27 27
 
28
-    public $page_label;
28
+	public $page_label;
29 29
 
30
-    public $page_folder;
30
+	public $page_folder;
31 31
 
32
-    // set in define_page_props()
33
-    protected $_admin_base_url;
32
+	// set in define_page_props()
33
+	protected $_admin_base_url;
34 34
 
35
-    protected $_admin_base_path;
35
+	protected $_admin_base_path;
36 36
 
37
-    protected $_admin_page_title;
37
+	protected $_admin_page_title;
38 38
 
39
-    protected $_labels;
39
+	protected $_labels;
40 40
 
41 41
 
42
-    // set early within EE_Admin_Init
43
-    protected $_wp_page_slug;
42
+	// set early within EE_Admin_Init
43
+	protected $_wp_page_slug;
44 44
 
45
-    // nav tabs
46
-    protected $_nav_tabs;
45
+	// nav tabs
46
+	protected $_nav_tabs;
47 47
 
48
-    protected $_default_nav_tab_name;
48
+	protected $_default_nav_tab_name;
49 49
 
50
-    /**
51
-     * @var array $_help_tour
52
-     */
53
-    protected $_help_tour = array();
50
+	/**
51
+	 * @var array $_help_tour
52
+	 */
53
+	protected $_help_tour = array();
54 54
 
55 55
 
56
-    // template variables (used by templates)
57
-    protected $_template_path;
56
+	// template variables (used by templates)
57
+	protected $_template_path;
58 58
 
59
-    protected $_column_template_path;
59
+	protected $_column_template_path;
60 60
 
61
-    /**
62
-     * @var array $_template_args
63
-     */
64
-    protected $_template_args = array();
61
+	/**
62
+	 * @var array $_template_args
63
+	 */
64
+	protected $_template_args = array();
65 65
 
66
-    /**
67
-     * this will hold the list table object for a given view.
68
-     *
69
-     * @var EE_Admin_List_Table $_list_table_object
70
-     */
71
-    protected $_list_table_object;
66
+	/**
67
+	 * this will hold the list table object for a given view.
68
+	 *
69
+	 * @var EE_Admin_List_Table $_list_table_object
70
+	 */
71
+	protected $_list_table_object;
72 72
 
73
-    // boolean
74
-    protected $_is_UI_request; // this starts at null so we can have no header routes progress through two states.
73
+	// boolean
74
+	protected $_is_UI_request; // this starts at null so we can have no header routes progress through two states.
75 75
 
76
-    protected $_routing;
76
+	protected $_routing;
77 77
 
78
-    // list table args
79
-    protected $_view;
78
+	// list table args
79
+	protected $_view;
80 80
 
81
-    protected $_views;
81
+	protected $_views;
82 82
 
83 83
 
84
-    // action => method pairs used for routing incoming requests
85
-    protected $_page_routes;
84
+	// action => method pairs used for routing incoming requests
85
+	protected $_page_routes;
86 86
 
87
-    /**
88
-     * @var array $_page_config
89
-     */
90
-    protected $_page_config;
87
+	/**
88
+	 * @var array $_page_config
89
+	 */
90
+	protected $_page_config;
91 91
 
92
-    /**
93
-     * the current page route and route config
94
-     *
95
-     * @var string $_route
96
-     */
97
-    protected $_route;
92
+	/**
93
+	 * the current page route and route config
94
+	 *
95
+	 * @var string $_route
96
+	 */
97
+	protected $_route;
98 98
 
99
-    /**
100
-     * @var string $_cpt_route
101
-     */
102
-    protected $_cpt_route;
99
+	/**
100
+	 * @var string $_cpt_route
101
+	 */
102
+	protected $_cpt_route;
103 103
 
104
-    /**
105
-     * @var array $_route_config
106
-     */
107
-    protected $_route_config;
104
+	/**
105
+	 * @var array $_route_config
106
+	 */
107
+	protected $_route_config;
108 108
 
109
-    /**
110
-     * Used to hold default query args for list table routes to help preserve stickiness of filters for carried out
111
-     * actions.
112
-     *
113
-     * @since 4.6.x
114
-     * @var array.
115
-     */
116
-    protected $_default_route_query_args;
117
-
118
-    // set via request page and action args.
119
-    protected $_current_page;
120
-
121
-    protected $_current_view;
122
-
123
-    protected $_current_page_view_url;
124
-
125
-    // sanitized request action (and nonce)
126
-
127
-    /**
128
-     * @var string $_req_action
129
-     */
130
-    protected $_req_action;
131
-
132
-    /**
133
-     * @var string $_req_nonce
134
-     */
135
-    protected $_req_nonce;
136
-
137
-    // search related
138
-    protected $_search_btn_label;
139
-
140
-    protected $_search_box_callback;
141
-
142
-    /**
143
-     * WP Current Screen object
144
-     *
145
-     * @var WP_Screen
146
-     */
147
-    protected $_current_screen;
148
-
149
-    // for holding EE_Admin_Hooks object when needed (set via set_hook_object())
150
-    protected $_hook_obj;
151
-
152
-    // for holding incoming request data
153
-    protected $_req_data;
154
-
155
-    // yes / no array for admin form fields
156
-    protected $_yes_no_values = array();
157
-
158
-    // some default things shared by all child classes
159
-    protected $_default_espresso_metaboxes;
160
-
161
-    /**
162
-     *    EE_Registry Object
163
-     *
164
-     * @var    EE_Registry
165
-     */
166
-    protected $EE;
167
-
168
-
169
-    /**
170
-     * This is just a property that flags whether the given route is a caffeinated route or not.
171
-     *
172
-     * @var boolean
173
-     */
174
-    protected $_is_caf = false;
175
-
176
-
177
-    /**
178
-     * @Constructor
179
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
180
-     * @throws InvalidArgumentException
181
-     * @throws InvalidDataTypeException
182
-     * @throws InvalidInterfaceException
183
-     * @throws ReflectionException
184
-     */
185
-    public function __construct($routing = true)
186
-    {
187
-        $this->loader = LoaderFactory::getLoader();
188
-        if (strpos($this->_get_dir(), 'caffeinated') !== false) {
189
-            $this->_is_caf = true;
190
-        }
191
-        $this->_yes_no_values = array(
192
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
193
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
194
-        );
195
-        // set the _req_data property.
196
-        $this->_req_data = array_merge($_GET, $_POST);
197
-        // routing enabled?
198
-        $this->_routing = $routing;
199
-    }
200
-
201
-
202
-    /**
203
-     * This logic used to be in the constructor, but that caused a chicken <--> egg scenario
204
-     * for child classes that needed to set properties prior to these methods getting called,
205
-     * but also needed the parent class to have its construction completed as well.
206
-     * Bottom line is that constructors should ONLY be used for setting initial properties
207
-     * and any complex initialization logic should only run after instantiation is complete.
208
-     *
209
-     * This method gets called immediately after construction from within
210
-     *      EE_Admin_Page_Init::_initialize_admin_page()
211
-     *
212
-     * @throws EE_Error
213
-     * @throws InvalidArgumentException
214
-     * @throws InvalidDataTypeException
215
-     * @throws InvalidInterfaceException
216
-     * @throws ReflectionException
217
-     * @since $VID:$
218
-     */
219
-    public function initializePage()
220
-    {
221
-        // set initial page props (child method)
222
-        $this->_init_page_props();
223
-        // set global defaults
224
-        $this->_set_defaults();
225
-        // set early because incoming requests could be ajax related and we need to register those hooks.
226
-        $this->_global_ajax_hooks();
227
-        $this->_ajax_hooks();
228
-        // other_page_hooks have to be early too.
229
-        $this->_do_other_page_hooks();
230
-        // This just allows us to have extending classes do something specific
231
-        // before the parent constructor runs _page_setup().
232
-        if (method_exists($this, '_before_page_setup')) {
233
-            $this->_before_page_setup();
234
-        }
235
-        // set up page dependencies
236
-        $this->_page_setup();
237
-    }
238
-
239
-
240
-    /**
241
-     * _init_page_props
242
-     * Child classes use to set at least the following properties:
243
-     * $page_slug.
244
-     * $page_label.
245
-     *
246
-     * @abstract
247
-     * @return void
248
-     */
249
-    abstract protected function _init_page_props();
250
-
251
-
252
-    /**
253
-     * _ajax_hooks
254
-     * child classes put all their add_action('wp_ajax_{name_of_hook}') hooks in here.
255
-     * Note: within the ajax callback methods.
256
-     *
257
-     * @abstract
258
-     * @return void
259
-     */
260
-    abstract protected function _ajax_hooks();
261
-
262
-
263
-    /**
264
-     * _define_page_props
265
-     * child classes define page properties in here.  Must include at least:
266
-     * $_admin_base_url = base_url for all admin pages
267
-     * $_admin_page_title = default admin_page_title for admin pages
268
-     * $_labels = array of default labels for various automatically generated elements:
269
-     *    array(
270
-     *        'buttons' => array(
271
-     *            'add' => esc_html__('label for add new button'),
272
-     *            'edit' => esc_html__('label for edit button'),
273
-     *            'delete' => esc_html__('label for delete button')
274
-     *            )
275
-     *        )
276
-     *
277
-     * @abstract
278
-     * @return void
279
-     */
280
-    abstract protected function _define_page_props();
281
-
282
-
283
-    /**
284
-     * _set_page_routes
285
-     * child classes use this to define the page routes for all subpages handled by the class.  Page routes are
286
-     * assigned to a action => method pairs in an array and to the $_page_routes property.  Each page route must also
287
-     * have a 'default' route. Here's the format
288
-     * $this->_page_routes = array(
289
-     *        'default' => array(
290
-     *            'func' => '_default_method_handling_route',
291
-     *            'args' => array('array','of','args'),
292
-     *            'noheader' => true, //add this in if this page route is processed before any headers are loaded (i.e.
293
-     *            ajax request, backend processing)
294
-     *            'headers_sent_route'=>'headers_route_reference', //add this if noheader=>true, and you want to load a
295
-     *            headers route after.  The string you enter here should match the defined route reference for a
296
-     *            headers sent route.
297
-     *            'capability' => 'route_capability', //indicate a string for minimum capability required to access
298
-     *            this route.
299
-     *            'obj_id' => 10 // if this route has an object id, then this can include it (used for capability
300
-     *            checks).
301
-     *        ),
302
-     *        'insert_item' => '_method_for_handling_insert_item' //this can be used if all we need to have is a
303
-     *        handling method.
304
-     *        )
305
-     * )
306
-     *
307
-     * @abstract
308
-     * @return void
309
-     */
310
-    abstract protected function _set_page_routes();
311
-
312
-
313
-    /**
314
-     * _set_page_config
315
-     * child classes use this to define the _page_config array for all subpages handled by the class. Each key in the
316
-     * array corresponds to the page_route for the loaded page. Format:
317
-     * $this->_page_config = array(
318
-     *        'default' => array(
319
-     *            'labels' => array(
320
-     *                'buttons' => array(
321
-     *                    'add' => esc_html__('label for adding item'),
322
-     *                    'edit' => esc_html__('label for editing item'),
323
-     *                    'delete' => esc_html__('label for deleting item')
324
-     *                ),
325
-     *                'publishbox' => esc_html__('Localized Title for Publish metabox', 'event_espresso')
326
-     *            ), //optional an array of custom labels for various automatically generated elements to use on the
327
-     *            page. If this isn't present then the defaults will be used as set for the $this->_labels in
328
-     *            _define_page_props() method
329
-     *            'nav' => array(
330
-     *                'label' => esc_html__('Label for Tab', 'event_espresso').
331
-     *                'url' => 'http://someurl', //automatically generated UNLESS you define
332
-     *                'css_class' => 'css-class', //automatically generated UNLESS you define
333
-     *                'order' => 10, //required to indicate tab position.
334
-     *                'persistent' => false //if you want the nav tab to ONLY display when the specific route is
335
-     *                displayed then add this parameter.
336
-     *            'list_table' => 'name_of_list_table' //string for list table class to be loaded for this admin_page.
337
-     *            'metaboxes' => array('metabox1', 'metabox2'), //if present this key indicates we want to load
338
-     *            metaboxes set for eventespresso admin pages.
339
-     *            'has_metaboxes' => true, //this boolean flag can simply be used to indicate if the route will have
340
-     *            metaboxes.  Typically this is used if the 'metaboxes' index is not used because metaboxes are added
341
-     *            later.  We just use this flag to make sure the necessary js gets enqueued on page load.
342
-     *            'has_help_popups' => false //defaults(true) //this boolean flag can simply be used to indicate if the
343
-     *            given route has help popups setup and if it does then we need to make sure thickbox is enqueued.
344
-     *            'columns' => array(4, 2), //this key triggers the setup of a page that uses columns (metaboxes).  The
345
-     *            array indicates the max number of columns (4) and the default number of columns on page load (2).
346
-     *            There is an option in the "screen_options" dropdown that is setup so users can pick what columns they
347
-     *            want to display.
348
-     *            'help_tabs' => array( //this is used for adding help tabs to a page
349
-     *                'tab_id' => array(
350
-     *                    'title' => 'tab_title',
351
-     *                    'filename' => 'name_of_file_containing_content', //this is the primary method for setting
352
-     *                    help tab content.  The fallback if it isn't present is to try a the callback.  Filename
353
-     *                    should match a file in the admin folder's "help_tabs" dir (ie..
354
-     *                    events/help_tabs/name_of_file_containing_content.help_tab.php)
355
-     *                    'callback' => 'callback_method_for_content', //if 'filename' isn't present then system will
356
-     *                    attempt to use the callback which should match the name of a method in the class
357
-     *                    ),
358
-     *                'tab2_id' => array(
359
-     *                    'title' => 'tab2 title',
360
-     *                    'filename' => 'file_name_2'
361
-     *                    'callback' => 'callback_method_for_content',
362
-     *                 ),
363
-     *            'help_sidebar' => 'callback_for_sidebar_content', //this is used for setting up the sidebar in the
364
-     *            help tab area on an admin page. @link
365
-     *            http://make.wordpress.org/core/2011/12/06/help-and-screen-api-changes-in-3-3/
366
-     *            'help_tour' => array(
367
-     *                'name_of_help_tour_class', //all help tours shoudl be a child class of EE_Help_Tour and located
368
-     *                in a folder for this admin page named "help_tours", a file name matching the key given here
369
-     *                (name_of_help_tour_class.class.php), and class matching key given here (name_of_help_tour_class)
370
-     *            ),
371
-     *            'require_nonce' => TRUE //this is used if you want to set a route to NOT require a nonce (default is
372
-     *            true if it isn't present).  To remove the requirement for a nonce check when this route is visited
373
-     *            just set
374
-     *            'require_nonce' to FALSE
375
-     *            )
376
-     * )
377
-     *
378
-     * @abstract
379
-     * @return void
380
-     */
381
-    abstract protected function _set_page_config();
382
-
383
-
384
-
385
-
386
-
387
-    /** end sample help_tour methods **/
388
-    /**
389
-     * _add_screen_options
390
-     * Child classes can add any extra wp_screen_options within this method using built-in WP functions/methods for
391
-     * doing so. Note child classes can also define _add_screen_options_($this->_current_view) to limit screen options
392
-     * to a particular view.
393
-     *
394
-     * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
395
-     *         see also WP_Screen object documents...
396
-     * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
397
-     * @abstract
398
-     * @return void
399
-     */
400
-    abstract protected function _add_screen_options();
401
-
402
-
403
-    /**
404
-     * _add_feature_pointers
405
-     * Child classes should use this method for implementing any "feature pointers" (using built-in WP styling js).
406
-     * Note child classes can also define _add_feature_pointers_($this->_current_view) to limit screen options to a
407
-     * particular view. Note: this is just a placeholder for now.  Implementation will come down the road See:
408
-     * WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
409
-     * extended) also see:
410
-     *
411
-     * @link   http://eamann.com/tech/wordpress-portland/
412
-     * @abstract
413
-     * @return void
414
-     */
415
-    abstract protected function _add_feature_pointers();
416
-
417
-
418
-    /**
419
-     * load_scripts_styles
420
-     * child classes put their wp_enqueue_script and wp_enqueue_style hooks in here for anything they need loaded for
421
-     * their pages/subpages.  Note this is for all pages/subpages of the system.  You can also load only specific
422
-     * scripts/styles per view by putting them in a dynamic function in this format
423
-     * (load_scripts_styles_{$this->_current_view}) which matches your page route (action request arg)
424
-     *
425
-     * @abstract
426
-     * @return void
427
-     */
428
-    abstract public function load_scripts_styles();
429
-
430
-
431
-    /**
432
-     * admin_init
433
-     * Anything that should be set/executed at 'admin_init' WP hook runtime should be put in here.  This will apply to
434
-     * all pages/views loaded by child class.
435
-     *
436
-     * @abstract
437
-     * @return void
438
-     */
439
-    abstract public function admin_init();
440
-
441
-
442
-    /**
443
-     * admin_notices
444
-     * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply to
445
-     * all pages/views loaded by child class.
446
-     *
447
-     * @abstract
448
-     * @return void
449
-     */
450
-    abstract public function admin_notices();
451
-
452
-
453
-    /**
454
-     * admin_footer_scripts
455
-     * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
456
-     * will apply to all pages/views loaded by child class.
457
-     *
458
-     * @return void
459
-     */
460
-    abstract public function admin_footer_scripts();
461
-
462
-
463
-    /**
464
-     * admin_footer
465
-     * anything triggered by the 'admin_footer' WP action hook should be added to here. This particular method will
466
-     * apply to all pages/views loaded by child class.
467
-     *
468
-     * @return void
469
-     */
470
-    public function admin_footer()
471
-    {
472
-    }
473
-
474
-
475
-    /**
476
-     * _global_ajax_hooks
477
-     * all global add_action('wp_ajax_{name_of_hook}') hooks in here.
478
-     * Note: within the ajax callback methods.
479
-     *
480
-     * @abstract
481
-     * @return void
482
-     */
483
-    protected function _global_ajax_hooks()
484
-    {
485
-        // for lazy loading of metabox content
486
-        add_action('wp_ajax_espresso-ajax-content', array($this, 'ajax_metabox_content'), 10);
487
-    }
488
-
489
-
490
-    public function ajax_metabox_content()
491
-    {
492
-        $contentid = isset($this->_req_data['contentid']) ? $this->_req_data['contentid'] : '';
493
-        $url = isset($this->_req_data['contenturl']) ? $this->_req_data['contenturl'] : '';
494
-        EE_Admin_Page::cached_rss_display($contentid, $url);
495
-        wp_die();
496
-    }
497
-
498
-
499
-    /**
500
-     * _page_setup
501
-     * Makes sure any things that need to be loaded early get handled.  We also escape early here if the page requested
502
-     * doesn't match the object.
503
-     *
504
-     * @final
505
-     * @return void
506
-     * @throws EE_Error
507
-     * @throws InvalidArgumentException
508
-     * @throws ReflectionException
509
-     * @throws InvalidDataTypeException
510
-     * @throws InvalidInterfaceException
511
-     */
512
-    final protected function _page_setup()
513
-    {
514
-        // requires?
515
-        // admin_init stuff - global - we're setting this REALLY early
516
-        // so if EE_Admin pages have to hook into other WP pages they can.
517
-        // But keep in mind, not everything is available from the EE_Admin Page object at this point.
518
-        add_action('admin_init', array($this, 'admin_init_global'), 5);
519
-        // next verify if we need to load anything...
520
-        $this->_current_page = ! empty($_GET['page']) ? sanitize_key($_GET['page']) : '';
521
-        $this->page_folder = strtolower(
522
-            str_replace(array('_Admin_Page', 'Extend_'), '', get_class($this))
523
-        );
524
-        global $ee_menu_slugs;
525
-        $ee_menu_slugs = (array) $ee_menu_slugs;
526
-        if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[ $this->_current_page ]))) {
527
-            return;
528
-        }
529
-        // becuz WP List tables have two duplicate select inputs for choosing bulk actions, we need to copy the action from the second to the first
530
-        if (isset($this->_req_data['action2']) && $this->_req_data['action'] === '-1') {
531
-            $this->_req_data['action'] = ! empty($this->_req_data['action2']) && $this->_req_data['action2'] !== '-1'
532
-                ? $this->_req_data['action2']
533
-                : $this->_req_data['action'];
534
-        }
535
-        // then set blank or -1 action values to 'default'
536
-        $this->_req_action = isset($this->_req_data['action'])
537
-                             && ! empty($this->_req_data['action'])
538
-                             && $this->_req_data['action'] !== '-1'
539
-            ? sanitize_key($this->_req_data['action'])
540
-            : 'default';
541
-        // if action is 'default' after the above BUT we have  'route' var set, then let's use the route as the action.
542
-        //  This covers cases where we're coming in from a list table that isn't on the default route.
543
-        $this->_req_action = $this->_req_action === 'default' && isset($this->_req_data['route'])
544
-            ? $this->_req_data['route'] : $this->_req_action;
545
-        // however if we are doing_ajax and we've got a 'route' set then that's what the req_action will be
546
-        $this->_req_action = defined('DOING_AJAX') && isset($this->_req_data['route'])
547
-            ? $this->_req_data['route']
548
-            : $this->_req_action;
549
-        $this->_current_view = $this->_req_action;
550
-        $this->_req_nonce = $this->_req_action . '_nonce';
551
-        $this->_define_page_props();
552
-        $this->_current_page_view_url = add_query_arg(
553
-            array('page' => $this->_current_page, 'action' => $this->_current_view),
554
-            $this->_admin_base_url
555
-        );
556
-        // default things
557
-        $this->_default_espresso_metaboxes = array(
558
-            '_espresso_news_post_box',
559
-            '_espresso_links_post_box',
560
-            '_espresso_ratings_request',
561
-            '_espresso_sponsors_post_box',
562
-        );
563
-        // set page configs
564
-        $this->_set_page_routes();
565
-        $this->_set_page_config();
566
-        // let's include any referrer data in our default_query_args for this route for "stickiness".
567
-        if (isset($this->_req_data['wp_referer'])) {
568
-            $this->_default_route_query_args['wp_referer'] = $this->_req_data['wp_referer'];
569
-        }
570
-        // for caffeinated and other extended functionality.
571
-        //  If there is a _extend_page_config method
572
-        // then let's run that to modify the all the various page configuration arrays
573
-        if (method_exists($this, '_extend_page_config')) {
574
-            $this->_extend_page_config();
575
-        }
576
-        // for CPT and other extended functionality.
577
-        // If there is an _extend_page_config_for_cpt
578
-        // then let's run that to modify all the various page configuration arrays.
579
-        if (method_exists($this, '_extend_page_config_for_cpt')) {
580
-            $this->_extend_page_config_for_cpt();
581
-        }
582
-        // filter routes and page_config so addons can add their stuff. Filtering done per class
583
-        $this->_page_routes = apply_filters(
584
-            'FHEE__' . get_class($this) . '__page_setup__page_routes',
585
-            $this->_page_routes,
586
-            $this
587
-        );
588
-        $this->_page_config = apply_filters(
589
-            'FHEE__' . get_class($this) . '__page_setup__page_config',
590
-            $this->_page_config,
591
-            $this
592
-        );
593
-        // if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present
594
-        // then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action
595
-        if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)) {
596
-            add_action(
597
-                'AHEE__EE_Admin_Page__route_admin_request',
598
-                array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view),
599
-                10,
600
-                2
601
-            );
602
-        }
603
-        // next route only if routing enabled
604
-        if ($this->_routing && ! defined('DOING_AJAX')) {
605
-            $this->_verify_routes();
606
-            // next let's just check user_access and kill if no access
607
-            $this->check_user_access();
608
-            if ($this->_is_UI_request) {
609
-                // admin_init stuff - global, all views for this page class, specific view
610
-                add_action('admin_init', array($this, 'admin_init'), 10);
611
-                if (method_exists($this, 'admin_init_' . $this->_current_view)) {
612
-                    add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15);
613
-                }
614
-            } else {
615
-                // hijack regular WP loading and route admin request immediately
616
-                @ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
617
-                $this->route_admin_request();
618
-            }
619
-        }
620
-    }
621
-
622
-
623
-    /**
624
-     * Provides a way for related child admin pages to load stuff on the loaded admin page.
625
-     *
626
-     * @return void
627
-     * @throws EE_Error
628
-     */
629
-    private function _do_other_page_hooks()
630
-    {
631
-        $registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array());
632
-        foreach ($registered_pages as $page) {
633
-            // now let's setup the file name and class that should be present
634
-            $classname = str_replace('.class.php', '', $page);
635
-            // autoloaders should take care of loading file
636
-            if (! class_exists($classname)) {
637
-                $error_msg[] = sprintf(
638
-                    esc_html__(
639
-                        'Something went wrong with loading the %s admin hooks page.',
640
-                        'event_espresso'
641
-                    ),
642
-                    $page
643
-                );
644
-                $error_msg[] = $error_msg[0]
645
-                               . "\r\n"
646
-                               . sprintf(
647
-                                   esc_html__(
648
-                                       'There is no class in place for the %1$s admin hooks page.%2$sMake sure you have %3$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
649
-                                       'event_espresso'
650
-                                   ),
651
-                                   $page,
652
-                                   '<br />',
653
-                                   '<strong>' . $classname . '</strong>'
654
-                               );
655
-                throw new EE_Error(implode('||', $error_msg));
656
-            }
657
-            // // notice we are passing the instance of this class to the hook object.
658
-            $this->loader->getShared($classname, [$this]);
659
-        }
660
-    }
661
-
662
-
663
-    /**
664
-     * @throws DomainException
665
-     * @throws EE_Error
666
-     * @throws InvalidArgumentException
667
-     * @throws InvalidDataTypeException
668
-     * @throws InvalidInterfaceException
669
-     * @throws ReflectionException
670
-     * @since $VID:$
671
-     */
672
-    public function load_page_dependencies()
673
-    {
674
-        try {
675
-            $this->_load_page_dependencies();
676
-        } catch (EE_Error $e) {
677
-            $e->get_error();
678
-        }
679
-    }
680
-
681
-
682
-    /**
683
-     * load_page_dependencies
684
-     * loads things specific to this page class when its loaded.  Really helps with efficiency.
685
-     *
686
-     * @return void
687
-     * @throws DomainException
688
-     * @throws EE_Error
689
-     * @throws InvalidArgumentException
690
-     * @throws InvalidDataTypeException
691
-     * @throws InvalidInterfaceException
692
-     * @throws ReflectionException
693
-     */
694
-    protected function _load_page_dependencies()
695
-    {
696
-        // let's set the current_screen and screen options to override what WP set
697
-        $this->_current_screen = get_current_screen();
698
-        // load admin_notices - global, page class, and view specific
699
-        add_action('admin_notices', array($this, 'admin_notices_global'), 5);
700
-        add_action('admin_notices', array($this, 'admin_notices'), 10);
701
-        if (method_exists($this, 'admin_notices_' . $this->_current_view)) {
702
-            add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15);
703
-        }
704
-        // load network admin_notices - global, page class, and view specific
705
-        add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5);
706
-        if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) {
707
-            add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view));
708
-        }
709
-        // this will save any per_page screen options if they are present
710
-        $this->_set_per_page_screen_options();
711
-        // setup list table properties
712
-        $this->_set_list_table();
713
-        // child classes can "register" a metabox to be automatically handled via the _page_config array property.
714
-        // However in some cases the metaboxes will need to be added within a route handling callback.
715
-        $this->_add_registered_meta_boxes();
716
-        $this->_add_screen_columns();
717
-        // add screen options - global, page child class, and view specific
718
-        $this->_add_global_screen_options();
719
-        $this->_add_screen_options();
720
-        $add_screen_options = "_add_screen_options_{$this->_current_view}";
721
-        if (method_exists($this, $add_screen_options)) {
722
-            $this->{$add_screen_options}();
723
-        }
724
-        // add help tab(s) and tours- set via page_config and qtips.
725
-        $this->_add_help_tour();
726
-        $this->_add_help_tabs();
727
-        $this->_add_qtips();
728
-        // add feature_pointers - global, page child class, and view specific
729
-        $this->_add_feature_pointers();
730
-        $this->_add_global_feature_pointers();
731
-        $add_feature_pointer = "_add_feature_pointer_{$this->_current_view}";
732
-        if (method_exists($this, $add_feature_pointer)) {
733
-            $this->{$add_feature_pointer}();
734
-        }
735
-        // enqueue scripts/styles - global, page class, and view specific
736
-        add_action('admin_enqueue_scripts', array($this, 'load_global_scripts_styles'), 5);
737
-        add_action('admin_enqueue_scripts', array($this, 'load_scripts_styles'), 10);
738
-        if (method_exists($this, "load_scripts_styles_{$this->_current_view}")) {
739
-            add_action('admin_enqueue_scripts', array($this, "load_scripts_styles_{$this->_current_view}"), 15);
740
-        }
741
-        add_action('admin_enqueue_scripts', array($this, 'admin_footer_scripts_eei18n_js_strings'), 100);
742
-        // admin_print_footer_scripts - global, page child class, and view specific.
743
-        // NOTE, despite the name, whenever possible, scripts should NOT be loaded using this.
744
-        // In most cases that's doing_it_wrong().  But adding hidden container elements etc.
745
-        // is a good use case. Notice the late priority we're giving these
746
-        add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts_global'), 99);
747
-        add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts'), 100);
748
-        if (method_exists($this, "admin_footer_scripts_{$this->_current_view}")) {
749
-            add_action('admin_print_footer_scripts', array($this, "admin_footer_scripts_{$this->_current_view}"), 101);
750
-        }
751
-        // admin footer scripts
752
-        add_action('admin_footer', array($this, 'admin_footer_global'), 99);
753
-        add_action('admin_footer', array($this, 'admin_footer'), 100);
754
-        if (method_exists($this, "admin_footer_{$this->_current_view}")) {
755
-            add_action('admin_footer', array($this, "admin_footer_{$this->_current_view}"), 101);
756
-        }
757
-        do_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', $this->page_slug);
758
-        // targeted hook
759
-        do_action(
760
-            "FHEE__EE_Admin_Page___load_page_dependencies__after_load__{$this->page_slug}__{$this->_req_action}"
761
-        );
762
-    }
763
-
764
-
765
-    /**
766
-     * _set_defaults
767
-     * This sets some global defaults for class properties.
768
-     */
769
-    private function _set_defaults()
770
-    {
771
-        $this->_current_screen = $this->_admin_page_title = $this->_req_action = $this->_req_nonce = null;
772
-        $this->_event = $this->_template_path = $this->_column_template_path = null;
773
-        $this->_nav_tabs = $this->_views = $this->_page_routes = array();
774
-        $this->_page_config = $this->_default_route_query_args = array();
775
-        $this->_default_nav_tab_name = 'overview';
776
-        // init template args
777
-        $this->_template_args = array(
778
-            'admin_page_header'  => '',
779
-            'admin_page_content' => '',
780
-            'post_body_content'  => '',
781
-            'before_list_table'  => '',
782
-            'after_list_table'   => '',
783
-        );
784
-    }
785
-
786
-
787
-    /**
788
-     * route_admin_request
789
-     *
790
-     * @see    _route_admin_request()
791
-     * @return exception|void error
792
-     * @throws InvalidArgumentException
793
-     * @throws InvalidInterfaceException
794
-     * @throws InvalidDataTypeException
795
-     * @throws EE_Error
796
-     * @throws ReflectionException
797
-     */
798
-    public function route_admin_request()
799
-    {
800
-        try {
801
-            $this->_route_admin_request();
802
-        } catch (EE_Error $e) {
803
-            $e->get_error();
804
-        }
805
-    }
806
-
807
-
808
-    public function set_wp_page_slug($wp_page_slug)
809
-    {
810
-        $this->_wp_page_slug = $wp_page_slug;
811
-        // if in network admin then we need to append "-network" to the page slug. Why? Because that's how WP rolls...
812
-        if (is_network_admin()) {
813
-            $this->_wp_page_slug .= '-network';
814
-        }
815
-    }
816
-
817
-
818
-    /**
819
-     * _verify_routes
820
-     * All this method does is verify the incoming request and make sure that routes exist for it.  We do this early so
821
-     * we know if we need to drop out.
822
-     *
823
-     * @return bool
824
-     * @throws EE_Error
825
-     */
826
-    protected function _verify_routes()
827
-    {
828
-        if (! $this->_current_page && ! defined('DOING_AJAX')) {
829
-            return false;
830
-        }
831
-        $this->_route = false;
832
-        // check that the page_routes array is not empty
833
-        if (empty($this->_page_routes)) {
834
-            // user error msg
835
-            $error_msg = sprintf(
836
-                esc_html__('No page routes have been set for the %s admin page.', 'event_espresso'),
837
-                $this->_admin_page_title
838
-            );
839
-            // developer error msg
840
-            $error_msg .= '||' . $error_msg
841
-                          . esc_html__(
842
-                              ' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.',
843
-                              'event_espresso'
844
-                          );
845
-            throw new EE_Error($error_msg);
846
-        }
847
-        // and that the requested page route exists
848
-        if (array_key_exists($this->_req_action, $this->_page_routes)) {
849
-            $this->_route = $this->_page_routes[ $this->_req_action ];
850
-            $this->_route_config = isset($this->_page_config[ $this->_req_action ])
851
-                ? $this->_page_config[ $this->_req_action ] : array();
852
-        } else {
853
-            // user error msg
854
-            $error_msg = sprintf(
855
-                esc_html__(
856
-                    'The requested page route does not exist for the %s admin page.',
857
-                    'event_espresso'
858
-                ),
859
-                $this->_admin_page_title
860
-            );
861
-            // developer error msg
862
-            $error_msg .= '||' . $error_msg
863
-                          . sprintf(
864
-                              esc_html__(
865
-                                  ' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.',
866
-                                  'event_espresso'
867
-                              ),
868
-                              $this->_req_action
869
-                          );
870
-            throw new EE_Error($error_msg);
871
-        }
872
-        // and that a default route exists
873
-        if (! array_key_exists('default', $this->_page_routes)) {
874
-            // user error msg
875
-            $error_msg = sprintf(
876
-                esc_html__(
877
-                    'A default page route has not been set for the % admin page.',
878
-                    'event_espresso'
879
-                ),
880
-                $this->_admin_page_title
881
-            );
882
-            // developer error msg
883
-            $error_msg .= '||' . $error_msg
884
-                          . esc_html__(
885
-                              ' Create a key in the "_page_routes" array named "default" and set its value to your default page method.',
886
-                              'event_espresso'
887
-                          );
888
-            throw new EE_Error($error_msg);
889
-        }
890
-
891
-        // first lets' catch if the UI request has EVER been set.
892
-        if ($this->_is_UI_request === null) {
893
-            // lets set if this is a UI request or not.
894
-            $this->_is_UI_request = ! isset($this->_req_data['noheader']) || $this->_req_data['noheader'] !== true;
895
-            // wait a minute... we might have a noheader in the route array
896
-            $this->_is_UI_request = is_array($this->_route)
897
-                                    && isset($this->_route['noheader'])
898
-                                    && $this->_route['noheader'] ? false : $this->_is_UI_request;
899
-        }
900
-        $this->_set_current_labels();
901
-        return true;
902
-    }
903
-
904
-
905
-    /**
906
-     * this method simply verifies a given route and makes sure its an actual route available for the loaded page
907
-     *
908
-     * @param  string $route the route name we're verifying
909
-     * @return mixed (bool|Exception)      we'll throw an exception if this isn't a valid route.
910
-     * @throws EE_Error
911
-     */
912
-    protected function _verify_route($route)
913
-    {
914
-        if (array_key_exists($this->_req_action, $this->_page_routes)) {
915
-            return true;
916
-        }
917
-        // user error msg
918
-        $error_msg = sprintf(
919
-            esc_html__('The given page route does not exist for the %s admin page.', 'event_espresso'),
920
-            $this->_admin_page_title
921
-        );
922
-        // developer error msg
923
-        $error_msg .= '||' . $error_msg
924
-                      . sprintf(
925
-                          esc_html__(
926
-                              ' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property',
927
-                              'event_espresso'
928
-                          ),
929
-                          $route
930
-                      );
931
-        throw new EE_Error($error_msg);
932
-    }
933
-
934
-
935
-    /**
936
-     * perform nonce verification
937
-     * This method has be encapsulated here so that any ajax requests that bypass normal routes can verify their nonces
938
-     * using this method (and save retyping!)
939
-     *
940
-     * @param string $nonce     The nonce sent
941
-     * @param string $nonce_ref The nonce reference string (name0)
942
-     * @return void
943
-     * @throws EE_Error
944
-     * @throws InvalidArgumentException
945
-     * @throws InvalidDataTypeException
946
-     * @throws InvalidInterfaceException
947
-     */
948
-    protected function _verify_nonce($nonce, $nonce_ref)
949
-    {
950
-        // verify nonce against expected value
951
-        if (! wp_verify_nonce($nonce, $nonce_ref)) {
952
-            // these are not the droids you are looking for !!!
953
-            $msg = sprintf(
954
-                esc_html__('%sNonce Fail.%s', 'event_espresso'),
955
-                '<a href="http://www.youtube.com/watch?v=56_S0WeTkzs">',
956
-                '</a>'
957
-            );
958
-            if (WP_DEBUG) {
959
-                $msg .= "\n  "
960
-                        . sprintf(
961
-                            esc_html__(
962
-                                'In order to dynamically generate nonces for your actions, use the %s::add_query_args_and_nonce() method. May the Nonce be with you!',
963
-                                'event_espresso'
964
-                            ),
965
-                            EE_Admin_Page::class
966
-                        );
967
-            }
968
-            if (! defined('DOING_AJAX')) {
969
-                wp_die($msg);
970
-            } else {
971
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
972
-                $this->_return_json();
973
-            }
974
-        }
975
-    }
976
-
977
-
978
-    /**
979
-     * _route_admin_request()
980
-     * Meat and potatoes of the class.  Basically, this dude checks out what's being requested and sees if there are
981
-     * some doodads to work the magic and handle the flingjangy. Translation:  Checks if the requested action is listed
982
-     * in the page routes and then will try to load the corresponding method.
983
-     *
984
-     * @return void
985
-     * @throws EE_Error
986
-     * @throws InvalidArgumentException
987
-     * @throws InvalidDataTypeException
988
-     * @throws InvalidInterfaceException
989
-     * @throws ReflectionException
990
-     */
991
-    protected function _route_admin_request()
992
-    {
993
-        if (! $this->_is_UI_request) {
994
-            $this->_verify_routes();
995
-        }
996
-        $nonce_check = isset($this->_route_config['require_nonce'])
997
-            ? $this->_route_config['require_nonce']
998
-            : true;
999
-        if ($this->_req_action !== 'default' && $nonce_check) {
1000
-            // set nonce from post data
1001
-            $nonce = isset($this->_req_data[ $this->_req_nonce ])
1002
-                ? sanitize_text_field($this->_req_data[ $this->_req_nonce ])
1003
-                : '';
1004
-            $this->_verify_nonce($nonce, $this->_req_nonce);
1005
-        }
1006
-        // set the nav_tabs array but ONLY if this is  UI_request
1007
-        if ($this->_is_UI_request) {
1008
-            $this->_set_nav_tabs();
1009
-        }
1010
-        // grab callback function
1011
-        $func = is_array($this->_route) && isset($this->_route['func']) ? $this->_route['func'] : $this->_route;
1012
-        // check if callback has args
1013
-        $args = is_array($this->_route) && isset($this->_route['args']) ? $this->_route['args'] : array();
1014
-        $error_msg = '';
1015
-        // action right before calling route
1016
-        // (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request')
1017
-        if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
1018
-            do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this);
1019
-        }
1020
-        // right before calling the route, let's remove _wp_http_referer from the
1021
-        // $_SERVER[REQUEST_URI] global (its now in _req_data for route processing).
1022
-        $_SERVER['REQUEST_URI'] = remove_query_arg(
1023
-            '_wp_http_referer',
1024
-            wp_unslash($_SERVER['REQUEST_URI'])
1025
-        );
1026
-        if (! empty($func)) {
1027
-            if (is_array($func)) {
1028
-                list($class, $method) = $func;
1029
-            } elseif (strpos($func, '::') !== false) {
1030
-                list($class, $method) = explode('::', $func);
1031
-            } else {
1032
-                $class = $this;
1033
-                $method = $func;
1034
-            }
1035
-            if (! (is_object($class) && $class === $this)) {
1036
-                // send along this admin page object for access by addons.
1037
-                $args['admin_page_object'] = $this;
1038
-            }
1039
-            // is it a method on a class that doesn't work?
1040
-            if (((method_exists($class, $method)
1041
-                  && call_user_func_array(array($class, $method), $args) === false)
1042
-                 && (// is it a standalone function that doesn't work?
1043
-                     function_exists($method)
1044
-                     && call_user_func_array(
1045
-                         $func,
1046
-                         array_merge(array('admin_page_object' => $this), $args)
1047
-                     ) === false
1048
-                 )) || (// is it neither a class method NOR a standalone function?
1049
-                    ! function_exists($method)
1050
-                    && ! method_exists($class, $method)
1051
-                )
1052
-            ) {
1053
-                // user error msg
1054
-                $error_msg = esc_html__(
1055
-                    'An error occurred. The  requested page route could not be found.',
1056
-                    'event_espresso'
1057
-                );
1058
-                // developer error msg
1059
-                $error_msg .= '||';
1060
-                $error_msg .= sprintf(
1061
-                    esc_html__(
1062
-                        'Page route "%s" could not be called. Check that the spelling for method names and actions in the "_page_routes" array are all correct.',
1063
-                        'event_espresso'
1064
-                    ),
1065
-                    $method
1066
-                );
1067
-            }
1068
-            if (! empty($error_msg)) {
1069
-                throw new EE_Error($error_msg);
1070
-            }
1071
-        }
1072
-        // if we've routed and this route has a no headers route AND a sent_headers_route,
1073
-        // then we need to reset the routing properties to the new route.
1074
-        // now if UI request is FALSE and noheader is true AND we have a headers_sent_route in the route array then let's set UI_request to true because the no header route has a second func after headers have been sent.
1075
-        if ($this->_is_UI_request === false
1076
-            && is_array($this->_route)
1077
-            && ! empty($this->_route['headers_sent_route'])
1078
-        ) {
1079
-            $this->_reset_routing_properties($this->_route['headers_sent_route']);
1080
-        }
1081
-    }
1082
-
1083
-
1084
-    /**
1085
-     * This method just allows the resetting of page properties in the case where a no headers
1086
-     * route redirects to a headers route in its route config.
1087
-     *
1088
-     * @since   4.3.0
1089
-     * @param  string $new_route New (non header) route to redirect to.
1090
-     * @return   void
1091
-     * @throws ReflectionException
1092
-     * @throws InvalidArgumentException
1093
-     * @throws InvalidInterfaceException
1094
-     * @throws InvalidDataTypeException
1095
-     * @throws EE_Error
1096
-     */
1097
-    protected function _reset_routing_properties($new_route)
1098
-    {
1099
-        $this->_is_UI_request = true;
1100
-        // now we set the current route to whatever the headers_sent_route is set at
1101
-        $this->_req_data['action'] = $new_route;
1102
-        // rerun page setup
1103
-        $this->_page_setup();
1104
-    }
1105
-
1106
-
1107
-    /**
1108
-     * _add_query_arg
1109
-     * adds nonce to array of arguments then calls WP add_query_arg function
1110
-     *(internally just uses EEH_URL's function with the same name)
1111
-     *
1112
-     * @param array  $args
1113
-     * @param string $url
1114
-     * @param bool   $sticky                  if true, then the existing Request params will be appended to the
1115
-     *                                        generated url in an associative array indexed by the key 'wp_referer';
1116
-     *                                        Example usage: If the current page is:
1117
-     *                                        http://mydomain.com/wp-admin/admin.php?page=espresso_registrations
1118
-     *                                        &action=default&event_id=20&month_range=March%202015
1119
-     *                                        &_wpnonce=5467821
1120
-     *                                        and you call:
1121
-     *                                        EE_Admin_Page::add_query_args_and_nonce(
1122
-     *                                        array(
1123
-     *                                        'action' => 'resend_something',
1124
-     *                                        'page=>espresso_registrations'
1125
-     *                                        ),
1126
-     *                                        $some_url,
1127
-     *                                        true
1128
-     *                                        );
1129
-     *                                        It will produce a url in this structure:
1130
-     *                                        http://{$some_url}/?page=espresso_registrations&action=resend_something
1131
-     *                                        &wp_referer[action]=default&wp_referer[event_id]=20&wpreferer[
1132
-     *                                        month_range]=March%202015
1133
-     * @param   bool $exclude_nonce           If true, the the nonce will be excluded from the generated nonce.
1134
-     * @return string
1135
-     */
1136
-    public static function add_query_args_and_nonce(
1137
-        $args = array(),
1138
-        $url = '',
1139
-        $sticky = false,
1140
-        $exclude_nonce = false
1141
-    ) {
1142
-        // if there is a _wp_http_referer include the values from the request but only if sticky = true
1143
-        if ($sticky) {
1144
-            $request = $_REQUEST;
1145
-            unset($request['_wp_http_referer'], $request['wp_referer']);
1146
-            foreach ($request as $key => $value) {
1147
-                // do not add nonces
1148
-                if (strpos($key, 'nonce') !== false) {
1149
-                    continue;
1150
-                }
1151
-                $args[ 'wp_referer[' . $key . ']' ] = $value;
1152
-            }
1153
-        }
1154
-        return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce);
1155
-    }
1156
-
1157
-
1158
-    /**
1159
-     * This returns a generated link that will load the related help tab.
1160
-     *
1161
-     * @param  string $help_tab_id the id for the connected help tab
1162
-     * @param  string $icon_style  (optional) include css class for the style you want to use for the help icon.
1163
-     * @param  string $help_text   (optional) send help text you want to use for the link if default not to be used
1164
-     * @uses EEH_Template::get_help_tab_link()
1165
-     * @return string              generated link
1166
-     */
1167
-    protected function _get_help_tab_link($help_tab_id, $icon_style = '', $help_text = '')
1168
-    {
1169
-        return EEH_Template::get_help_tab_link(
1170
-            $help_tab_id,
1171
-            $this->page_slug,
1172
-            $this->_req_action,
1173
-            $icon_style,
1174
-            $help_text
1175
-        );
1176
-    }
1177
-
1178
-
1179
-    /**
1180
-     * _add_help_tabs
1181
-     * Note child classes define their help tabs within the page_config array.
1182
-     *
1183
-     * @link   http://codex.wordpress.org/Function_Reference/add_help_tab
1184
-     * @return void
1185
-     * @throws DomainException
1186
-     * @throws EE_Error
1187
-     * @throws ReflectionException
1188
-     */
1189
-    protected function _add_help_tabs()
1190
-    {
1191
-        $tour_buttons = '';
1192
-        if (isset($this->_page_config[ $this->_req_action ])) {
1193
-            $config = $this->_page_config[ $this->_req_action ];
1194
-            // is there a help tour for the current route?  if there is let's setup the tour buttons
1195
-            if (isset($this->_help_tour[ $this->_req_action ])) {
1196
-                $tb = array();
1197
-                $tour_buttons = '<div class="ee-abs-container"><div class="ee-help-tour-restart-buttons">';
1198
-                foreach ($this->_help_tour['tours'] as $tour) {
1199
-                    // if this is the end tour then we don't need to setup a button
1200
-                    if ($tour instanceof EE_Help_Tour_final_stop || ! $tour instanceof EE_Help_Tour) {
1201
-                        continue;
1202
-                    }
1203
-                    $tb[] = '<button id="trigger-tour-'
1204
-                            . $tour->get_slug()
1205
-                            . '" class="button-primary trigger-ee-help-tour">'
1206
-                            . $tour->get_label()
1207
-                            . '</button>';
1208
-                }
1209
-                $tour_buttons .= implode('<br />', $tb);
1210
-                $tour_buttons .= '</div></div>';
1211
-            }
1212
-            // let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well.
1213
-            if (is_array($config) && isset($config['help_sidebar'])) {
1214
-                // check that the callback given is valid
1215
-                if (! method_exists($this, $config['help_sidebar'])) {
1216
-                    throw new EE_Error(
1217
-                        sprintf(
1218
-                            esc_html__(
1219
-                                'The _page_config array has a callback set for the "help_sidebar" option.  However the callback given (%s) is not a valid callback.  Doublecheck the spelling and make sure this method exists for the class %s',
1220
-                                'event_espresso'
1221
-                            ),
1222
-                            $config['help_sidebar'],
1223
-                            get_class($this)
1224
-                        )
1225
-                    );
1226
-                }
1227
-                $content = apply_filters(
1228
-                    'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar',
1229
-                    $this->{$config['help_sidebar']}()
1230
-                );
1231
-                $content .= $tour_buttons; // add help tour buttons.
1232
-                // do we have any help tours setup?  Cause if we do we want to add the buttons
1233
-                $this->_current_screen->set_help_sidebar($content);
1234
-            }
1235
-            // if there ARE tour buttons...
1236
-            if (! empty($tour_buttons)) {
1237
-                // if we DON'T have config help sidebar then we'll just add the tour buttons to the sidebar.
1238
-                if (! isset($config['help_sidebar'])) {
1239
-                    $this->_current_screen->set_help_sidebar($tour_buttons);
1240
-                }
1241
-                // handle if no help_tabs are set so the sidebar will still show for the help tour buttons
1242
-                if (! isset($config['help_tabs'])) {
1243
-                    $_ht['id'] = $this->page_slug;
1244
-                    $_ht['title'] = esc_html__('Help Tours', 'event_espresso');
1245
-                    $_ht['content'] = '<p>'
1246
-                                      . esc_html__(
1247
-                                          'The buttons to the right allow you to start/restart any help tours available for this page',
1248
-                                          'event_espresso'
1249
-                                      ) . '</p>';
1250
-                    $this->_current_screen->add_help_tab($_ht);
1251
-                }
1252
-            }
1253
-            if (! isset($config['help_tabs'])) {
1254
-                return;
1255
-            } //no help tabs for this route
1256
-            foreach ((array) $config['help_tabs'] as $tab_id => $cfg) {
1257
-                // we're here so there ARE help tabs!
1258
-                // make sure we've got what we need
1259
-                if (! isset($cfg['title'])) {
1260
-                    throw new EE_Error(
1261
-                        esc_html__(
1262
-                            'The _page_config array is not set up properly for help tabs.  It is missing a title',
1263
-                            'event_espresso'
1264
-                        )
1265
-                    );
1266
-                }
1267
-                if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1268
-                    throw new EE_Error(
1269
-                        esc_html__(
1270
-                            'The _page_config array is not setup properly for help tabs. It is missing a either a filename reference, or a callback reference or a content reference so there is no way to know the content for the help tab',
1271
-                            'event_espresso'
1272
-                        )
1273
-                    );
1274
-                }
1275
-                // first priority goes to content.
1276
-                if (! empty($cfg['content'])) {
1277
-                    $content = ! empty($cfg['content']) ? $cfg['content'] : null;
1278
-                    // second priority goes to filename
1279
-                } elseif (! empty($cfg['filename'])) {
1280
-                    $file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php';
1281
-                    // it's possible that the file is located on decaf route (and above sets up for caf route, if this is the case then lets check decaf route too)
1282
-                    $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1283
-                                                             . basename($this->_get_dir())
1284
-                                                             . '/help_tabs/'
1285
-                                                             . $cfg['filename']
1286
-                                                             . '.help_tab.php' : $file_path;
1287
-                    // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1288
-                    if (! isset($cfg['callback']) && ! is_readable($file_path)) {
1289
-                        EE_Error::add_error(
1290
-                            sprintf(
1291
-                                esc_html__(
1292
-                                    'The filename given for the help tab %s is not a valid file and there is no other configuration for the tab content.  Please check that the string you set for the help tab on this route (%s) is the correct spelling.  The file should be in %s',
1293
-                                    'event_espresso'
1294
-                                ),
1295
-                                $tab_id,
1296
-                                key($config),
1297
-                                $file_path
1298
-                            ),
1299
-                            __FILE__,
1300
-                            __FUNCTION__,
1301
-                            __LINE__
1302
-                        );
1303
-                        return;
1304
-                    }
1305
-                    $template_args['admin_page_obj'] = $this;
1306
-                    $content = EEH_Template::display_template(
1307
-                        $file_path,
1308
-                        $template_args,
1309
-                        true
1310
-                    );
1311
-                } else {
1312
-                    $content = '';
1313
-                }
1314
-                // check if callback is valid
1315
-                if (empty($content) && (
1316
-                        ! isset($cfg['callback']) || ! method_exists($this, $cfg['callback'])
1317
-                    )
1318
-                ) {
1319
-                    EE_Error::add_error(
1320
-                        sprintf(
1321
-                            esc_html__(
1322
-                                'The callback given for a %s help tab on this page does not content OR a corresponding method for generating the content.  Check the spelling or make sure the method is present.',
1323
-                                'event_espresso'
1324
-                            ),
1325
-                            $cfg['title']
1326
-                        ),
1327
-                        __FILE__,
1328
-                        __FUNCTION__,
1329
-                        __LINE__
1330
-                    );
1331
-                    return;
1332
-                }
1333
-                // setup config array for help tab method
1334
-                $id = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id;
1335
-                $_ht = array(
1336
-                    'id'       => $id,
1337
-                    'title'    => $cfg['title'],
1338
-                    'callback' => isset($cfg['callback']) && empty($content) ? array($this, $cfg['callback']) : null,
1339
-                    'content'  => $content,
1340
-                );
1341
-                $this->_current_screen->add_help_tab($_ht);
1342
-            }
1343
-        }
1344
-    }
1345
-
1346
-
1347
-    /**
1348
-     * This basically checks loaded $_page_config property to see if there are any help_tours defined.  "help_tours" is
1349
-     * an array with properties for setting up usage of the joyride plugin
1350
-     *
1351
-     * @link   http://zurb.com/playground/jquery-joyride-feature-tour-plugin
1352
-     * @see    instructions regarding the format and construction of the "help_tour" array element is found in the
1353
-     *         _set_page_config() comments
1354
-     * @return void
1355
-     * @throws EE_Error
1356
-     * @throws InvalidArgumentException
1357
-     * @throws InvalidDataTypeException
1358
-     * @throws InvalidInterfaceException
1359
-     * @throws ReflectionException
1360
-     */
1361
-    protected function _add_help_tour()
1362
-    {
1363
-        $tours = array();
1364
-        $this->_help_tour = array();
1365
-        // exit early if help tours are turned off globally
1366
-        if ((defined('EE_DISABLE_HELP_TOURS') && EE_DISABLE_HELP_TOURS)
1367
-            || ! EE_Registry::instance()->CFG->admin->help_tour_activation
1368
-        ) {
1369
-            return;
1370
-        }
1371
-        // loop through _page_config to find any help_tour defined
1372
-        foreach ($this->_page_config as $route => $config) {
1373
-            // we're only going to set things up for this route
1374
-            if ($route !== $this->_req_action) {
1375
-                continue;
1376
-            }
1377
-            if (isset($config['help_tour'])) {
1378
-                foreach ($config['help_tour'] as $tour) {
1379
-                    $file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php';
1380
-                    // let's see if we can get that file...
1381
-                    // if not its possible this is a decaf route not set in caffeinated
1382
-                    // so lets try and get the caffeinated equivalent
1383
-                    $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1384
-                                                             . basename($this->_get_dir())
1385
-                                                             . '/help_tours/'
1386
-                                                             . $tour
1387
-                                                             . '.class.php' : $file_path;
1388
-                    // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1389
-                    if (! is_readable($file_path)) {
1390
-                        EE_Error::add_error(
1391
-                            sprintf(
1392
-                                esc_html__(
1393
-                                    'The file path given for the help tour (%s) is not a valid path.  Please check that the string you set for the help tour on this route (%s) is the correct spelling',
1394
-                                    'event_espresso'
1395
-                                ),
1396
-                                $file_path,
1397
-                                $tour
1398
-                            ),
1399
-                            __FILE__,
1400
-                            __FUNCTION__,
1401
-                            __LINE__
1402
-                        );
1403
-                        return;
1404
-                    }
1405
-                    require_once $file_path;
1406
-                    if (! class_exists($tour)) {
1407
-                        $error_msg = [];
1408
-                        $error_msg[] = sprintf(
1409
-                            esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'),
1410
-                            $tour
1411
-                        );
1412
-                        $error_msg[] = $error_msg[0] . "\r\n"
1413
-                                       . sprintf(
1414
-                                           esc_html__(
1415
-                                               'There is no class in place for the %s help tour.%s Make sure you have <strong>%s</strong> defined in the "help_tour" array for the %s route of the % admin page.',
1416
-                                               'event_espresso'
1417
-                                           ),
1418
-                                           $tour,
1419
-                                           '<br />',
1420
-                                           $tour,
1421
-                                           $this->_req_action,
1422
-                                           get_class($this)
1423
-                                       );
1424
-                        throw new EE_Error(implode('||', $error_msg));
1425
-                    }
1426
-                    $tour_obj = new $tour($this->_is_caf);
1427
-                    $tours[] = $tour_obj;
1428
-                    $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($tour_obj);
1429
-                }
1430
-                // let's inject the end tour stop element common to all pages... this will only get seen once per machine.
1431
-                $end_stop_tour = new EE_Help_Tour_final_stop($this->_is_caf);
1432
-                $tours[] = $end_stop_tour;
1433
-                $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($end_stop_tour);
1434
-            }
1435
-        }
1436
-
1437
-        if (! empty($tours)) {
1438
-            $this->_help_tour['tours'] = $tours;
1439
-        }
1440
-        // that's it!  Now that the $_help_tours property is set (or not)
1441
-        // the scripts and html should be taken care of automatically.
1442
-
1443
-        /**
1444
-         * Allow extending the help tours variable.
1445
-         *
1446
-         * @param array $_help_tour The array containing all help tour information to be displayed.
1447
-         */
1448
-        $this->_help_tour = apply_filters('FHEE__EE_Admin_Page___add_help_tour___help_tour', $this->_help_tour);
1449
-    }
1450
-
1451
-
1452
-    /**
1453
-     * This simply sets up any qtips that have been defined in the page config
1454
-     *
1455
-     * @return void
1456
-     * @throws ReflectionException
1457
-     * @throws EE_Error
1458
-     */
1459
-    protected function _add_qtips()
1460
-    {
1461
-        if (isset($this->_route_config['qtips'])) {
1462
-            $qtips = (array) $this->_route_config['qtips'];
1463
-            // load qtip loader
1464
-            $path = array(
1465
-                $this->_get_dir() . '/qtips/',
1466
-                EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/',
1467
-            );
1468
-            $qtip_loader = EEH_Qtip_Loader::instance();
1469
-            if ($qtip_loader instanceof EEH_Qtip_Loader) {
1470
-                $qtip_loader->register($qtips, $path);
1471
-            }
1472
-        }
1473
-    }
1474
-
1475
-
1476
-    /**
1477
-     * _set_nav_tabs
1478
-     * This sets up the nav tabs from the page_routes array.  This method can be overwritten by child classes if you
1479
-     * wish to add additional tabs or modify accordingly.
1480
-     *
1481
-     * @return void
1482
-     * @throws InvalidArgumentException
1483
-     * @throws InvalidInterfaceException
1484
-     * @throws InvalidDataTypeException
1485
-     */
1486
-    protected function _set_nav_tabs()
1487
-    {
1488
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1489
-        $i = 0;
1490
-        foreach ($this->_page_config as $slug => $config) {
1491
-            if (! is_array($config)
1492
-                || (
1493
-                    is_array($config)
1494
-                    && (
1495
-                        (isset($config['nav']) && ! $config['nav'])
1496
-                        || ! isset($config['nav'])
1497
-                    )
1498
-                )
1499
-            ) {
1500
-                continue;
1501
-            }
1502
-            // no nav tab for this config
1503
-            // check for persistent flag
1504
-            if ($slug !== $this->_req_action && isset($config['nav']['persistent']) && ! $config['nav']['persistent']) {
1505
-                // nav tab is only to appear when route requested.
1506
-                continue;
1507
-            }
1508
-            if (! $this->check_user_access($slug, true)) {
1509
-                // no nav tab because current user does not have access.
1510
-                continue;
1511
-            }
1512
-            $css_class = isset($config['css_class']) ? $config['css_class'] . ' ' : '';
1513
-            $this->_nav_tabs[ $slug ] = array(
1514
-                'url'       => isset($config['nav']['url'])
1515
-                    ? $config['nav']['url']
1516
-                    : EE_Admin_Page::add_query_args_and_nonce(
1517
-                        array('action' => $slug),
1518
-                        $this->_admin_base_url
1519
-                    ),
1520
-                'link_text' => isset($config['nav']['label'])
1521
-                    ? $config['nav']['label']
1522
-                    : ucwords(
1523
-                        str_replace('_', ' ', $slug)
1524
-                    ),
1525
-                'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class,
1526
-                'order'     => isset($config['nav']['order']) ? $config['nav']['order'] : $i,
1527
-            );
1528
-            $i++;
1529
-        }
1530
-        // if $this->_nav_tabs is empty then lets set the default
1531
-        if (empty($this->_nav_tabs)) {
1532
-            $this->_nav_tabs[ $this->_default_nav_tab_name ] = array(
1533
-                'url'       => $this->_admin_base_url,
1534
-                'link_text' => ucwords(str_replace('_', ' ', $this->_default_nav_tab_name)),
1535
-                'css_class' => 'nav-tab-active',
1536
-                'order'     => 10,
1537
-            );
1538
-        }
1539
-        // now let's sort the tabs according to order
1540
-        usort($this->_nav_tabs, array($this, '_sort_nav_tabs'));
1541
-    }
1542
-
1543
-
1544
-    /**
1545
-     * _set_current_labels
1546
-     * This method modifies the _labels property with any optional specific labels indicated in the _page_routes
1547
-     * property array
1548
-     *
1549
-     * @return void
1550
-     */
1551
-    private function _set_current_labels()
1552
-    {
1553
-        if (is_array($this->_route_config) && isset($this->_route_config['labels'])) {
1554
-            foreach ($this->_route_config['labels'] as $label => $text) {
1555
-                if (is_array($text)) {
1556
-                    foreach ($text as $sublabel => $subtext) {
1557
-                        $this->_labels[ $label ][ $sublabel ] = $subtext;
1558
-                    }
1559
-                } else {
1560
-                    $this->_labels[ $label ] = $text;
1561
-                }
1562
-            }
1563
-        }
1564
-    }
1565
-
1566
-
1567
-    /**
1568
-     *        verifies user access for this admin page
1569
-     *
1570
-     * @param string $route_to_check if present then the capability for the route matching this string is checked.
1571
-     * @param bool   $verify_only    Default is FALSE which means if user check fails then wp_die().  Otherwise just
1572
-     *                               return false if verify fail.
1573
-     * @return bool
1574
-     * @throws InvalidArgumentException
1575
-     * @throws InvalidDataTypeException
1576
-     * @throws InvalidInterfaceException
1577
-     */
1578
-    public function check_user_access($route_to_check = '', $verify_only = false)
1579
-    {
1580
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1581
-        $route_to_check = empty($route_to_check) ? $this->_req_action : $route_to_check;
1582
-        $capability = ! empty($route_to_check) && isset($this->_page_routes[ $route_to_check ])
1583
-                      && is_array(
1584
-                          $this->_page_routes[ $route_to_check ]
1585
-                      )
1586
-                      && ! empty($this->_page_routes[ $route_to_check ]['capability'])
1587
-            ? $this->_page_routes[ $route_to_check ]['capability'] : null;
1588
-        if (empty($capability) && empty($route_to_check)) {
1589
-            $capability = is_array($this->_route) && empty($this->_route['capability']) ? 'manage_options'
1590
-                : $this->_route['capability'];
1591
-        } else {
1592
-            $capability = empty($capability) ? 'manage_options' : $capability;
1593
-        }
1594
-        $id = is_array($this->_route) && ! empty($this->_route['obj_id']) ? $this->_route['obj_id'] : 0;
1595
-        if (! defined('DOING_AJAX')
1596
-            && (
1597
-                ! function_exists('is_admin')
1598
-                || ! EE_Registry::instance()->CAP->current_user_can(
1599
-                    $capability,
1600
-                    $this->page_slug
1601
-                    . '_'
1602
-                    . $route_to_check,
1603
-                    $id
1604
-                )
1605
-            )
1606
-        ) {
1607
-            if ($verify_only) {
1608
-                return false;
1609
-            }
1610
-            if (is_user_logged_in()) {
1611
-                wp_die(__('You do not have access to this route.', 'event_espresso'));
1612
-            } else {
1613
-                return false;
1614
-            }
1615
-        }
1616
-        return true;
1617
-    }
1618
-
1619
-
1620
-    /**
1621
-     * admin_init_global
1622
-     * This runs all the code that we want executed within the WP admin_init hook.
1623
-     * This method executes for ALL EE Admin pages.
1624
-     *
1625
-     * @return void
1626
-     */
1627
-    public function admin_init_global()
1628
-    {
1629
-    }
1630
-
1631
-
1632
-    /**
1633
-     * wp_loaded_global
1634
-     * This runs all the code that we want executed within the WP wp_loaded hook.  This method is optional for an
1635
-     * EE_Admin page and will execute on every EE Admin Page load
1636
-     *
1637
-     * @return void
1638
-     */
1639
-    public function wp_loaded()
1640
-    {
1641
-    }
1642
-
1643
-
1644
-    /**
1645
-     * admin_notices
1646
-     * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply on
1647
-     * ALL EE_Admin pages.
1648
-     *
1649
-     * @return void
1650
-     */
1651
-    public function admin_notices_global()
1652
-    {
1653
-        $this->_display_no_javascript_warning();
1654
-        $this->_display_espresso_notices();
1655
-    }
1656
-
1657
-
1658
-    public function network_admin_notices_global()
1659
-    {
1660
-        $this->_display_no_javascript_warning();
1661
-        $this->_display_espresso_notices();
1662
-    }
1663
-
1664
-
1665
-    /**
1666
-     * admin_footer_scripts_global
1667
-     * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
1668
-     * will apply on ALL EE_Admin pages.
1669
-     *
1670
-     * @return void
1671
-     */
1672
-    public function admin_footer_scripts_global()
1673
-    {
1674
-        $this->_add_admin_page_ajax_loading_img();
1675
-        $this->_add_admin_page_overlay();
1676
-        // if metaboxes are present we need to add the nonce field
1677
-        if (isset($this->_route_config['metaboxes'])
1678
-            || isset($this->_route_config['list_table'])
1679
-            || (isset($this->_route_config['has_metaboxes']) && $this->_route_config['has_metaboxes'])
1680
-        ) {
1681
-            wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false);
1682
-            wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false);
1683
-        }
1684
-    }
1685
-
1686
-
1687
-    /**
1688
-     * admin_footer_global
1689
-     * Anything triggered by the wp 'admin_footer' wp hook should be put in here.
1690
-     * This particular method will apply on ALL EE_Admin Pages.
1691
-     *
1692
-     * @return void
1693
-     * @throws InvalidArgumentException
1694
-     * @throws InvalidDataTypeException
1695
-     * @throws InvalidInterfaceException
1696
-     */
1697
-    public function admin_footer_global()
1698
-    {
1699
-        // dialog container for dialog helper
1700
-        $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n";
1701
-        $d_cont .= '<div class="ee-notices"></div>';
1702
-        $d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>';
1703
-        $d_cont .= '</div>';
1704
-        echo $d_cont;
1705
-        // help tour stuff?
1706
-        if (isset($this->_help_tour[ $this->_req_action ])) {
1707
-            echo implode('<br />', $this->_help_tour[ $this->_req_action ]);
1708
-        }
1709
-        // current set timezone for timezone js
1710
-        echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>';
1711
-    }
1712
-
1713
-
1714
-    /**
1715
-     * This function sees if there is a method for help popup content existing for the given route.  If there is then
1716
-     * we'll use the retrieved array to output the content using the template. For child classes: If you want to have
1717
-     * help popups then in your templates or your content you set "triggers" for the content using the
1718
-     * "_set_help_trigger('help_trigger_id')" where "help_trigger_id" is what you will use later in your custom method
1719
-     * for the help popup content on that page. Then in your Child_Admin_Page class you need to define a help popup
1720
-     * method for the content in the format "_help_popup_content_{route_name}()"  So if you are setting help content
1721
-     * for the
1722
-     * 'edit_event' route you should have a method named "_help_popup_content_edit_route". In your defined
1723
-     * "help_popup_content_..." method.  You must prepare and return an array in the following format array(
1724
-     *    'help_trigger_id' => array(
1725
-     *        'title' => esc_html__('localized title for popup', 'event_espresso'),
1726
-     *        'content' => esc_html__('localized content for popup', 'event_espresso')
1727
-     *    )
1728
-     * );
1729
-     * Then the EE_Admin_Parent will take care of making sure that is setup properly on the correct route.
1730
-     *
1731
-     * @param array $help_array
1732
-     * @param bool  $display
1733
-     * @return string content
1734
-     * @throws DomainException
1735
-     * @throws EE_Error
1736
-     */
1737
-    protected function _set_help_popup_content($help_array = array(), $display = false)
1738
-    {
1739
-        $content = '';
1740
-        $help_array = empty($help_array) ? $this->_get_help_content() : $help_array;
1741
-        // loop through the array and setup content
1742
-        foreach ($help_array as $trigger => $help) {
1743
-            // make sure the array is setup properly
1744
-            if (! isset($help['title'], $help['content'])) {
1745
-                throw new EE_Error(
1746
-                    esc_html__(
1747
-                        'Does not look like the popup content array has been setup correctly.  Might want to double check that.  Read the comments for the _get_help_popup_content method found in "EE_Admin_Page" class',
1748
-                        'event_espresso'
1749
-                    )
1750
-                );
1751
-            }
1752
-            // we're good so let'd setup the template vars and then assign parsed template content to our content.
1753
-            $template_args = array(
1754
-                'help_popup_id'      => $trigger,
1755
-                'help_popup_title'   => $help['title'],
1756
-                'help_popup_content' => $help['content'],
1757
-            );
1758
-            $content .= EEH_Template::display_template(
1759
-                EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php',
1760
-                $template_args,
1761
-                true
1762
-            );
1763
-        }
1764
-        if ($display) {
1765
-            echo $content;
1766
-            return '';
1767
-        }
1768
-        return $content;
1769
-    }
1770
-
1771
-
1772
-    /**
1773
-     * All this does is retrieve the help content array if set by the EE_Admin_Page child
1774
-     *
1775
-     * @return array properly formatted array for help popup content
1776
-     * @throws EE_Error
1777
-     */
1778
-    private function _get_help_content()
1779
-    {
1780
-        // what is the method we're looking for?
1781
-        $method_name = '_help_popup_content_' . $this->_req_action;
1782
-        // if method doesn't exist let's get out.
1783
-        if (! method_exists($this, $method_name)) {
1784
-            return array();
1785
-        }
1786
-        // k we're good to go let's retrieve the help array
1787
-        $help_array = $this->{$method_name}();
1788
-        // make sure we've got an array!
1789
-        if (! is_array($help_array)) {
1790
-            throw new EE_Error(
1791
-                esc_html__(
1792
-                    'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.',
1793
-                    'event_espresso'
1794
-                )
1795
-            );
1796
-        }
1797
-        return $help_array;
1798
-    }
1799
-
1800
-
1801
-    /**
1802
-     * EE Admin Pages can use this to set a properly formatted trigger for a help popup.
1803
-     * By default the trigger html is printed.  Otherwise it can be returned if the $display flag is set "false"
1804
-     * See comments made on the _set_help_content method for understanding other parts to the help popup tool.
1805
-     *
1806
-     * @param string  $trigger_id reference for retrieving the trigger content for the popup
1807
-     * @param boolean $display    if false then we return the trigger string
1808
-     * @param array   $dimensions an array of dimensions for the box (array(h,w))
1809
-     * @return string
1810
-     * @throws DomainException
1811
-     * @throws EE_Error
1812
-     */
1813
-    protected function _set_help_trigger($trigger_id, $display = true, $dimensions = array('400', '640'))
1814
-    {
1815
-        if (defined('DOING_AJAX')) {
1816
-            return '';
1817
-        }
1818
-        // let's check and see if there is any content set for this popup.  If there isn't then we'll include a default title and content so that developers know something needs to be corrected
1819
-        $help_array = $this->_get_help_content();
1820
-        $help_content = '';
1821
-        if (empty($help_array) || ! isset($help_array[ $trigger_id ])) {
1822
-            $help_array[ $trigger_id ] = array(
1823
-                'title'   => esc_html__('Missing Content', 'event_espresso'),
1824
-                'content' => esc_html__(
1825
-                    'A trigger has been set that doesn\'t have any corresponding content. Make sure you have set the help content. (see the "_set_help_popup_content" method in the EE_Admin_Page for instructions.)',
1826
-                    'event_espresso'
1827
-                ),
1828
-            );
1829
-            $help_content = $this->_set_help_popup_content($help_array);
1830
-        }
1831
-        // let's setup the trigger
1832
-        $content = '<a class="ee-dialog" href="?height='
1833
-                   . $dimensions[0]
1834
-                   . '&width='
1835
-                   . $dimensions[1]
1836
-                   . '&inlineId='
1837
-                   . $trigger_id
1838
-                   . '" target="_blank"><span class="question ee-help-popup-question"></span></a>';
1839
-        $content .= $help_content;
1840
-        if ($display) {
1841
-            echo $content;
1842
-            return '';
1843
-        }
1844
-        return $content;
1845
-    }
1846
-
1847
-
1848
-    /**
1849
-     * _add_global_screen_options
1850
-     * Add any extra wp_screen_options within this method using built-in WP functions/methods for doing so.
1851
-     * This particular method will add_screen_options on ALL EE_Admin Pages
1852
-     *
1853
-     * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
1854
-     *         see also WP_Screen object documents...
1855
-     * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
1856
-     * @abstract
1857
-     * @return void
1858
-     */
1859
-    private function _add_global_screen_options()
1860
-    {
1861
-    }
1862
-
1863
-
1864
-    /**
1865
-     * _add_global_feature_pointers
1866
-     * This method is used for implementing any "feature pointers" (using built-in WP styling js).
1867
-     * This particular method will implement feature pointers for ALL EE_Admin pages.
1868
-     * Note: this is just a placeholder for now.  Implementation will come down the road
1869
-     *
1870
-     * @see    WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
1871
-     *         extended) also see:
1872
-     * @link   http://eamann.com/tech/wordpress-portland/
1873
-     * @abstract
1874
-     * @return void
1875
-     */
1876
-    private function _add_global_feature_pointers()
1877
-    {
1878
-    }
1879
-
1880
-
1881
-    /**
1882
-     * load_global_scripts_styles
1883
-     * The scripts and styles enqueued in here will be loaded on every EE Admin page
1884
-     *
1885
-     * @return void
1886
-     * @throws EE_Error
1887
-     */
1888
-    public function load_global_scripts_styles()
1889
-    {
1890
-        /** STYLES **/
1891
-        // add debugging styles
1892
-        if (WP_DEBUG) {
1893
-            add_action('admin_head', array($this, 'add_xdebug_style'));
1894
-        }
1895
-        // register all styles
1896
-        wp_register_style(
1897
-            'espresso-ui-theme',
1898
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1899
-            array(),
1900
-            EVENT_ESPRESSO_VERSION
1901
-        );
1902
-        wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1903
-        // helpers styles
1904
-        wp_register_style(
1905
-            'ee-text-links',
1906
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css',
1907
-            array(),
1908
-            EVENT_ESPRESSO_VERSION
1909
-        );
1910
-        /** SCRIPTS **/
1911
-        // register all scripts
1912
-        wp_register_script(
1913
-            'ee-dialog',
1914
-            EE_ADMIN_URL . 'assets/ee-dialog-helper.js',
1915
-            array('jquery', 'jquery-ui-draggable'),
1916
-            EVENT_ESPRESSO_VERSION,
1917
-            true
1918
-        );
1919
-        wp_register_script(
1920
-            'ee_admin_js',
1921
-            EE_ADMIN_URL . 'assets/ee-admin-page.js',
1922
-            array('espresso_core', 'ee-parse-uri', 'ee-dialog'),
1923
-            EVENT_ESPRESSO_VERSION,
1924
-            true
1925
-        );
1926
-        wp_register_script(
1927
-            'jquery-ui-timepicker-addon',
1928
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js',
1929
-            array('jquery-ui-datepicker', 'jquery-ui-slider'),
1930
-            EVENT_ESPRESSO_VERSION,
1931
-            true
1932
-        );
1933
-        if (EE_Registry::instance()->CFG->admin->help_tour_activation) {
1934
-            add_filter('FHEE_load_joyride', '__return_true');
1935
-        }
1936
-        // script for sorting tables
1937
-        wp_register_script(
1938
-            'espresso_ajax_table_sorting',
1939
-            EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js',
1940
-            array('ee_admin_js', 'jquery-ui-sortable'),
1941
-            EVENT_ESPRESSO_VERSION,
1942
-            true
1943
-        );
1944
-        // script for parsing uri's
1945
-        wp_register_script(
1946
-            'ee-parse-uri',
1947
-            EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js',
1948
-            array(),
1949
-            EVENT_ESPRESSO_VERSION,
1950
-            true
1951
-        );
1952
-        // and parsing associative serialized form elements
1953
-        wp_register_script(
1954
-            'ee-serialize-full-array',
1955
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js',
1956
-            array('jquery'),
1957
-            EVENT_ESPRESSO_VERSION,
1958
-            true
1959
-        );
1960
-        // helpers scripts
1961
-        wp_register_script(
1962
-            'ee-text-links',
1963
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js',
1964
-            array('jquery'),
1965
-            EVENT_ESPRESSO_VERSION,
1966
-            true
1967
-        );
1968
-        wp_register_script(
1969
-            'ee-moment-core',
1970
-            EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js',
1971
-            array(),
1972
-            EVENT_ESPRESSO_VERSION,
1973
-            true
1974
-        );
1975
-        wp_register_script(
1976
-            'ee-moment',
1977
-            EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js',
1978
-            array('ee-moment-core'),
1979
-            EVENT_ESPRESSO_VERSION,
1980
-            true
1981
-        );
1982
-        wp_register_script(
1983
-            'ee-datepicker',
1984
-            EE_ADMIN_URL . 'assets/ee-datepicker.js',
1985
-            array('jquery-ui-timepicker-addon', 'ee-moment'),
1986
-            EVENT_ESPRESSO_VERSION,
1987
-            true
1988
-        );
1989
-        // google charts
1990
-        wp_register_script(
1991
-            'google-charts',
1992
-            'https://www.gstatic.com/charts/loader.js',
1993
-            array(),
1994
-            EVENT_ESPRESSO_VERSION
1995
-        );
1996
-        // ENQUEUE ALL BASICS BY DEFAULT
1997
-        wp_enqueue_style('ee-admin-css');
1998
-        wp_enqueue_script('ee_admin_js');
1999
-        wp_enqueue_script('jquery-validate');
2000
-        // taking care of metaboxes
2001
-        if (empty($this->_cpt_route)
2002
-            && (isset($this->_route_config['metaboxes']) || isset($this->_route_config['has_metaboxes']))
2003
-        ) {
2004
-            wp_enqueue_script('dashboard');
2005
-        }
2006
-        // LOCALIZED DATA
2007
-        // localize script for ajax lazy loading
2008
-        $lazy_loader_container_ids = apply_filters(
2009
-            'FHEE__EE_Admin_Page_Core__load_global_scripts_styles__loader_containers',
2010
-            array('espresso_news_post_box_content')
2011
-        );
2012
-        wp_localize_script('ee_admin_js', 'eeLazyLoadingContainers', $lazy_loader_container_ids);
2013
-        /**
2014
-         * help tour stuff
2015
-         */
2016
-        if (! empty($this->_help_tour)) {
2017
-            // register the js for kicking things off
2018
-            wp_enqueue_script(
2019
-                'ee-help-tour',
2020
-                EE_ADMIN_URL . 'assets/ee-help-tour.js',
2021
-                array('jquery-joyride'),
2022
-                EVENT_ESPRESSO_VERSION,
2023
-                true
2024
-            );
2025
-            $tours = array();
2026
-            // setup tours for the js tour object
2027
-            foreach ($this->_help_tour['tours'] as $tour) {
2028
-                if ($tour instanceof EE_Help_Tour) {
2029
-                    $tours[] = array(
2030
-                        'id'      => $tour->get_slug(),
2031
-                        'options' => $tour->get_options(),
2032
-                    );
2033
-                }
2034
-            }
2035
-            wp_localize_script('ee-help-tour', 'EE_HELP_TOUR', array('tours' => $tours));
2036
-            // admin_footer_global will take care of making sure our help_tour skeleton gets printed via the info stored in $this->_help_tour
2037
-        }
2038
-    }
2039
-
2040
-
2041
-    /**
2042
-     *        admin_footer_scripts_eei18n_js_strings
2043
-     *
2044
-     * @return        void
2045
-     */
2046
-    public function admin_footer_scripts_eei18n_js_strings()
2047
-    {
2048
-        EE_Registry::$i18n_js_strings['ajax_url'] = WP_AJAX_URL;
2049
-        EE_Registry::$i18n_js_strings['confirm_delete'] = esc_html__(
2050
-            'Are you absolutely sure you want to delete this item?\nThis action will delete ALL DATA associated with this item!!!\nThis can NOT be undone!!!',
2051
-            'event_espresso'
2052
-        );
2053
-        EE_Registry::$i18n_js_strings['January'] = esc_html__('January', 'event_espresso');
2054
-        EE_Registry::$i18n_js_strings['February'] = esc_html__('February', 'event_espresso');
2055
-        EE_Registry::$i18n_js_strings['March'] = esc_html__('March', 'event_espresso');
2056
-        EE_Registry::$i18n_js_strings['April'] = esc_html__('April', 'event_espresso');
2057
-        EE_Registry::$i18n_js_strings['May'] = esc_html__('May', 'event_espresso');
2058
-        EE_Registry::$i18n_js_strings['June'] = esc_html__('June', 'event_espresso');
2059
-        EE_Registry::$i18n_js_strings['July'] = esc_html__('July', 'event_espresso');
2060
-        EE_Registry::$i18n_js_strings['August'] = esc_html__('August', 'event_espresso');
2061
-        EE_Registry::$i18n_js_strings['September'] = esc_html__('September', 'event_espresso');
2062
-        EE_Registry::$i18n_js_strings['October'] = esc_html__('October', 'event_espresso');
2063
-        EE_Registry::$i18n_js_strings['November'] = esc_html__('November', 'event_espresso');
2064
-        EE_Registry::$i18n_js_strings['December'] = esc_html__('December', 'event_espresso');
2065
-        EE_Registry::$i18n_js_strings['Jan'] = esc_html__('Jan', 'event_espresso');
2066
-        EE_Registry::$i18n_js_strings['Feb'] = esc_html__('Feb', 'event_espresso');
2067
-        EE_Registry::$i18n_js_strings['Mar'] = esc_html__('Mar', 'event_espresso');
2068
-        EE_Registry::$i18n_js_strings['Apr'] = esc_html__('Apr', 'event_espresso');
2069
-        EE_Registry::$i18n_js_strings['May'] = esc_html__('May', 'event_espresso');
2070
-        EE_Registry::$i18n_js_strings['Jun'] = esc_html__('Jun', 'event_espresso');
2071
-        EE_Registry::$i18n_js_strings['Jul'] = esc_html__('Jul', 'event_espresso');
2072
-        EE_Registry::$i18n_js_strings['Aug'] = esc_html__('Aug', 'event_espresso');
2073
-        EE_Registry::$i18n_js_strings['Sep'] = esc_html__('Sep', 'event_espresso');
2074
-        EE_Registry::$i18n_js_strings['Oct'] = esc_html__('Oct', 'event_espresso');
2075
-        EE_Registry::$i18n_js_strings['Nov'] = esc_html__('Nov', 'event_espresso');
2076
-        EE_Registry::$i18n_js_strings['Dec'] = esc_html__('Dec', 'event_espresso');
2077
-        EE_Registry::$i18n_js_strings['Sunday'] = esc_html__('Sunday', 'event_espresso');
2078
-        EE_Registry::$i18n_js_strings['Monday'] = esc_html__('Monday', 'event_espresso');
2079
-        EE_Registry::$i18n_js_strings['Tuesday'] = esc_html__('Tuesday', 'event_espresso');
2080
-        EE_Registry::$i18n_js_strings['Wednesday'] = esc_html__('Wednesday', 'event_espresso');
2081
-        EE_Registry::$i18n_js_strings['Thursday'] = esc_html__('Thursday', 'event_espresso');
2082
-        EE_Registry::$i18n_js_strings['Friday'] = esc_html__('Friday', 'event_espresso');
2083
-        EE_Registry::$i18n_js_strings['Saturday'] = esc_html__('Saturday', 'event_espresso');
2084
-        EE_Registry::$i18n_js_strings['Sun'] = esc_html__('Sun', 'event_espresso');
2085
-        EE_Registry::$i18n_js_strings['Mon'] = esc_html__('Mon', 'event_espresso');
2086
-        EE_Registry::$i18n_js_strings['Tue'] = esc_html__('Tue', 'event_espresso');
2087
-        EE_Registry::$i18n_js_strings['Wed'] = esc_html__('Wed', 'event_espresso');
2088
-        EE_Registry::$i18n_js_strings['Thu'] = esc_html__('Thu', 'event_espresso');
2089
-        EE_Registry::$i18n_js_strings['Fri'] = esc_html__('Fri', 'event_espresso');
2090
-        EE_Registry::$i18n_js_strings['Sat'] = esc_html__('Sat', 'event_espresso');
2091
-    }
2092
-
2093
-
2094
-    /**
2095
-     *        load enhanced xdebug styles for ppl with failing eyesight
2096
-     *
2097
-     * @return        void
2098
-     */
2099
-    public function add_xdebug_style()
2100
-    {
2101
-        echo '<style>.xdebug-error { font-size:1.5em; }</style>';
2102
-    }
2103
-
2104
-
2105
-    /************************/
2106
-    /** LIST TABLE METHODS **/
2107
-    /************************/
2108
-    /**
2109
-     * this sets up the list table if the current view requires it.
2110
-     *
2111
-     * @return void
2112
-     * @throws EE_Error
2113
-     * @throws InvalidArgumentException
2114
-     * @throws InvalidDataTypeException
2115
-     * @throws InvalidInterfaceException
2116
-     */
2117
-    protected function _set_list_table()
2118
-    {
2119
-        // first is this a list_table view?
2120
-        if (! isset($this->_route_config['list_table'])) {
2121
-            return;
2122
-        } //not a list_table view so get out.
2123
-        // list table functions are per view specific (because some admin pages might have more than one list table!)
2124
-        $list_table_view = '_set_list_table_views_' . $this->_req_action;
2125
-        if (! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) {
2126
-            // user error msg
2127
-            $error_msg = esc_html__(
2128
-                'An error occurred. The requested list table views could not be found.',
2129
-                'event_espresso'
2130
-            );
2131
-            // developer error msg
2132
-            $error_msg .= '||'
2133
-                          . sprintf(
2134
-                              esc_html__(
2135
-                                  'List table views for "%s" route could not be setup. Check that you have the corresponding method, "%s" set up for defining list_table_views for this route.',
2136
-                                  'event_espresso'
2137
-                              ),
2138
-                              $this->_req_action,
2139
-                              $list_table_view
2140
-                          );
2141
-            throw new EE_Error($error_msg);
2142
-        }
2143
-        // let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally
2144
-        $this->_views = apply_filters(
2145
-            'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action,
2146
-            $this->_views
2147
-        );
2148
-        $this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views);
2149
-        $this->_views = apply_filters('FHEE_list_table_views', $this->_views);
2150
-        $this->_set_list_table_view();
2151
-        $this->_set_list_table_object();
2152
-    }
2153
-
2154
-
2155
-    /**
2156
-     * set current view for List Table
2157
-     *
2158
-     * @return void
2159
-     */
2160
-    protected function _set_list_table_view()
2161
-    {
2162
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2163
-        // looking at active items or dumpster diving ?
2164
-        if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2165
-            $this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all';
2166
-        } else {
2167
-            $this->_view = sanitize_key($this->_req_data['status']);
2168
-        }
2169
-    }
2170
-
2171
-
2172
-    /**
2173
-     * _set_list_table_object
2174
-     * WP_List_Table objects need to be loaded fairly early so automatic stuff WP does is taken care of.
2175
-     *
2176
-     * @throws InvalidInterfaceException
2177
-     * @throws InvalidArgumentException
2178
-     * @throws InvalidDataTypeException
2179
-     * @throws EE_Error
2180
-     * @throws InvalidInterfaceException
2181
-     */
2182
-    protected function _set_list_table_object()
2183
-    {
2184
-        if (isset($this->_route_config['list_table'])) {
2185
-            if (! class_exists($this->_route_config['list_table'])) {
2186
-                throw new EE_Error(
2187
-                    sprintf(
2188
-                        esc_html__(
2189
-                            'The %s class defined for the list table does not exist.  Please check the spelling of the class ref in the $_page_config property on %s.',
2190
-                            'event_espresso'
2191
-                        ),
2192
-                        $this->_route_config['list_table'],
2193
-                        get_class($this)
2194
-                    )
2195
-                );
2196
-            }
2197
-            $this->_list_table_object = $this->loader->getShared(
2198
-                $this->_route_config['list_table'],
2199
-                array($this)
2200
-            );
2201
-        }
2202
-    }
2203
-
2204
-
2205
-    /**
2206
-     * get_list_table_view_RLs - get it? View RL ?? VU-RL???  URL ??
2207
-     *
2208
-     * @param array $extra_query_args                     Optional. An array of extra query args to add to the generated
2209
-     *                                                    urls.  The array should be indexed by the view it is being
2210
-     *                                                    added to.
2211
-     * @return array
2212
-     */
2213
-    public function get_list_table_view_RLs($extra_query_args = array())
2214
-    {
2215
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2216
-        if (empty($this->_views)) {
2217
-            $this->_views = array();
2218
-        }
2219
-        // cycle thru views
2220
-        foreach ($this->_views as $key => $view) {
2221
-            $query_args = array();
2222
-            // check for current view
2223
-            $this->_views[ $key ]['class'] = $this->_view === $view['slug'] ? 'current' : '';
2224
-            $query_args['action'] = $this->_req_action;
2225
-            $query_args[ $this->_req_action . '_nonce' ] = wp_create_nonce($query_args['action'] . '_nonce');
2226
-            $query_args['status'] = $view['slug'];
2227
-            // merge any other arguments sent in.
2228
-            if (isset($extra_query_args[ $view['slug'] ])) {
2229
-                foreach ($extra_query_args[ $view['slug'] ] as $extra_query_arg) {
2230
-                    $query_args[] = $extra_query_arg;
2231
-                }
2232
-            }
2233
-            $this->_views[ $key ]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2234
-        }
2235
-        return $this->_views;
2236
-    }
2237
-
2238
-
2239
-    /**
2240
-     * _entries_per_page_dropdown
2241
-     * generates a drop down box for selecting the number of visible rows in an admin page list table
2242
-     *
2243
-     * @todo   : Note: ideally this should be added to the screen options dropdown as that would be consistent with how
2244
-     *         WP does it.
2245
-     * @param int $max_entries total number of rows in the table
2246
-     * @return string
2247
-     */
2248
-    protected function _entries_per_page_dropdown($max_entries = 0)
2249
-    {
2250
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2251
-        $values = array(10, 25, 50, 100);
2252
-        $per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2253
-        if ($max_entries) {
2254
-            $values[] = $max_entries;
2255
-            sort($values);
2256
-        }
2257
-        $entries_per_page_dropdown = '
109
+	/**
110
+	 * Used to hold default query args for list table routes to help preserve stickiness of filters for carried out
111
+	 * actions.
112
+	 *
113
+	 * @since 4.6.x
114
+	 * @var array.
115
+	 */
116
+	protected $_default_route_query_args;
117
+
118
+	// set via request page and action args.
119
+	protected $_current_page;
120
+
121
+	protected $_current_view;
122
+
123
+	protected $_current_page_view_url;
124
+
125
+	// sanitized request action (and nonce)
126
+
127
+	/**
128
+	 * @var string $_req_action
129
+	 */
130
+	protected $_req_action;
131
+
132
+	/**
133
+	 * @var string $_req_nonce
134
+	 */
135
+	protected $_req_nonce;
136
+
137
+	// search related
138
+	protected $_search_btn_label;
139
+
140
+	protected $_search_box_callback;
141
+
142
+	/**
143
+	 * WP Current Screen object
144
+	 *
145
+	 * @var WP_Screen
146
+	 */
147
+	protected $_current_screen;
148
+
149
+	// for holding EE_Admin_Hooks object when needed (set via set_hook_object())
150
+	protected $_hook_obj;
151
+
152
+	// for holding incoming request data
153
+	protected $_req_data;
154
+
155
+	// yes / no array for admin form fields
156
+	protected $_yes_no_values = array();
157
+
158
+	// some default things shared by all child classes
159
+	protected $_default_espresso_metaboxes;
160
+
161
+	/**
162
+	 *    EE_Registry Object
163
+	 *
164
+	 * @var    EE_Registry
165
+	 */
166
+	protected $EE;
167
+
168
+
169
+	/**
170
+	 * This is just a property that flags whether the given route is a caffeinated route or not.
171
+	 *
172
+	 * @var boolean
173
+	 */
174
+	protected $_is_caf = false;
175
+
176
+
177
+	/**
178
+	 * @Constructor
179
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
180
+	 * @throws InvalidArgumentException
181
+	 * @throws InvalidDataTypeException
182
+	 * @throws InvalidInterfaceException
183
+	 * @throws ReflectionException
184
+	 */
185
+	public function __construct($routing = true)
186
+	{
187
+		$this->loader = LoaderFactory::getLoader();
188
+		if (strpos($this->_get_dir(), 'caffeinated') !== false) {
189
+			$this->_is_caf = true;
190
+		}
191
+		$this->_yes_no_values = array(
192
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
193
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
194
+		);
195
+		// set the _req_data property.
196
+		$this->_req_data = array_merge($_GET, $_POST);
197
+		// routing enabled?
198
+		$this->_routing = $routing;
199
+	}
200
+
201
+
202
+	/**
203
+	 * This logic used to be in the constructor, but that caused a chicken <--> egg scenario
204
+	 * for child classes that needed to set properties prior to these methods getting called,
205
+	 * but also needed the parent class to have its construction completed as well.
206
+	 * Bottom line is that constructors should ONLY be used for setting initial properties
207
+	 * and any complex initialization logic should only run after instantiation is complete.
208
+	 *
209
+	 * This method gets called immediately after construction from within
210
+	 *      EE_Admin_Page_Init::_initialize_admin_page()
211
+	 *
212
+	 * @throws EE_Error
213
+	 * @throws InvalidArgumentException
214
+	 * @throws InvalidDataTypeException
215
+	 * @throws InvalidInterfaceException
216
+	 * @throws ReflectionException
217
+	 * @since $VID:$
218
+	 */
219
+	public function initializePage()
220
+	{
221
+		// set initial page props (child method)
222
+		$this->_init_page_props();
223
+		// set global defaults
224
+		$this->_set_defaults();
225
+		// set early because incoming requests could be ajax related and we need to register those hooks.
226
+		$this->_global_ajax_hooks();
227
+		$this->_ajax_hooks();
228
+		// other_page_hooks have to be early too.
229
+		$this->_do_other_page_hooks();
230
+		// This just allows us to have extending classes do something specific
231
+		// before the parent constructor runs _page_setup().
232
+		if (method_exists($this, '_before_page_setup')) {
233
+			$this->_before_page_setup();
234
+		}
235
+		// set up page dependencies
236
+		$this->_page_setup();
237
+	}
238
+
239
+
240
+	/**
241
+	 * _init_page_props
242
+	 * Child classes use to set at least the following properties:
243
+	 * $page_slug.
244
+	 * $page_label.
245
+	 *
246
+	 * @abstract
247
+	 * @return void
248
+	 */
249
+	abstract protected function _init_page_props();
250
+
251
+
252
+	/**
253
+	 * _ajax_hooks
254
+	 * child classes put all their add_action('wp_ajax_{name_of_hook}') hooks in here.
255
+	 * Note: within the ajax callback methods.
256
+	 *
257
+	 * @abstract
258
+	 * @return void
259
+	 */
260
+	abstract protected function _ajax_hooks();
261
+
262
+
263
+	/**
264
+	 * _define_page_props
265
+	 * child classes define page properties in here.  Must include at least:
266
+	 * $_admin_base_url = base_url for all admin pages
267
+	 * $_admin_page_title = default admin_page_title for admin pages
268
+	 * $_labels = array of default labels for various automatically generated elements:
269
+	 *    array(
270
+	 *        'buttons' => array(
271
+	 *            'add' => esc_html__('label for add new button'),
272
+	 *            'edit' => esc_html__('label for edit button'),
273
+	 *            'delete' => esc_html__('label for delete button')
274
+	 *            )
275
+	 *        )
276
+	 *
277
+	 * @abstract
278
+	 * @return void
279
+	 */
280
+	abstract protected function _define_page_props();
281
+
282
+
283
+	/**
284
+	 * _set_page_routes
285
+	 * child classes use this to define the page routes for all subpages handled by the class.  Page routes are
286
+	 * assigned to a action => method pairs in an array and to the $_page_routes property.  Each page route must also
287
+	 * have a 'default' route. Here's the format
288
+	 * $this->_page_routes = array(
289
+	 *        'default' => array(
290
+	 *            'func' => '_default_method_handling_route',
291
+	 *            'args' => array('array','of','args'),
292
+	 *            'noheader' => true, //add this in if this page route is processed before any headers are loaded (i.e.
293
+	 *            ajax request, backend processing)
294
+	 *            'headers_sent_route'=>'headers_route_reference', //add this if noheader=>true, and you want to load a
295
+	 *            headers route after.  The string you enter here should match the defined route reference for a
296
+	 *            headers sent route.
297
+	 *            'capability' => 'route_capability', //indicate a string for minimum capability required to access
298
+	 *            this route.
299
+	 *            'obj_id' => 10 // if this route has an object id, then this can include it (used for capability
300
+	 *            checks).
301
+	 *        ),
302
+	 *        'insert_item' => '_method_for_handling_insert_item' //this can be used if all we need to have is a
303
+	 *        handling method.
304
+	 *        )
305
+	 * )
306
+	 *
307
+	 * @abstract
308
+	 * @return void
309
+	 */
310
+	abstract protected function _set_page_routes();
311
+
312
+
313
+	/**
314
+	 * _set_page_config
315
+	 * child classes use this to define the _page_config array for all subpages handled by the class. Each key in the
316
+	 * array corresponds to the page_route for the loaded page. Format:
317
+	 * $this->_page_config = array(
318
+	 *        'default' => array(
319
+	 *            'labels' => array(
320
+	 *                'buttons' => array(
321
+	 *                    'add' => esc_html__('label for adding item'),
322
+	 *                    'edit' => esc_html__('label for editing item'),
323
+	 *                    'delete' => esc_html__('label for deleting item')
324
+	 *                ),
325
+	 *                'publishbox' => esc_html__('Localized Title for Publish metabox', 'event_espresso')
326
+	 *            ), //optional an array of custom labels for various automatically generated elements to use on the
327
+	 *            page. If this isn't present then the defaults will be used as set for the $this->_labels in
328
+	 *            _define_page_props() method
329
+	 *            'nav' => array(
330
+	 *                'label' => esc_html__('Label for Tab', 'event_espresso').
331
+	 *                'url' => 'http://someurl', //automatically generated UNLESS you define
332
+	 *                'css_class' => 'css-class', //automatically generated UNLESS you define
333
+	 *                'order' => 10, //required to indicate tab position.
334
+	 *                'persistent' => false //if you want the nav tab to ONLY display when the specific route is
335
+	 *                displayed then add this parameter.
336
+	 *            'list_table' => 'name_of_list_table' //string for list table class to be loaded for this admin_page.
337
+	 *            'metaboxes' => array('metabox1', 'metabox2'), //if present this key indicates we want to load
338
+	 *            metaboxes set for eventespresso admin pages.
339
+	 *            'has_metaboxes' => true, //this boolean flag can simply be used to indicate if the route will have
340
+	 *            metaboxes.  Typically this is used if the 'metaboxes' index is not used because metaboxes are added
341
+	 *            later.  We just use this flag to make sure the necessary js gets enqueued on page load.
342
+	 *            'has_help_popups' => false //defaults(true) //this boolean flag can simply be used to indicate if the
343
+	 *            given route has help popups setup and if it does then we need to make sure thickbox is enqueued.
344
+	 *            'columns' => array(4, 2), //this key triggers the setup of a page that uses columns (metaboxes).  The
345
+	 *            array indicates the max number of columns (4) and the default number of columns on page load (2).
346
+	 *            There is an option in the "screen_options" dropdown that is setup so users can pick what columns they
347
+	 *            want to display.
348
+	 *            'help_tabs' => array( //this is used for adding help tabs to a page
349
+	 *                'tab_id' => array(
350
+	 *                    'title' => 'tab_title',
351
+	 *                    'filename' => 'name_of_file_containing_content', //this is the primary method for setting
352
+	 *                    help tab content.  The fallback if it isn't present is to try a the callback.  Filename
353
+	 *                    should match a file in the admin folder's "help_tabs" dir (ie..
354
+	 *                    events/help_tabs/name_of_file_containing_content.help_tab.php)
355
+	 *                    'callback' => 'callback_method_for_content', //if 'filename' isn't present then system will
356
+	 *                    attempt to use the callback which should match the name of a method in the class
357
+	 *                    ),
358
+	 *                'tab2_id' => array(
359
+	 *                    'title' => 'tab2 title',
360
+	 *                    'filename' => 'file_name_2'
361
+	 *                    'callback' => 'callback_method_for_content',
362
+	 *                 ),
363
+	 *            'help_sidebar' => 'callback_for_sidebar_content', //this is used for setting up the sidebar in the
364
+	 *            help tab area on an admin page. @link
365
+	 *            http://make.wordpress.org/core/2011/12/06/help-and-screen-api-changes-in-3-3/
366
+	 *            'help_tour' => array(
367
+	 *                'name_of_help_tour_class', //all help tours shoudl be a child class of EE_Help_Tour and located
368
+	 *                in a folder for this admin page named "help_tours", a file name matching the key given here
369
+	 *                (name_of_help_tour_class.class.php), and class matching key given here (name_of_help_tour_class)
370
+	 *            ),
371
+	 *            'require_nonce' => TRUE //this is used if you want to set a route to NOT require a nonce (default is
372
+	 *            true if it isn't present).  To remove the requirement for a nonce check when this route is visited
373
+	 *            just set
374
+	 *            'require_nonce' to FALSE
375
+	 *            )
376
+	 * )
377
+	 *
378
+	 * @abstract
379
+	 * @return void
380
+	 */
381
+	abstract protected function _set_page_config();
382
+
383
+
384
+
385
+
386
+
387
+	/** end sample help_tour methods **/
388
+	/**
389
+	 * _add_screen_options
390
+	 * Child classes can add any extra wp_screen_options within this method using built-in WP functions/methods for
391
+	 * doing so. Note child classes can also define _add_screen_options_($this->_current_view) to limit screen options
392
+	 * to a particular view.
393
+	 *
394
+	 * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
395
+	 *         see also WP_Screen object documents...
396
+	 * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
397
+	 * @abstract
398
+	 * @return void
399
+	 */
400
+	abstract protected function _add_screen_options();
401
+
402
+
403
+	/**
404
+	 * _add_feature_pointers
405
+	 * Child classes should use this method for implementing any "feature pointers" (using built-in WP styling js).
406
+	 * Note child classes can also define _add_feature_pointers_($this->_current_view) to limit screen options to a
407
+	 * particular view. Note: this is just a placeholder for now.  Implementation will come down the road See:
408
+	 * WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
409
+	 * extended) also see:
410
+	 *
411
+	 * @link   http://eamann.com/tech/wordpress-portland/
412
+	 * @abstract
413
+	 * @return void
414
+	 */
415
+	abstract protected function _add_feature_pointers();
416
+
417
+
418
+	/**
419
+	 * load_scripts_styles
420
+	 * child classes put their wp_enqueue_script and wp_enqueue_style hooks in here for anything they need loaded for
421
+	 * their pages/subpages.  Note this is for all pages/subpages of the system.  You can also load only specific
422
+	 * scripts/styles per view by putting them in a dynamic function in this format
423
+	 * (load_scripts_styles_{$this->_current_view}) which matches your page route (action request arg)
424
+	 *
425
+	 * @abstract
426
+	 * @return void
427
+	 */
428
+	abstract public function load_scripts_styles();
429
+
430
+
431
+	/**
432
+	 * admin_init
433
+	 * Anything that should be set/executed at 'admin_init' WP hook runtime should be put in here.  This will apply to
434
+	 * all pages/views loaded by child class.
435
+	 *
436
+	 * @abstract
437
+	 * @return void
438
+	 */
439
+	abstract public function admin_init();
440
+
441
+
442
+	/**
443
+	 * admin_notices
444
+	 * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply to
445
+	 * all pages/views loaded by child class.
446
+	 *
447
+	 * @abstract
448
+	 * @return void
449
+	 */
450
+	abstract public function admin_notices();
451
+
452
+
453
+	/**
454
+	 * admin_footer_scripts
455
+	 * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
456
+	 * will apply to all pages/views loaded by child class.
457
+	 *
458
+	 * @return void
459
+	 */
460
+	abstract public function admin_footer_scripts();
461
+
462
+
463
+	/**
464
+	 * admin_footer
465
+	 * anything triggered by the 'admin_footer' WP action hook should be added to here. This particular method will
466
+	 * apply to all pages/views loaded by child class.
467
+	 *
468
+	 * @return void
469
+	 */
470
+	public function admin_footer()
471
+	{
472
+	}
473
+
474
+
475
+	/**
476
+	 * _global_ajax_hooks
477
+	 * all global add_action('wp_ajax_{name_of_hook}') hooks in here.
478
+	 * Note: within the ajax callback methods.
479
+	 *
480
+	 * @abstract
481
+	 * @return void
482
+	 */
483
+	protected function _global_ajax_hooks()
484
+	{
485
+		// for lazy loading of metabox content
486
+		add_action('wp_ajax_espresso-ajax-content', array($this, 'ajax_metabox_content'), 10);
487
+	}
488
+
489
+
490
+	public function ajax_metabox_content()
491
+	{
492
+		$contentid = isset($this->_req_data['contentid']) ? $this->_req_data['contentid'] : '';
493
+		$url = isset($this->_req_data['contenturl']) ? $this->_req_data['contenturl'] : '';
494
+		EE_Admin_Page::cached_rss_display($contentid, $url);
495
+		wp_die();
496
+	}
497
+
498
+
499
+	/**
500
+	 * _page_setup
501
+	 * Makes sure any things that need to be loaded early get handled.  We also escape early here if the page requested
502
+	 * doesn't match the object.
503
+	 *
504
+	 * @final
505
+	 * @return void
506
+	 * @throws EE_Error
507
+	 * @throws InvalidArgumentException
508
+	 * @throws ReflectionException
509
+	 * @throws InvalidDataTypeException
510
+	 * @throws InvalidInterfaceException
511
+	 */
512
+	final protected function _page_setup()
513
+	{
514
+		// requires?
515
+		// admin_init stuff - global - we're setting this REALLY early
516
+		// so if EE_Admin pages have to hook into other WP pages they can.
517
+		// But keep in mind, not everything is available from the EE_Admin Page object at this point.
518
+		add_action('admin_init', array($this, 'admin_init_global'), 5);
519
+		// next verify if we need to load anything...
520
+		$this->_current_page = ! empty($_GET['page']) ? sanitize_key($_GET['page']) : '';
521
+		$this->page_folder = strtolower(
522
+			str_replace(array('_Admin_Page', 'Extend_'), '', get_class($this))
523
+		);
524
+		global $ee_menu_slugs;
525
+		$ee_menu_slugs = (array) $ee_menu_slugs;
526
+		if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[ $this->_current_page ]))) {
527
+			return;
528
+		}
529
+		// becuz WP List tables have two duplicate select inputs for choosing bulk actions, we need to copy the action from the second to the first
530
+		if (isset($this->_req_data['action2']) && $this->_req_data['action'] === '-1') {
531
+			$this->_req_data['action'] = ! empty($this->_req_data['action2']) && $this->_req_data['action2'] !== '-1'
532
+				? $this->_req_data['action2']
533
+				: $this->_req_data['action'];
534
+		}
535
+		// then set blank or -1 action values to 'default'
536
+		$this->_req_action = isset($this->_req_data['action'])
537
+							 && ! empty($this->_req_data['action'])
538
+							 && $this->_req_data['action'] !== '-1'
539
+			? sanitize_key($this->_req_data['action'])
540
+			: 'default';
541
+		// if action is 'default' after the above BUT we have  'route' var set, then let's use the route as the action.
542
+		//  This covers cases where we're coming in from a list table that isn't on the default route.
543
+		$this->_req_action = $this->_req_action === 'default' && isset($this->_req_data['route'])
544
+			? $this->_req_data['route'] : $this->_req_action;
545
+		// however if we are doing_ajax and we've got a 'route' set then that's what the req_action will be
546
+		$this->_req_action = defined('DOING_AJAX') && isset($this->_req_data['route'])
547
+			? $this->_req_data['route']
548
+			: $this->_req_action;
549
+		$this->_current_view = $this->_req_action;
550
+		$this->_req_nonce = $this->_req_action . '_nonce';
551
+		$this->_define_page_props();
552
+		$this->_current_page_view_url = add_query_arg(
553
+			array('page' => $this->_current_page, 'action' => $this->_current_view),
554
+			$this->_admin_base_url
555
+		);
556
+		// default things
557
+		$this->_default_espresso_metaboxes = array(
558
+			'_espresso_news_post_box',
559
+			'_espresso_links_post_box',
560
+			'_espresso_ratings_request',
561
+			'_espresso_sponsors_post_box',
562
+		);
563
+		// set page configs
564
+		$this->_set_page_routes();
565
+		$this->_set_page_config();
566
+		// let's include any referrer data in our default_query_args for this route for "stickiness".
567
+		if (isset($this->_req_data['wp_referer'])) {
568
+			$this->_default_route_query_args['wp_referer'] = $this->_req_data['wp_referer'];
569
+		}
570
+		// for caffeinated and other extended functionality.
571
+		//  If there is a _extend_page_config method
572
+		// then let's run that to modify the all the various page configuration arrays
573
+		if (method_exists($this, '_extend_page_config')) {
574
+			$this->_extend_page_config();
575
+		}
576
+		// for CPT and other extended functionality.
577
+		// If there is an _extend_page_config_for_cpt
578
+		// then let's run that to modify all the various page configuration arrays.
579
+		if (method_exists($this, '_extend_page_config_for_cpt')) {
580
+			$this->_extend_page_config_for_cpt();
581
+		}
582
+		// filter routes and page_config so addons can add their stuff. Filtering done per class
583
+		$this->_page_routes = apply_filters(
584
+			'FHEE__' . get_class($this) . '__page_setup__page_routes',
585
+			$this->_page_routes,
586
+			$this
587
+		);
588
+		$this->_page_config = apply_filters(
589
+			'FHEE__' . get_class($this) . '__page_setup__page_config',
590
+			$this->_page_config,
591
+			$this
592
+		);
593
+		// if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present
594
+		// then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action
595
+		if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)) {
596
+			add_action(
597
+				'AHEE__EE_Admin_Page__route_admin_request',
598
+				array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view),
599
+				10,
600
+				2
601
+			);
602
+		}
603
+		// next route only if routing enabled
604
+		if ($this->_routing && ! defined('DOING_AJAX')) {
605
+			$this->_verify_routes();
606
+			// next let's just check user_access and kill if no access
607
+			$this->check_user_access();
608
+			if ($this->_is_UI_request) {
609
+				// admin_init stuff - global, all views for this page class, specific view
610
+				add_action('admin_init', array($this, 'admin_init'), 10);
611
+				if (method_exists($this, 'admin_init_' . $this->_current_view)) {
612
+					add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15);
613
+				}
614
+			} else {
615
+				// hijack regular WP loading and route admin request immediately
616
+				@ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
617
+				$this->route_admin_request();
618
+			}
619
+		}
620
+	}
621
+
622
+
623
+	/**
624
+	 * Provides a way for related child admin pages to load stuff on the loaded admin page.
625
+	 *
626
+	 * @return void
627
+	 * @throws EE_Error
628
+	 */
629
+	private function _do_other_page_hooks()
630
+	{
631
+		$registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array());
632
+		foreach ($registered_pages as $page) {
633
+			// now let's setup the file name and class that should be present
634
+			$classname = str_replace('.class.php', '', $page);
635
+			// autoloaders should take care of loading file
636
+			if (! class_exists($classname)) {
637
+				$error_msg[] = sprintf(
638
+					esc_html__(
639
+						'Something went wrong with loading the %s admin hooks page.',
640
+						'event_espresso'
641
+					),
642
+					$page
643
+				);
644
+				$error_msg[] = $error_msg[0]
645
+							   . "\r\n"
646
+							   . sprintf(
647
+								   esc_html__(
648
+									   'There is no class in place for the %1$s admin hooks page.%2$sMake sure you have %3$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
649
+									   'event_espresso'
650
+								   ),
651
+								   $page,
652
+								   '<br />',
653
+								   '<strong>' . $classname . '</strong>'
654
+							   );
655
+				throw new EE_Error(implode('||', $error_msg));
656
+			}
657
+			// // notice we are passing the instance of this class to the hook object.
658
+			$this->loader->getShared($classname, [$this]);
659
+		}
660
+	}
661
+
662
+
663
+	/**
664
+	 * @throws DomainException
665
+	 * @throws EE_Error
666
+	 * @throws InvalidArgumentException
667
+	 * @throws InvalidDataTypeException
668
+	 * @throws InvalidInterfaceException
669
+	 * @throws ReflectionException
670
+	 * @since $VID:$
671
+	 */
672
+	public function load_page_dependencies()
673
+	{
674
+		try {
675
+			$this->_load_page_dependencies();
676
+		} catch (EE_Error $e) {
677
+			$e->get_error();
678
+		}
679
+	}
680
+
681
+
682
+	/**
683
+	 * load_page_dependencies
684
+	 * loads things specific to this page class when its loaded.  Really helps with efficiency.
685
+	 *
686
+	 * @return void
687
+	 * @throws DomainException
688
+	 * @throws EE_Error
689
+	 * @throws InvalidArgumentException
690
+	 * @throws InvalidDataTypeException
691
+	 * @throws InvalidInterfaceException
692
+	 * @throws ReflectionException
693
+	 */
694
+	protected function _load_page_dependencies()
695
+	{
696
+		// let's set the current_screen and screen options to override what WP set
697
+		$this->_current_screen = get_current_screen();
698
+		// load admin_notices - global, page class, and view specific
699
+		add_action('admin_notices', array($this, 'admin_notices_global'), 5);
700
+		add_action('admin_notices', array($this, 'admin_notices'), 10);
701
+		if (method_exists($this, 'admin_notices_' . $this->_current_view)) {
702
+			add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15);
703
+		}
704
+		// load network admin_notices - global, page class, and view specific
705
+		add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5);
706
+		if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) {
707
+			add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view));
708
+		}
709
+		// this will save any per_page screen options if they are present
710
+		$this->_set_per_page_screen_options();
711
+		// setup list table properties
712
+		$this->_set_list_table();
713
+		// child classes can "register" a metabox to be automatically handled via the _page_config array property.
714
+		// However in some cases the metaboxes will need to be added within a route handling callback.
715
+		$this->_add_registered_meta_boxes();
716
+		$this->_add_screen_columns();
717
+		// add screen options - global, page child class, and view specific
718
+		$this->_add_global_screen_options();
719
+		$this->_add_screen_options();
720
+		$add_screen_options = "_add_screen_options_{$this->_current_view}";
721
+		if (method_exists($this, $add_screen_options)) {
722
+			$this->{$add_screen_options}();
723
+		}
724
+		// add help tab(s) and tours- set via page_config and qtips.
725
+		$this->_add_help_tour();
726
+		$this->_add_help_tabs();
727
+		$this->_add_qtips();
728
+		// add feature_pointers - global, page child class, and view specific
729
+		$this->_add_feature_pointers();
730
+		$this->_add_global_feature_pointers();
731
+		$add_feature_pointer = "_add_feature_pointer_{$this->_current_view}";
732
+		if (method_exists($this, $add_feature_pointer)) {
733
+			$this->{$add_feature_pointer}();
734
+		}
735
+		// enqueue scripts/styles - global, page class, and view specific
736
+		add_action('admin_enqueue_scripts', array($this, 'load_global_scripts_styles'), 5);
737
+		add_action('admin_enqueue_scripts', array($this, 'load_scripts_styles'), 10);
738
+		if (method_exists($this, "load_scripts_styles_{$this->_current_view}")) {
739
+			add_action('admin_enqueue_scripts', array($this, "load_scripts_styles_{$this->_current_view}"), 15);
740
+		}
741
+		add_action('admin_enqueue_scripts', array($this, 'admin_footer_scripts_eei18n_js_strings'), 100);
742
+		// admin_print_footer_scripts - global, page child class, and view specific.
743
+		// NOTE, despite the name, whenever possible, scripts should NOT be loaded using this.
744
+		// In most cases that's doing_it_wrong().  But adding hidden container elements etc.
745
+		// is a good use case. Notice the late priority we're giving these
746
+		add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts_global'), 99);
747
+		add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts'), 100);
748
+		if (method_exists($this, "admin_footer_scripts_{$this->_current_view}")) {
749
+			add_action('admin_print_footer_scripts', array($this, "admin_footer_scripts_{$this->_current_view}"), 101);
750
+		}
751
+		// admin footer scripts
752
+		add_action('admin_footer', array($this, 'admin_footer_global'), 99);
753
+		add_action('admin_footer', array($this, 'admin_footer'), 100);
754
+		if (method_exists($this, "admin_footer_{$this->_current_view}")) {
755
+			add_action('admin_footer', array($this, "admin_footer_{$this->_current_view}"), 101);
756
+		}
757
+		do_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', $this->page_slug);
758
+		// targeted hook
759
+		do_action(
760
+			"FHEE__EE_Admin_Page___load_page_dependencies__after_load__{$this->page_slug}__{$this->_req_action}"
761
+		);
762
+	}
763
+
764
+
765
+	/**
766
+	 * _set_defaults
767
+	 * This sets some global defaults for class properties.
768
+	 */
769
+	private function _set_defaults()
770
+	{
771
+		$this->_current_screen = $this->_admin_page_title = $this->_req_action = $this->_req_nonce = null;
772
+		$this->_event = $this->_template_path = $this->_column_template_path = null;
773
+		$this->_nav_tabs = $this->_views = $this->_page_routes = array();
774
+		$this->_page_config = $this->_default_route_query_args = array();
775
+		$this->_default_nav_tab_name = 'overview';
776
+		// init template args
777
+		$this->_template_args = array(
778
+			'admin_page_header'  => '',
779
+			'admin_page_content' => '',
780
+			'post_body_content'  => '',
781
+			'before_list_table'  => '',
782
+			'after_list_table'   => '',
783
+		);
784
+	}
785
+
786
+
787
+	/**
788
+	 * route_admin_request
789
+	 *
790
+	 * @see    _route_admin_request()
791
+	 * @return exception|void error
792
+	 * @throws InvalidArgumentException
793
+	 * @throws InvalidInterfaceException
794
+	 * @throws InvalidDataTypeException
795
+	 * @throws EE_Error
796
+	 * @throws ReflectionException
797
+	 */
798
+	public function route_admin_request()
799
+	{
800
+		try {
801
+			$this->_route_admin_request();
802
+		} catch (EE_Error $e) {
803
+			$e->get_error();
804
+		}
805
+	}
806
+
807
+
808
+	public function set_wp_page_slug($wp_page_slug)
809
+	{
810
+		$this->_wp_page_slug = $wp_page_slug;
811
+		// if in network admin then we need to append "-network" to the page slug. Why? Because that's how WP rolls...
812
+		if (is_network_admin()) {
813
+			$this->_wp_page_slug .= '-network';
814
+		}
815
+	}
816
+
817
+
818
+	/**
819
+	 * _verify_routes
820
+	 * All this method does is verify the incoming request and make sure that routes exist for it.  We do this early so
821
+	 * we know if we need to drop out.
822
+	 *
823
+	 * @return bool
824
+	 * @throws EE_Error
825
+	 */
826
+	protected function _verify_routes()
827
+	{
828
+		if (! $this->_current_page && ! defined('DOING_AJAX')) {
829
+			return false;
830
+		}
831
+		$this->_route = false;
832
+		// check that the page_routes array is not empty
833
+		if (empty($this->_page_routes)) {
834
+			// user error msg
835
+			$error_msg = sprintf(
836
+				esc_html__('No page routes have been set for the %s admin page.', 'event_espresso'),
837
+				$this->_admin_page_title
838
+			);
839
+			// developer error msg
840
+			$error_msg .= '||' . $error_msg
841
+						  . esc_html__(
842
+							  ' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.',
843
+							  'event_espresso'
844
+						  );
845
+			throw new EE_Error($error_msg);
846
+		}
847
+		// and that the requested page route exists
848
+		if (array_key_exists($this->_req_action, $this->_page_routes)) {
849
+			$this->_route = $this->_page_routes[ $this->_req_action ];
850
+			$this->_route_config = isset($this->_page_config[ $this->_req_action ])
851
+				? $this->_page_config[ $this->_req_action ] : array();
852
+		} else {
853
+			// user error msg
854
+			$error_msg = sprintf(
855
+				esc_html__(
856
+					'The requested page route does not exist for the %s admin page.',
857
+					'event_espresso'
858
+				),
859
+				$this->_admin_page_title
860
+			);
861
+			// developer error msg
862
+			$error_msg .= '||' . $error_msg
863
+						  . sprintf(
864
+							  esc_html__(
865
+								  ' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.',
866
+								  'event_espresso'
867
+							  ),
868
+							  $this->_req_action
869
+						  );
870
+			throw new EE_Error($error_msg);
871
+		}
872
+		// and that a default route exists
873
+		if (! array_key_exists('default', $this->_page_routes)) {
874
+			// user error msg
875
+			$error_msg = sprintf(
876
+				esc_html__(
877
+					'A default page route has not been set for the % admin page.',
878
+					'event_espresso'
879
+				),
880
+				$this->_admin_page_title
881
+			);
882
+			// developer error msg
883
+			$error_msg .= '||' . $error_msg
884
+						  . esc_html__(
885
+							  ' Create a key in the "_page_routes" array named "default" and set its value to your default page method.',
886
+							  'event_espresso'
887
+						  );
888
+			throw new EE_Error($error_msg);
889
+		}
890
+
891
+		// first lets' catch if the UI request has EVER been set.
892
+		if ($this->_is_UI_request === null) {
893
+			// lets set if this is a UI request or not.
894
+			$this->_is_UI_request = ! isset($this->_req_data['noheader']) || $this->_req_data['noheader'] !== true;
895
+			// wait a minute... we might have a noheader in the route array
896
+			$this->_is_UI_request = is_array($this->_route)
897
+									&& isset($this->_route['noheader'])
898
+									&& $this->_route['noheader'] ? false : $this->_is_UI_request;
899
+		}
900
+		$this->_set_current_labels();
901
+		return true;
902
+	}
903
+
904
+
905
+	/**
906
+	 * this method simply verifies a given route and makes sure its an actual route available for the loaded page
907
+	 *
908
+	 * @param  string $route the route name we're verifying
909
+	 * @return mixed (bool|Exception)      we'll throw an exception if this isn't a valid route.
910
+	 * @throws EE_Error
911
+	 */
912
+	protected function _verify_route($route)
913
+	{
914
+		if (array_key_exists($this->_req_action, $this->_page_routes)) {
915
+			return true;
916
+		}
917
+		// user error msg
918
+		$error_msg = sprintf(
919
+			esc_html__('The given page route does not exist for the %s admin page.', 'event_espresso'),
920
+			$this->_admin_page_title
921
+		);
922
+		// developer error msg
923
+		$error_msg .= '||' . $error_msg
924
+					  . sprintf(
925
+						  esc_html__(
926
+							  ' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property',
927
+							  'event_espresso'
928
+						  ),
929
+						  $route
930
+					  );
931
+		throw new EE_Error($error_msg);
932
+	}
933
+
934
+
935
+	/**
936
+	 * perform nonce verification
937
+	 * This method has be encapsulated here so that any ajax requests that bypass normal routes can verify their nonces
938
+	 * using this method (and save retyping!)
939
+	 *
940
+	 * @param string $nonce     The nonce sent
941
+	 * @param string $nonce_ref The nonce reference string (name0)
942
+	 * @return void
943
+	 * @throws EE_Error
944
+	 * @throws InvalidArgumentException
945
+	 * @throws InvalidDataTypeException
946
+	 * @throws InvalidInterfaceException
947
+	 */
948
+	protected function _verify_nonce($nonce, $nonce_ref)
949
+	{
950
+		// verify nonce against expected value
951
+		if (! wp_verify_nonce($nonce, $nonce_ref)) {
952
+			// these are not the droids you are looking for !!!
953
+			$msg = sprintf(
954
+				esc_html__('%sNonce Fail.%s', 'event_espresso'),
955
+				'<a href="http://www.youtube.com/watch?v=56_S0WeTkzs">',
956
+				'</a>'
957
+			);
958
+			if (WP_DEBUG) {
959
+				$msg .= "\n  "
960
+						. sprintf(
961
+							esc_html__(
962
+								'In order to dynamically generate nonces for your actions, use the %s::add_query_args_and_nonce() method. May the Nonce be with you!',
963
+								'event_espresso'
964
+							),
965
+							EE_Admin_Page::class
966
+						);
967
+			}
968
+			if (! defined('DOING_AJAX')) {
969
+				wp_die($msg);
970
+			} else {
971
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
972
+				$this->_return_json();
973
+			}
974
+		}
975
+	}
976
+
977
+
978
+	/**
979
+	 * _route_admin_request()
980
+	 * Meat and potatoes of the class.  Basically, this dude checks out what's being requested and sees if there are
981
+	 * some doodads to work the magic and handle the flingjangy. Translation:  Checks if the requested action is listed
982
+	 * in the page routes and then will try to load the corresponding method.
983
+	 *
984
+	 * @return void
985
+	 * @throws EE_Error
986
+	 * @throws InvalidArgumentException
987
+	 * @throws InvalidDataTypeException
988
+	 * @throws InvalidInterfaceException
989
+	 * @throws ReflectionException
990
+	 */
991
+	protected function _route_admin_request()
992
+	{
993
+		if (! $this->_is_UI_request) {
994
+			$this->_verify_routes();
995
+		}
996
+		$nonce_check = isset($this->_route_config['require_nonce'])
997
+			? $this->_route_config['require_nonce']
998
+			: true;
999
+		if ($this->_req_action !== 'default' && $nonce_check) {
1000
+			// set nonce from post data
1001
+			$nonce = isset($this->_req_data[ $this->_req_nonce ])
1002
+				? sanitize_text_field($this->_req_data[ $this->_req_nonce ])
1003
+				: '';
1004
+			$this->_verify_nonce($nonce, $this->_req_nonce);
1005
+		}
1006
+		// set the nav_tabs array but ONLY if this is  UI_request
1007
+		if ($this->_is_UI_request) {
1008
+			$this->_set_nav_tabs();
1009
+		}
1010
+		// grab callback function
1011
+		$func = is_array($this->_route) && isset($this->_route['func']) ? $this->_route['func'] : $this->_route;
1012
+		// check if callback has args
1013
+		$args = is_array($this->_route) && isset($this->_route['args']) ? $this->_route['args'] : array();
1014
+		$error_msg = '';
1015
+		// action right before calling route
1016
+		// (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request')
1017
+		if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
1018
+			do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this);
1019
+		}
1020
+		// right before calling the route, let's remove _wp_http_referer from the
1021
+		// $_SERVER[REQUEST_URI] global (its now in _req_data for route processing).
1022
+		$_SERVER['REQUEST_URI'] = remove_query_arg(
1023
+			'_wp_http_referer',
1024
+			wp_unslash($_SERVER['REQUEST_URI'])
1025
+		);
1026
+		if (! empty($func)) {
1027
+			if (is_array($func)) {
1028
+				list($class, $method) = $func;
1029
+			} elseif (strpos($func, '::') !== false) {
1030
+				list($class, $method) = explode('::', $func);
1031
+			} else {
1032
+				$class = $this;
1033
+				$method = $func;
1034
+			}
1035
+			if (! (is_object($class) && $class === $this)) {
1036
+				// send along this admin page object for access by addons.
1037
+				$args['admin_page_object'] = $this;
1038
+			}
1039
+			// is it a method on a class that doesn't work?
1040
+			if (((method_exists($class, $method)
1041
+				  && call_user_func_array(array($class, $method), $args) === false)
1042
+				 && (// is it a standalone function that doesn't work?
1043
+					 function_exists($method)
1044
+					 && call_user_func_array(
1045
+						 $func,
1046
+						 array_merge(array('admin_page_object' => $this), $args)
1047
+					 ) === false
1048
+				 )) || (// is it neither a class method NOR a standalone function?
1049
+					! function_exists($method)
1050
+					&& ! method_exists($class, $method)
1051
+				)
1052
+			) {
1053
+				// user error msg
1054
+				$error_msg = esc_html__(
1055
+					'An error occurred. The  requested page route could not be found.',
1056
+					'event_espresso'
1057
+				);
1058
+				// developer error msg
1059
+				$error_msg .= '||';
1060
+				$error_msg .= sprintf(
1061
+					esc_html__(
1062
+						'Page route "%s" could not be called. Check that the spelling for method names and actions in the "_page_routes" array are all correct.',
1063
+						'event_espresso'
1064
+					),
1065
+					$method
1066
+				);
1067
+			}
1068
+			if (! empty($error_msg)) {
1069
+				throw new EE_Error($error_msg);
1070
+			}
1071
+		}
1072
+		// if we've routed and this route has a no headers route AND a sent_headers_route,
1073
+		// then we need to reset the routing properties to the new route.
1074
+		// now if UI request is FALSE and noheader is true AND we have a headers_sent_route in the route array then let's set UI_request to true because the no header route has a second func after headers have been sent.
1075
+		if ($this->_is_UI_request === false
1076
+			&& is_array($this->_route)
1077
+			&& ! empty($this->_route['headers_sent_route'])
1078
+		) {
1079
+			$this->_reset_routing_properties($this->_route['headers_sent_route']);
1080
+		}
1081
+	}
1082
+
1083
+
1084
+	/**
1085
+	 * This method just allows the resetting of page properties in the case where a no headers
1086
+	 * route redirects to a headers route in its route config.
1087
+	 *
1088
+	 * @since   4.3.0
1089
+	 * @param  string $new_route New (non header) route to redirect to.
1090
+	 * @return   void
1091
+	 * @throws ReflectionException
1092
+	 * @throws InvalidArgumentException
1093
+	 * @throws InvalidInterfaceException
1094
+	 * @throws InvalidDataTypeException
1095
+	 * @throws EE_Error
1096
+	 */
1097
+	protected function _reset_routing_properties($new_route)
1098
+	{
1099
+		$this->_is_UI_request = true;
1100
+		// now we set the current route to whatever the headers_sent_route is set at
1101
+		$this->_req_data['action'] = $new_route;
1102
+		// rerun page setup
1103
+		$this->_page_setup();
1104
+	}
1105
+
1106
+
1107
+	/**
1108
+	 * _add_query_arg
1109
+	 * adds nonce to array of arguments then calls WP add_query_arg function
1110
+	 *(internally just uses EEH_URL's function with the same name)
1111
+	 *
1112
+	 * @param array  $args
1113
+	 * @param string $url
1114
+	 * @param bool   $sticky                  if true, then the existing Request params will be appended to the
1115
+	 *                                        generated url in an associative array indexed by the key 'wp_referer';
1116
+	 *                                        Example usage: If the current page is:
1117
+	 *                                        http://mydomain.com/wp-admin/admin.php?page=espresso_registrations
1118
+	 *                                        &action=default&event_id=20&month_range=March%202015
1119
+	 *                                        &_wpnonce=5467821
1120
+	 *                                        and you call:
1121
+	 *                                        EE_Admin_Page::add_query_args_and_nonce(
1122
+	 *                                        array(
1123
+	 *                                        'action' => 'resend_something',
1124
+	 *                                        'page=>espresso_registrations'
1125
+	 *                                        ),
1126
+	 *                                        $some_url,
1127
+	 *                                        true
1128
+	 *                                        );
1129
+	 *                                        It will produce a url in this structure:
1130
+	 *                                        http://{$some_url}/?page=espresso_registrations&action=resend_something
1131
+	 *                                        &wp_referer[action]=default&wp_referer[event_id]=20&wpreferer[
1132
+	 *                                        month_range]=March%202015
1133
+	 * @param   bool $exclude_nonce           If true, the the nonce will be excluded from the generated nonce.
1134
+	 * @return string
1135
+	 */
1136
+	public static function add_query_args_and_nonce(
1137
+		$args = array(),
1138
+		$url = '',
1139
+		$sticky = false,
1140
+		$exclude_nonce = false
1141
+	) {
1142
+		// if there is a _wp_http_referer include the values from the request but only if sticky = true
1143
+		if ($sticky) {
1144
+			$request = $_REQUEST;
1145
+			unset($request['_wp_http_referer'], $request['wp_referer']);
1146
+			foreach ($request as $key => $value) {
1147
+				// do not add nonces
1148
+				if (strpos($key, 'nonce') !== false) {
1149
+					continue;
1150
+				}
1151
+				$args[ 'wp_referer[' . $key . ']' ] = $value;
1152
+			}
1153
+		}
1154
+		return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce);
1155
+	}
1156
+
1157
+
1158
+	/**
1159
+	 * This returns a generated link that will load the related help tab.
1160
+	 *
1161
+	 * @param  string $help_tab_id the id for the connected help tab
1162
+	 * @param  string $icon_style  (optional) include css class for the style you want to use for the help icon.
1163
+	 * @param  string $help_text   (optional) send help text you want to use for the link if default not to be used
1164
+	 * @uses EEH_Template::get_help_tab_link()
1165
+	 * @return string              generated link
1166
+	 */
1167
+	protected function _get_help_tab_link($help_tab_id, $icon_style = '', $help_text = '')
1168
+	{
1169
+		return EEH_Template::get_help_tab_link(
1170
+			$help_tab_id,
1171
+			$this->page_slug,
1172
+			$this->_req_action,
1173
+			$icon_style,
1174
+			$help_text
1175
+		);
1176
+	}
1177
+
1178
+
1179
+	/**
1180
+	 * _add_help_tabs
1181
+	 * Note child classes define their help tabs within the page_config array.
1182
+	 *
1183
+	 * @link   http://codex.wordpress.org/Function_Reference/add_help_tab
1184
+	 * @return void
1185
+	 * @throws DomainException
1186
+	 * @throws EE_Error
1187
+	 * @throws ReflectionException
1188
+	 */
1189
+	protected function _add_help_tabs()
1190
+	{
1191
+		$tour_buttons = '';
1192
+		if (isset($this->_page_config[ $this->_req_action ])) {
1193
+			$config = $this->_page_config[ $this->_req_action ];
1194
+			// is there a help tour for the current route?  if there is let's setup the tour buttons
1195
+			if (isset($this->_help_tour[ $this->_req_action ])) {
1196
+				$tb = array();
1197
+				$tour_buttons = '<div class="ee-abs-container"><div class="ee-help-tour-restart-buttons">';
1198
+				foreach ($this->_help_tour['tours'] as $tour) {
1199
+					// if this is the end tour then we don't need to setup a button
1200
+					if ($tour instanceof EE_Help_Tour_final_stop || ! $tour instanceof EE_Help_Tour) {
1201
+						continue;
1202
+					}
1203
+					$tb[] = '<button id="trigger-tour-'
1204
+							. $tour->get_slug()
1205
+							. '" class="button-primary trigger-ee-help-tour">'
1206
+							. $tour->get_label()
1207
+							. '</button>';
1208
+				}
1209
+				$tour_buttons .= implode('<br />', $tb);
1210
+				$tour_buttons .= '</div></div>';
1211
+			}
1212
+			// let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well.
1213
+			if (is_array($config) && isset($config['help_sidebar'])) {
1214
+				// check that the callback given is valid
1215
+				if (! method_exists($this, $config['help_sidebar'])) {
1216
+					throw new EE_Error(
1217
+						sprintf(
1218
+							esc_html__(
1219
+								'The _page_config array has a callback set for the "help_sidebar" option.  However the callback given (%s) is not a valid callback.  Doublecheck the spelling and make sure this method exists for the class %s',
1220
+								'event_espresso'
1221
+							),
1222
+							$config['help_sidebar'],
1223
+							get_class($this)
1224
+						)
1225
+					);
1226
+				}
1227
+				$content = apply_filters(
1228
+					'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar',
1229
+					$this->{$config['help_sidebar']}()
1230
+				);
1231
+				$content .= $tour_buttons; // add help tour buttons.
1232
+				// do we have any help tours setup?  Cause if we do we want to add the buttons
1233
+				$this->_current_screen->set_help_sidebar($content);
1234
+			}
1235
+			// if there ARE tour buttons...
1236
+			if (! empty($tour_buttons)) {
1237
+				// if we DON'T have config help sidebar then we'll just add the tour buttons to the sidebar.
1238
+				if (! isset($config['help_sidebar'])) {
1239
+					$this->_current_screen->set_help_sidebar($tour_buttons);
1240
+				}
1241
+				// handle if no help_tabs are set so the sidebar will still show for the help tour buttons
1242
+				if (! isset($config['help_tabs'])) {
1243
+					$_ht['id'] = $this->page_slug;
1244
+					$_ht['title'] = esc_html__('Help Tours', 'event_espresso');
1245
+					$_ht['content'] = '<p>'
1246
+									  . esc_html__(
1247
+										  'The buttons to the right allow you to start/restart any help tours available for this page',
1248
+										  'event_espresso'
1249
+									  ) . '</p>';
1250
+					$this->_current_screen->add_help_tab($_ht);
1251
+				}
1252
+			}
1253
+			if (! isset($config['help_tabs'])) {
1254
+				return;
1255
+			} //no help tabs for this route
1256
+			foreach ((array) $config['help_tabs'] as $tab_id => $cfg) {
1257
+				// we're here so there ARE help tabs!
1258
+				// make sure we've got what we need
1259
+				if (! isset($cfg['title'])) {
1260
+					throw new EE_Error(
1261
+						esc_html__(
1262
+							'The _page_config array is not set up properly for help tabs.  It is missing a title',
1263
+							'event_espresso'
1264
+						)
1265
+					);
1266
+				}
1267
+				if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1268
+					throw new EE_Error(
1269
+						esc_html__(
1270
+							'The _page_config array is not setup properly for help tabs. It is missing a either a filename reference, or a callback reference or a content reference so there is no way to know the content for the help tab',
1271
+							'event_espresso'
1272
+						)
1273
+					);
1274
+				}
1275
+				// first priority goes to content.
1276
+				if (! empty($cfg['content'])) {
1277
+					$content = ! empty($cfg['content']) ? $cfg['content'] : null;
1278
+					// second priority goes to filename
1279
+				} elseif (! empty($cfg['filename'])) {
1280
+					$file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php';
1281
+					// it's possible that the file is located on decaf route (and above sets up for caf route, if this is the case then lets check decaf route too)
1282
+					$file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1283
+															 . basename($this->_get_dir())
1284
+															 . '/help_tabs/'
1285
+															 . $cfg['filename']
1286
+															 . '.help_tab.php' : $file_path;
1287
+					// if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1288
+					if (! isset($cfg['callback']) && ! is_readable($file_path)) {
1289
+						EE_Error::add_error(
1290
+							sprintf(
1291
+								esc_html__(
1292
+									'The filename given for the help tab %s is not a valid file and there is no other configuration for the tab content.  Please check that the string you set for the help tab on this route (%s) is the correct spelling.  The file should be in %s',
1293
+									'event_espresso'
1294
+								),
1295
+								$tab_id,
1296
+								key($config),
1297
+								$file_path
1298
+							),
1299
+							__FILE__,
1300
+							__FUNCTION__,
1301
+							__LINE__
1302
+						);
1303
+						return;
1304
+					}
1305
+					$template_args['admin_page_obj'] = $this;
1306
+					$content = EEH_Template::display_template(
1307
+						$file_path,
1308
+						$template_args,
1309
+						true
1310
+					);
1311
+				} else {
1312
+					$content = '';
1313
+				}
1314
+				// check if callback is valid
1315
+				if (empty($content) && (
1316
+						! isset($cfg['callback']) || ! method_exists($this, $cfg['callback'])
1317
+					)
1318
+				) {
1319
+					EE_Error::add_error(
1320
+						sprintf(
1321
+							esc_html__(
1322
+								'The callback given for a %s help tab on this page does not content OR a corresponding method for generating the content.  Check the spelling or make sure the method is present.',
1323
+								'event_espresso'
1324
+							),
1325
+							$cfg['title']
1326
+						),
1327
+						__FILE__,
1328
+						__FUNCTION__,
1329
+						__LINE__
1330
+					);
1331
+					return;
1332
+				}
1333
+				// setup config array for help tab method
1334
+				$id = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id;
1335
+				$_ht = array(
1336
+					'id'       => $id,
1337
+					'title'    => $cfg['title'],
1338
+					'callback' => isset($cfg['callback']) && empty($content) ? array($this, $cfg['callback']) : null,
1339
+					'content'  => $content,
1340
+				);
1341
+				$this->_current_screen->add_help_tab($_ht);
1342
+			}
1343
+		}
1344
+	}
1345
+
1346
+
1347
+	/**
1348
+	 * This basically checks loaded $_page_config property to see if there are any help_tours defined.  "help_tours" is
1349
+	 * an array with properties for setting up usage of the joyride plugin
1350
+	 *
1351
+	 * @link   http://zurb.com/playground/jquery-joyride-feature-tour-plugin
1352
+	 * @see    instructions regarding the format and construction of the "help_tour" array element is found in the
1353
+	 *         _set_page_config() comments
1354
+	 * @return void
1355
+	 * @throws EE_Error
1356
+	 * @throws InvalidArgumentException
1357
+	 * @throws InvalidDataTypeException
1358
+	 * @throws InvalidInterfaceException
1359
+	 * @throws ReflectionException
1360
+	 */
1361
+	protected function _add_help_tour()
1362
+	{
1363
+		$tours = array();
1364
+		$this->_help_tour = array();
1365
+		// exit early if help tours are turned off globally
1366
+		if ((defined('EE_DISABLE_HELP_TOURS') && EE_DISABLE_HELP_TOURS)
1367
+			|| ! EE_Registry::instance()->CFG->admin->help_tour_activation
1368
+		) {
1369
+			return;
1370
+		}
1371
+		// loop through _page_config to find any help_tour defined
1372
+		foreach ($this->_page_config as $route => $config) {
1373
+			// we're only going to set things up for this route
1374
+			if ($route !== $this->_req_action) {
1375
+				continue;
1376
+			}
1377
+			if (isset($config['help_tour'])) {
1378
+				foreach ($config['help_tour'] as $tour) {
1379
+					$file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php';
1380
+					// let's see if we can get that file...
1381
+					// if not its possible this is a decaf route not set in caffeinated
1382
+					// so lets try and get the caffeinated equivalent
1383
+					$file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1384
+															 . basename($this->_get_dir())
1385
+															 . '/help_tours/'
1386
+															 . $tour
1387
+															 . '.class.php' : $file_path;
1388
+					// if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1389
+					if (! is_readable($file_path)) {
1390
+						EE_Error::add_error(
1391
+							sprintf(
1392
+								esc_html__(
1393
+									'The file path given for the help tour (%s) is not a valid path.  Please check that the string you set for the help tour on this route (%s) is the correct spelling',
1394
+									'event_espresso'
1395
+								),
1396
+								$file_path,
1397
+								$tour
1398
+							),
1399
+							__FILE__,
1400
+							__FUNCTION__,
1401
+							__LINE__
1402
+						);
1403
+						return;
1404
+					}
1405
+					require_once $file_path;
1406
+					if (! class_exists($tour)) {
1407
+						$error_msg = [];
1408
+						$error_msg[] = sprintf(
1409
+							esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'),
1410
+							$tour
1411
+						);
1412
+						$error_msg[] = $error_msg[0] . "\r\n"
1413
+									   . sprintf(
1414
+										   esc_html__(
1415
+											   'There is no class in place for the %s help tour.%s Make sure you have <strong>%s</strong> defined in the "help_tour" array for the %s route of the % admin page.',
1416
+											   'event_espresso'
1417
+										   ),
1418
+										   $tour,
1419
+										   '<br />',
1420
+										   $tour,
1421
+										   $this->_req_action,
1422
+										   get_class($this)
1423
+									   );
1424
+						throw new EE_Error(implode('||', $error_msg));
1425
+					}
1426
+					$tour_obj = new $tour($this->_is_caf);
1427
+					$tours[] = $tour_obj;
1428
+					$this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($tour_obj);
1429
+				}
1430
+				// let's inject the end tour stop element common to all pages... this will only get seen once per machine.
1431
+				$end_stop_tour = new EE_Help_Tour_final_stop($this->_is_caf);
1432
+				$tours[] = $end_stop_tour;
1433
+				$this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($end_stop_tour);
1434
+			}
1435
+		}
1436
+
1437
+		if (! empty($tours)) {
1438
+			$this->_help_tour['tours'] = $tours;
1439
+		}
1440
+		// that's it!  Now that the $_help_tours property is set (or not)
1441
+		// the scripts and html should be taken care of automatically.
1442
+
1443
+		/**
1444
+		 * Allow extending the help tours variable.
1445
+		 *
1446
+		 * @param array $_help_tour The array containing all help tour information to be displayed.
1447
+		 */
1448
+		$this->_help_tour = apply_filters('FHEE__EE_Admin_Page___add_help_tour___help_tour', $this->_help_tour);
1449
+	}
1450
+
1451
+
1452
+	/**
1453
+	 * This simply sets up any qtips that have been defined in the page config
1454
+	 *
1455
+	 * @return void
1456
+	 * @throws ReflectionException
1457
+	 * @throws EE_Error
1458
+	 */
1459
+	protected function _add_qtips()
1460
+	{
1461
+		if (isset($this->_route_config['qtips'])) {
1462
+			$qtips = (array) $this->_route_config['qtips'];
1463
+			// load qtip loader
1464
+			$path = array(
1465
+				$this->_get_dir() . '/qtips/',
1466
+				EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/',
1467
+			);
1468
+			$qtip_loader = EEH_Qtip_Loader::instance();
1469
+			if ($qtip_loader instanceof EEH_Qtip_Loader) {
1470
+				$qtip_loader->register($qtips, $path);
1471
+			}
1472
+		}
1473
+	}
1474
+
1475
+
1476
+	/**
1477
+	 * _set_nav_tabs
1478
+	 * This sets up the nav tabs from the page_routes array.  This method can be overwritten by child classes if you
1479
+	 * wish to add additional tabs or modify accordingly.
1480
+	 *
1481
+	 * @return void
1482
+	 * @throws InvalidArgumentException
1483
+	 * @throws InvalidInterfaceException
1484
+	 * @throws InvalidDataTypeException
1485
+	 */
1486
+	protected function _set_nav_tabs()
1487
+	{
1488
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1489
+		$i = 0;
1490
+		foreach ($this->_page_config as $slug => $config) {
1491
+			if (! is_array($config)
1492
+				|| (
1493
+					is_array($config)
1494
+					&& (
1495
+						(isset($config['nav']) && ! $config['nav'])
1496
+						|| ! isset($config['nav'])
1497
+					)
1498
+				)
1499
+			) {
1500
+				continue;
1501
+			}
1502
+			// no nav tab for this config
1503
+			// check for persistent flag
1504
+			if ($slug !== $this->_req_action && isset($config['nav']['persistent']) && ! $config['nav']['persistent']) {
1505
+				// nav tab is only to appear when route requested.
1506
+				continue;
1507
+			}
1508
+			if (! $this->check_user_access($slug, true)) {
1509
+				// no nav tab because current user does not have access.
1510
+				continue;
1511
+			}
1512
+			$css_class = isset($config['css_class']) ? $config['css_class'] . ' ' : '';
1513
+			$this->_nav_tabs[ $slug ] = array(
1514
+				'url'       => isset($config['nav']['url'])
1515
+					? $config['nav']['url']
1516
+					: EE_Admin_Page::add_query_args_and_nonce(
1517
+						array('action' => $slug),
1518
+						$this->_admin_base_url
1519
+					),
1520
+				'link_text' => isset($config['nav']['label'])
1521
+					? $config['nav']['label']
1522
+					: ucwords(
1523
+						str_replace('_', ' ', $slug)
1524
+					),
1525
+				'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class,
1526
+				'order'     => isset($config['nav']['order']) ? $config['nav']['order'] : $i,
1527
+			);
1528
+			$i++;
1529
+		}
1530
+		// if $this->_nav_tabs is empty then lets set the default
1531
+		if (empty($this->_nav_tabs)) {
1532
+			$this->_nav_tabs[ $this->_default_nav_tab_name ] = array(
1533
+				'url'       => $this->_admin_base_url,
1534
+				'link_text' => ucwords(str_replace('_', ' ', $this->_default_nav_tab_name)),
1535
+				'css_class' => 'nav-tab-active',
1536
+				'order'     => 10,
1537
+			);
1538
+		}
1539
+		// now let's sort the tabs according to order
1540
+		usort($this->_nav_tabs, array($this, '_sort_nav_tabs'));
1541
+	}
1542
+
1543
+
1544
+	/**
1545
+	 * _set_current_labels
1546
+	 * This method modifies the _labels property with any optional specific labels indicated in the _page_routes
1547
+	 * property array
1548
+	 *
1549
+	 * @return void
1550
+	 */
1551
+	private function _set_current_labels()
1552
+	{
1553
+		if (is_array($this->_route_config) && isset($this->_route_config['labels'])) {
1554
+			foreach ($this->_route_config['labels'] as $label => $text) {
1555
+				if (is_array($text)) {
1556
+					foreach ($text as $sublabel => $subtext) {
1557
+						$this->_labels[ $label ][ $sublabel ] = $subtext;
1558
+					}
1559
+				} else {
1560
+					$this->_labels[ $label ] = $text;
1561
+				}
1562
+			}
1563
+		}
1564
+	}
1565
+
1566
+
1567
+	/**
1568
+	 *        verifies user access for this admin page
1569
+	 *
1570
+	 * @param string $route_to_check if present then the capability for the route matching this string is checked.
1571
+	 * @param bool   $verify_only    Default is FALSE which means if user check fails then wp_die().  Otherwise just
1572
+	 *                               return false if verify fail.
1573
+	 * @return bool
1574
+	 * @throws InvalidArgumentException
1575
+	 * @throws InvalidDataTypeException
1576
+	 * @throws InvalidInterfaceException
1577
+	 */
1578
+	public function check_user_access($route_to_check = '', $verify_only = false)
1579
+	{
1580
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1581
+		$route_to_check = empty($route_to_check) ? $this->_req_action : $route_to_check;
1582
+		$capability = ! empty($route_to_check) && isset($this->_page_routes[ $route_to_check ])
1583
+					  && is_array(
1584
+						  $this->_page_routes[ $route_to_check ]
1585
+					  )
1586
+					  && ! empty($this->_page_routes[ $route_to_check ]['capability'])
1587
+			? $this->_page_routes[ $route_to_check ]['capability'] : null;
1588
+		if (empty($capability) && empty($route_to_check)) {
1589
+			$capability = is_array($this->_route) && empty($this->_route['capability']) ? 'manage_options'
1590
+				: $this->_route['capability'];
1591
+		} else {
1592
+			$capability = empty($capability) ? 'manage_options' : $capability;
1593
+		}
1594
+		$id = is_array($this->_route) && ! empty($this->_route['obj_id']) ? $this->_route['obj_id'] : 0;
1595
+		if (! defined('DOING_AJAX')
1596
+			&& (
1597
+				! function_exists('is_admin')
1598
+				|| ! EE_Registry::instance()->CAP->current_user_can(
1599
+					$capability,
1600
+					$this->page_slug
1601
+					. '_'
1602
+					. $route_to_check,
1603
+					$id
1604
+				)
1605
+			)
1606
+		) {
1607
+			if ($verify_only) {
1608
+				return false;
1609
+			}
1610
+			if (is_user_logged_in()) {
1611
+				wp_die(__('You do not have access to this route.', 'event_espresso'));
1612
+			} else {
1613
+				return false;
1614
+			}
1615
+		}
1616
+		return true;
1617
+	}
1618
+
1619
+
1620
+	/**
1621
+	 * admin_init_global
1622
+	 * This runs all the code that we want executed within the WP admin_init hook.
1623
+	 * This method executes for ALL EE Admin pages.
1624
+	 *
1625
+	 * @return void
1626
+	 */
1627
+	public function admin_init_global()
1628
+	{
1629
+	}
1630
+
1631
+
1632
+	/**
1633
+	 * wp_loaded_global
1634
+	 * This runs all the code that we want executed within the WP wp_loaded hook.  This method is optional for an
1635
+	 * EE_Admin page and will execute on every EE Admin Page load
1636
+	 *
1637
+	 * @return void
1638
+	 */
1639
+	public function wp_loaded()
1640
+	{
1641
+	}
1642
+
1643
+
1644
+	/**
1645
+	 * admin_notices
1646
+	 * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply on
1647
+	 * ALL EE_Admin pages.
1648
+	 *
1649
+	 * @return void
1650
+	 */
1651
+	public function admin_notices_global()
1652
+	{
1653
+		$this->_display_no_javascript_warning();
1654
+		$this->_display_espresso_notices();
1655
+	}
1656
+
1657
+
1658
+	public function network_admin_notices_global()
1659
+	{
1660
+		$this->_display_no_javascript_warning();
1661
+		$this->_display_espresso_notices();
1662
+	}
1663
+
1664
+
1665
+	/**
1666
+	 * admin_footer_scripts_global
1667
+	 * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
1668
+	 * will apply on ALL EE_Admin pages.
1669
+	 *
1670
+	 * @return void
1671
+	 */
1672
+	public function admin_footer_scripts_global()
1673
+	{
1674
+		$this->_add_admin_page_ajax_loading_img();
1675
+		$this->_add_admin_page_overlay();
1676
+		// if metaboxes are present we need to add the nonce field
1677
+		if (isset($this->_route_config['metaboxes'])
1678
+			|| isset($this->_route_config['list_table'])
1679
+			|| (isset($this->_route_config['has_metaboxes']) && $this->_route_config['has_metaboxes'])
1680
+		) {
1681
+			wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false);
1682
+			wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false);
1683
+		}
1684
+	}
1685
+
1686
+
1687
+	/**
1688
+	 * admin_footer_global
1689
+	 * Anything triggered by the wp 'admin_footer' wp hook should be put in here.
1690
+	 * This particular method will apply on ALL EE_Admin Pages.
1691
+	 *
1692
+	 * @return void
1693
+	 * @throws InvalidArgumentException
1694
+	 * @throws InvalidDataTypeException
1695
+	 * @throws InvalidInterfaceException
1696
+	 */
1697
+	public function admin_footer_global()
1698
+	{
1699
+		// dialog container for dialog helper
1700
+		$d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n";
1701
+		$d_cont .= '<div class="ee-notices"></div>';
1702
+		$d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>';
1703
+		$d_cont .= '</div>';
1704
+		echo $d_cont;
1705
+		// help tour stuff?
1706
+		if (isset($this->_help_tour[ $this->_req_action ])) {
1707
+			echo implode('<br />', $this->_help_tour[ $this->_req_action ]);
1708
+		}
1709
+		// current set timezone for timezone js
1710
+		echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>';
1711
+	}
1712
+
1713
+
1714
+	/**
1715
+	 * This function sees if there is a method for help popup content existing for the given route.  If there is then
1716
+	 * we'll use the retrieved array to output the content using the template. For child classes: If you want to have
1717
+	 * help popups then in your templates or your content you set "triggers" for the content using the
1718
+	 * "_set_help_trigger('help_trigger_id')" where "help_trigger_id" is what you will use later in your custom method
1719
+	 * for the help popup content on that page. Then in your Child_Admin_Page class you need to define a help popup
1720
+	 * method for the content in the format "_help_popup_content_{route_name}()"  So if you are setting help content
1721
+	 * for the
1722
+	 * 'edit_event' route you should have a method named "_help_popup_content_edit_route". In your defined
1723
+	 * "help_popup_content_..." method.  You must prepare and return an array in the following format array(
1724
+	 *    'help_trigger_id' => array(
1725
+	 *        'title' => esc_html__('localized title for popup', 'event_espresso'),
1726
+	 *        'content' => esc_html__('localized content for popup', 'event_espresso')
1727
+	 *    )
1728
+	 * );
1729
+	 * Then the EE_Admin_Parent will take care of making sure that is setup properly on the correct route.
1730
+	 *
1731
+	 * @param array $help_array
1732
+	 * @param bool  $display
1733
+	 * @return string content
1734
+	 * @throws DomainException
1735
+	 * @throws EE_Error
1736
+	 */
1737
+	protected function _set_help_popup_content($help_array = array(), $display = false)
1738
+	{
1739
+		$content = '';
1740
+		$help_array = empty($help_array) ? $this->_get_help_content() : $help_array;
1741
+		// loop through the array and setup content
1742
+		foreach ($help_array as $trigger => $help) {
1743
+			// make sure the array is setup properly
1744
+			if (! isset($help['title'], $help['content'])) {
1745
+				throw new EE_Error(
1746
+					esc_html__(
1747
+						'Does not look like the popup content array has been setup correctly.  Might want to double check that.  Read the comments for the _get_help_popup_content method found in "EE_Admin_Page" class',
1748
+						'event_espresso'
1749
+					)
1750
+				);
1751
+			}
1752
+			// we're good so let'd setup the template vars and then assign parsed template content to our content.
1753
+			$template_args = array(
1754
+				'help_popup_id'      => $trigger,
1755
+				'help_popup_title'   => $help['title'],
1756
+				'help_popup_content' => $help['content'],
1757
+			);
1758
+			$content .= EEH_Template::display_template(
1759
+				EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php',
1760
+				$template_args,
1761
+				true
1762
+			);
1763
+		}
1764
+		if ($display) {
1765
+			echo $content;
1766
+			return '';
1767
+		}
1768
+		return $content;
1769
+	}
1770
+
1771
+
1772
+	/**
1773
+	 * All this does is retrieve the help content array if set by the EE_Admin_Page child
1774
+	 *
1775
+	 * @return array properly formatted array for help popup content
1776
+	 * @throws EE_Error
1777
+	 */
1778
+	private function _get_help_content()
1779
+	{
1780
+		// what is the method we're looking for?
1781
+		$method_name = '_help_popup_content_' . $this->_req_action;
1782
+		// if method doesn't exist let's get out.
1783
+		if (! method_exists($this, $method_name)) {
1784
+			return array();
1785
+		}
1786
+		// k we're good to go let's retrieve the help array
1787
+		$help_array = $this->{$method_name}();
1788
+		// make sure we've got an array!
1789
+		if (! is_array($help_array)) {
1790
+			throw new EE_Error(
1791
+				esc_html__(
1792
+					'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.',
1793
+					'event_espresso'
1794
+				)
1795
+			);
1796
+		}
1797
+		return $help_array;
1798
+	}
1799
+
1800
+
1801
+	/**
1802
+	 * EE Admin Pages can use this to set a properly formatted trigger for a help popup.
1803
+	 * By default the trigger html is printed.  Otherwise it can be returned if the $display flag is set "false"
1804
+	 * See comments made on the _set_help_content method for understanding other parts to the help popup tool.
1805
+	 *
1806
+	 * @param string  $trigger_id reference for retrieving the trigger content for the popup
1807
+	 * @param boolean $display    if false then we return the trigger string
1808
+	 * @param array   $dimensions an array of dimensions for the box (array(h,w))
1809
+	 * @return string
1810
+	 * @throws DomainException
1811
+	 * @throws EE_Error
1812
+	 */
1813
+	protected function _set_help_trigger($trigger_id, $display = true, $dimensions = array('400', '640'))
1814
+	{
1815
+		if (defined('DOING_AJAX')) {
1816
+			return '';
1817
+		}
1818
+		// let's check and see if there is any content set for this popup.  If there isn't then we'll include a default title and content so that developers know something needs to be corrected
1819
+		$help_array = $this->_get_help_content();
1820
+		$help_content = '';
1821
+		if (empty($help_array) || ! isset($help_array[ $trigger_id ])) {
1822
+			$help_array[ $trigger_id ] = array(
1823
+				'title'   => esc_html__('Missing Content', 'event_espresso'),
1824
+				'content' => esc_html__(
1825
+					'A trigger has been set that doesn\'t have any corresponding content. Make sure you have set the help content. (see the "_set_help_popup_content" method in the EE_Admin_Page for instructions.)',
1826
+					'event_espresso'
1827
+				),
1828
+			);
1829
+			$help_content = $this->_set_help_popup_content($help_array);
1830
+		}
1831
+		// let's setup the trigger
1832
+		$content = '<a class="ee-dialog" href="?height='
1833
+				   . $dimensions[0]
1834
+				   . '&width='
1835
+				   . $dimensions[1]
1836
+				   . '&inlineId='
1837
+				   . $trigger_id
1838
+				   . '" target="_blank"><span class="question ee-help-popup-question"></span></a>';
1839
+		$content .= $help_content;
1840
+		if ($display) {
1841
+			echo $content;
1842
+			return '';
1843
+		}
1844
+		return $content;
1845
+	}
1846
+
1847
+
1848
+	/**
1849
+	 * _add_global_screen_options
1850
+	 * Add any extra wp_screen_options within this method using built-in WP functions/methods for doing so.
1851
+	 * This particular method will add_screen_options on ALL EE_Admin Pages
1852
+	 *
1853
+	 * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
1854
+	 *         see also WP_Screen object documents...
1855
+	 * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
1856
+	 * @abstract
1857
+	 * @return void
1858
+	 */
1859
+	private function _add_global_screen_options()
1860
+	{
1861
+	}
1862
+
1863
+
1864
+	/**
1865
+	 * _add_global_feature_pointers
1866
+	 * This method is used for implementing any "feature pointers" (using built-in WP styling js).
1867
+	 * This particular method will implement feature pointers for ALL EE_Admin pages.
1868
+	 * Note: this is just a placeholder for now.  Implementation will come down the road
1869
+	 *
1870
+	 * @see    WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
1871
+	 *         extended) also see:
1872
+	 * @link   http://eamann.com/tech/wordpress-portland/
1873
+	 * @abstract
1874
+	 * @return void
1875
+	 */
1876
+	private function _add_global_feature_pointers()
1877
+	{
1878
+	}
1879
+
1880
+
1881
+	/**
1882
+	 * load_global_scripts_styles
1883
+	 * The scripts and styles enqueued in here will be loaded on every EE Admin page
1884
+	 *
1885
+	 * @return void
1886
+	 * @throws EE_Error
1887
+	 */
1888
+	public function load_global_scripts_styles()
1889
+	{
1890
+		/** STYLES **/
1891
+		// add debugging styles
1892
+		if (WP_DEBUG) {
1893
+			add_action('admin_head', array($this, 'add_xdebug_style'));
1894
+		}
1895
+		// register all styles
1896
+		wp_register_style(
1897
+			'espresso-ui-theme',
1898
+			EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1899
+			array(),
1900
+			EVENT_ESPRESSO_VERSION
1901
+		);
1902
+		wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1903
+		// helpers styles
1904
+		wp_register_style(
1905
+			'ee-text-links',
1906
+			EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css',
1907
+			array(),
1908
+			EVENT_ESPRESSO_VERSION
1909
+		);
1910
+		/** SCRIPTS **/
1911
+		// register all scripts
1912
+		wp_register_script(
1913
+			'ee-dialog',
1914
+			EE_ADMIN_URL . 'assets/ee-dialog-helper.js',
1915
+			array('jquery', 'jquery-ui-draggable'),
1916
+			EVENT_ESPRESSO_VERSION,
1917
+			true
1918
+		);
1919
+		wp_register_script(
1920
+			'ee_admin_js',
1921
+			EE_ADMIN_URL . 'assets/ee-admin-page.js',
1922
+			array('espresso_core', 'ee-parse-uri', 'ee-dialog'),
1923
+			EVENT_ESPRESSO_VERSION,
1924
+			true
1925
+		);
1926
+		wp_register_script(
1927
+			'jquery-ui-timepicker-addon',
1928
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js',
1929
+			array('jquery-ui-datepicker', 'jquery-ui-slider'),
1930
+			EVENT_ESPRESSO_VERSION,
1931
+			true
1932
+		);
1933
+		if (EE_Registry::instance()->CFG->admin->help_tour_activation) {
1934
+			add_filter('FHEE_load_joyride', '__return_true');
1935
+		}
1936
+		// script for sorting tables
1937
+		wp_register_script(
1938
+			'espresso_ajax_table_sorting',
1939
+			EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js',
1940
+			array('ee_admin_js', 'jquery-ui-sortable'),
1941
+			EVENT_ESPRESSO_VERSION,
1942
+			true
1943
+		);
1944
+		// script for parsing uri's
1945
+		wp_register_script(
1946
+			'ee-parse-uri',
1947
+			EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js',
1948
+			array(),
1949
+			EVENT_ESPRESSO_VERSION,
1950
+			true
1951
+		);
1952
+		// and parsing associative serialized form elements
1953
+		wp_register_script(
1954
+			'ee-serialize-full-array',
1955
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js',
1956
+			array('jquery'),
1957
+			EVENT_ESPRESSO_VERSION,
1958
+			true
1959
+		);
1960
+		// helpers scripts
1961
+		wp_register_script(
1962
+			'ee-text-links',
1963
+			EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js',
1964
+			array('jquery'),
1965
+			EVENT_ESPRESSO_VERSION,
1966
+			true
1967
+		);
1968
+		wp_register_script(
1969
+			'ee-moment-core',
1970
+			EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js',
1971
+			array(),
1972
+			EVENT_ESPRESSO_VERSION,
1973
+			true
1974
+		);
1975
+		wp_register_script(
1976
+			'ee-moment',
1977
+			EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js',
1978
+			array('ee-moment-core'),
1979
+			EVENT_ESPRESSO_VERSION,
1980
+			true
1981
+		);
1982
+		wp_register_script(
1983
+			'ee-datepicker',
1984
+			EE_ADMIN_URL . 'assets/ee-datepicker.js',
1985
+			array('jquery-ui-timepicker-addon', 'ee-moment'),
1986
+			EVENT_ESPRESSO_VERSION,
1987
+			true
1988
+		);
1989
+		// google charts
1990
+		wp_register_script(
1991
+			'google-charts',
1992
+			'https://www.gstatic.com/charts/loader.js',
1993
+			array(),
1994
+			EVENT_ESPRESSO_VERSION
1995
+		);
1996
+		// ENQUEUE ALL BASICS BY DEFAULT
1997
+		wp_enqueue_style('ee-admin-css');
1998
+		wp_enqueue_script('ee_admin_js');
1999
+		wp_enqueue_script('jquery-validate');
2000
+		// taking care of metaboxes
2001
+		if (empty($this->_cpt_route)
2002
+			&& (isset($this->_route_config['metaboxes']) || isset($this->_route_config['has_metaboxes']))
2003
+		) {
2004
+			wp_enqueue_script('dashboard');
2005
+		}
2006
+		// LOCALIZED DATA
2007
+		// localize script for ajax lazy loading
2008
+		$lazy_loader_container_ids = apply_filters(
2009
+			'FHEE__EE_Admin_Page_Core__load_global_scripts_styles__loader_containers',
2010
+			array('espresso_news_post_box_content')
2011
+		);
2012
+		wp_localize_script('ee_admin_js', 'eeLazyLoadingContainers', $lazy_loader_container_ids);
2013
+		/**
2014
+		 * help tour stuff
2015
+		 */
2016
+		if (! empty($this->_help_tour)) {
2017
+			// register the js for kicking things off
2018
+			wp_enqueue_script(
2019
+				'ee-help-tour',
2020
+				EE_ADMIN_URL . 'assets/ee-help-tour.js',
2021
+				array('jquery-joyride'),
2022
+				EVENT_ESPRESSO_VERSION,
2023
+				true
2024
+			);
2025
+			$tours = array();
2026
+			// setup tours for the js tour object
2027
+			foreach ($this->_help_tour['tours'] as $tour) {
2028
+				if ($tour instanceof EE_Help_Tour) {
2029
+					$tours[] = array(
2030
+						'id'      => $tour->get_slug(),
2031
+						'options' => $tour->get_options(),
2032
+					);
2033
+				}
2034
+			}
2035
+			wp_localize_script('ee-help-tour', 'EE_HELP_TOUR', array('tours' => $tours));
2036
+			// admin_footer_global will take care of making sure our help_tour skeleton gets printed via the info stored in $this->_help_tour
2037
+		}
2038
+	}
2039
+
2040
+
2041
+	/**
2042
+	 *        admin_footer_scripts_eei18n_js_strings
2043
+	 *
2044
+	 * @return        void
2045
+	 */
2046
+	public function admin_footer_scripts_eei18n_js_strings()
2047
+	{
2048
+		EE_Registry::$i18n_js_strings['ajax_url'] = WP_AJAX_URL;
2049
+		EE_Registry::$i18n_js_strings['confirm_delete'] = esc_html__(
2050
+			'Are you absolutely sure you want to delete this item?\nThis action will delete ALL DATA associated with this item!!!\nThis can NOT be undone!!!',
2051
+			'event_espresso'
2052
+		);
2053
+		EE_Registry::$i18n_js_strings['January'] = esc_html__('January', 'event_espresso');
2054
+		EE_Registry::$i18n_js_strings['February'] = esc_html__('February', 'event_espresso');
2055
+		EE_Registry::$i18n_js_strings['March'] = esc_html__('March', 'event_espresso');
2056
+		EE_Registry::$i18n_js_strings['April'] = esc_html__('April', 'event_espresso');
2057
+		EE_Registry::$i18n_js_strings['May'] = esc_html__('May', 'event_espresso');
2058
+		EE_Registry::$i18n_js_strings['June'] = esc_html__('June', 'event_espresso');
2059
+		EE_Registry::$i18n_js_strings['July'] = esc_html__('July', 'event_espresso');
2060
+		EE_Registry::$i18n_js_strings['August'] = esc_html__('August', 'event_espresso');
2061
+		EE_Registry::$i18n_js_strings['September'] = esc_html__('September', 'event_espresso');
2062
+		EE_Registry::$i18n_js_strings['October'] = esc_html__('October', 'event_espresso');
2063
+		EE_Registry::$i18n_js_strings['November'] = esc_html__('November', 'event_espresso');
2064
+		EE_Registry::$i18n_js_strings['December'] = esc_html__('December', 'event_espresso');
2065
+		EE_Registry::$i18n_js_strings['Jan'] = esc_html__('Jan', 'event_espresso');
2066
+		EE_Registry::$i18n_js_strings['Feb'] = esc_html__('Feb', 'event_espresso');
2067
+		EE_Registry::$i18n_js_strings['Mar'] = esc_html__('Mar', 'event_espresso');
2068
+		EE_Registry::$i18n_js_strings['Apr'] = esc_html__('Apr', 'event_espresso');
2069
+		EE_Registry::$i18n_js_strings['May'] = esc_html__('May', 'event_espresso');
2070
+		EE_Registry::$i18n_js_strings['Jun'] = esc_html__('Jun', 'event_espresso');
2071
+		EE_Registry::$i18n_js_strings['Jul'] = esc_html__('Jul', 'event_espresso');
2072
+		EE_Registry::$i18n_js_strings['Aug'] = esc_html__('Aug', 'event_espresso');
2073
+		EE_Registry::$i18n_js_strings['Sep'] = esc_html__('Sep', 'event_espresso');
2074
+		EE_Registry::$i18n_js_strings['Oct'] = esc_html__('Oct', 'event_espresso');
2075
+		EE_Registry::$i18n_js_strings['Nov'] = esc_html__('Nov', 'event_espresso');
2076
+		EE_Registry::$i18n_js_strings['Dec'] = esc_html__('Dec', 'event_espresso');
2077
+		EE_Registry::$i18n_js_strings['Sunday'] = esc_html__('Sunday', 'event_espresso');
2078
+		EE_Registry::$i18n_js_strings['Monday'] = esc_html__('Monday', 'event_espresso');
2079
+		EE_Registry::$i18n_js_strings['Tuesday'] = esc_html__('Tuesday', 'event_espresso');
2080
+		EE_Registry::$i18n_js_strings['Wednesday'] = esc_html__('Wednesday', 'event_espresso');
2081
+		EE_Registry::$i18n_js_strings['Thursday'] = esc_html__('Thursday', 'event_espresso');
2082
+		EE_Registry::$i18n_js_strings['Friday'] = esc_html__('Friday', 'event_espresso');
2083
+		EE_Registry::$i18n_js_strings['Saturday'] = esc_html__('Saturday', 'event_espresso');
2084
+		EE_Registry::$i18n_js_strings['Sun'] = esc_html__('Sun', 'event_espresso');
2085
+		EE_Registry::$i18n_js_strings['Mon'] = esc_html__('Mon', 'event_espresso');
2086
+		EE_Registry::$i18n_js_strings['Tue'] = esc_html__('Tue', 'event_espresso');
2087
+		EE_Registry::$i18n_js_strings['Wed'] = esc_html__('Wed', 'event_espresso');
2088
+		EE_Registry::$i18n_js_strings['Thu'] = esc_html__('Thu', 'event_espresso');
2089
+		EE_Registry::$i18n_js_strings['Fri'] = esc_html__('Fri', 'event_espresso');
2090
+		EE_Registry::$i18n_js_strings['Sat'] = esc_html__('Sat', 'event_espresso');
2091
+	}
2092
+
2093
+
2094
+	/**
2095
+	 *        load enhanced xdebug styles for ppl with failing eyesight
2096
+	 *
2097
+	 * @return        void
2098
+	 */
2099
+	public function add_xdebug_style()
2100
+	{
2101
+		echo '<style>.xdebug-error { font-size:1.5em; }</style>';
2102
+	}
2103
+
2104
+
2105
+	/************************/
2106
+	/** LIST TABLE METHODS **/
2107
+	/************************/
2108
+	/**
2109
+	 * this sets up the list table if the current view requires it.
2110
+	 *
2111
+	 * @return void
2112
+	 * @throws EE_Error
2113
+	 * @throws InvalidArgumentException
2114
+	 * @throws InvalidDataTypeException
2115
+	 * @throws InvalidInterfaceException
2116
+	 */
2117
+	protected function _set_list_table()
2118
+	{
2119
+		// first is this a list_table view?
2120
+		if (! isset($this->_route_config['list_table'])) {
2121
+			return;
2122
+		} //not a list_table view so get out.
2123
+		// list table functions are per view specific (because some admin pages might have more than one list table!)
2124
+		$list_table_view = '_set_list_table_views_' . $this->_req_action;
2125
+		if (! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) {
2126
+			// user error msg
2127
+			$error_msg = esc_html__(
2128
+				'An error occurred. The requested list table views could not be found.',
2129
+				'event_espresso'
2130
+			);
2131
+			// developer error msg
2132
+			$error_msg .= '||'
2133
+						  . sprintf(
2134
+							  esc_html__(
2135
+								  'List table views for "%s" route could not be setup. Check that you have the corresponding method, "%s" set up for defining list_table_views for this route.',
2136
+								  'event_espresso'
2137
+							  ),
2138
+							  $this->_req_action,
2139
+							  $list_table_view
2140
+						  );
2141
+			throw new EE_Error($error_msg);
2142
+		}
2143
+		// let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally
2144
+		$this->_views = apply_filters(
2145
+			'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action,
2146
+			$this->_views
2147
+		);
2148
+		$this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views);
2149
+		$this->_views = apply_filters('FHEE_list_table_views', $this->_views);
2150
+		$this->_set_list_table_view();
2151
+		$this->_set_list_table_object();
2152
+	}
2153
+
2154
+
2155
+	/**
2156
+	 * set current view for List Table
2157
+	 *
2158
+	 * @return void
2159
+	 */
2160
+	protected function _set_list_table_view()
2161
+	{
2162
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2163
+		// looking at active items or dumpster diving ?
2164
+		if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2165
+			$this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all';
2166
+		} else {
2167
+			$this->_view = sanitize_key($this->_req_data['status']);
2168
+		}
2169
+	}
2170
+
2171
+
2172
+	/**
2173
+	 * _set_list_table_object
2174
+	 * WP_List_Table objects need to be loaded fairly early so automatic stuff WP does is taken care of.
2175
+	 *
2176
+	 * @throws InvalidInterfaceException
2177
+	 * @throws InvalidArgumentException
2178
+	 * @throws InvalidDataTypeException
2179
+	 * @throws EE_Error
2180
+	 * @throws InvalidInterfaceException
2181
+	 */
2182
+	protected function _set_list_table_object()
2183
+	{
2184
+		if (isset($this->_route_config['list_table'])) {
2185
+			if (! class_exists($this->_route_config['list_table'])) {
2186
+				throw new EE_Error(
2187
+					sprintf(
2188
+						esc_html__(
2189
+							'The %s class defined for the list table does not exist.  Please check the spelling of the class ref in the $_page_config property on %s.',
2190
+							'event_espresso'
2191
+						),
2192
+						$this->_route_config['list_table'],
2193
+						get_class($this)
2194
+					)
2195
+				);
2196
+			}
2197
+			$this->_list_table_object = $this->loader->getShared(
2198
+				$this->_route_config['list_table'],
2199
+				array($this)
2200
+			);
2201
+		}
2202
+	}
2203
+
2204
+
2205
+	/**
2206
+	 * get_list_table_view_RLs - get it? View RL ?? VU-RL???  URL ??
2207
+	 *
2208
+	 * @param array $extra_query_args                     Optional. An array of extra query args to add to the generated
2209
+	 *                                                    urls.  The array should be indexed by the view it is being
2210
+	 *                                                    added to.
2211
+	 * @return array
2212
+	 */
2213
+	public function get_list_table_view_RLs($extra_query_args = array())
2214
+	{
2215
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2216
+		if (empty($this->_views)) {
2217
+			$this->_views = array();
2218
+		}
2219
+		// cycle thru views
2220
+		foreach ($this->_views as $key => $view) {
2221
+			$query_args = array();
2222
+			// check for current view
2223
+			$this->_views[ $key ]['class'] = $this->_view === $view['slug'] ? 'current' : '';
2224
+			$query_args['action'] = $this->_req_action;
2225
+			$query_args[ $this->_req_action . '_nonce' ] = wp_create_nonce($query_args['action'] . '_nonce');
2226
+			$query_args['status'] = $view['slug'];
2227
+			// merge any other arguments sent in.
2228
+			if (isset($extra_query_args[ $view['slug'] ])) {
2229
+				foreach ($extra_query_args[ $view['slug'] ] as $extra_query_arg) {
2230
+					$query_args[] = $extra_query_arg;
2231
+				}
2232
+			}
2233
+			$this->_views[ $key ]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2234
+		}
2235
+		return $this->_views;
2236
+	}
2237
+
2238
+
2239
+	/**
2240
+	 * _entries_per_page_dropdown
2241
+	 * generates a drop down box for selecting the number of visible rows in an admin page list table
2242
+	 *
2243
+	 * @todo   : Note: ideally this should be added to the screen options dropdown as that would be consistent with how
2244
+	 *         WP does it.
2245
+	 * @param int $max_entries total number of rows in the table
2246
+	 * @return string
2247
+	 */
2248
+	protected function _entries_per_page_dropdown($max_entries = 0)
2249
+	{
2250
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2251
+		$values = array(10, 25, 50, 100);
2252
+		$per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2253
+		if ($max_entries) {
2254
+			$values[] = $max_entries;
2255
+			sort($values);
2256
+		}
2257
+		$entries_per_page_dropdown = '
2258 2258
 			<div id="entries-per-page-dv" class="alignleft actions">
2259 2259
 				<label class="hide-if-no-js">
2260 2260
 					Show
2261 2261
 					<select id="entries-per-page-slct" name="entries-per-page-slct">';
2262
-        foreach ($values as $value) {
2263
-            if ($value < $max_entries) {
2264
-                $selected = $value === $per_page ? ' selected="' . $per_page . '"' : '';
2265
-                $entries_per_page_dropdown .= '
2262
+		foreach ($values as $value) {
2263
+			if ($value < $max_entries) {
2264
+				$selected = $value === $per_page ? ' selected="' . $per_page . '"' : '';
2265
+				$entries_per_page_dropdown .= '
2266 2266
 						<option value="' . $value . '"' . $selected . '>' . $value . '&nbsp;&nbsp;</option>';
2267
-            }
2268
-        }
2269
-        $selected = $max_entries === $per_page ? ' selected="' . $per_page . '"' : '';
2270
-        $entries_per_page_dropdown .= '
2267
+			}
2268
+		}
2269
+		$selected = $max_entries === $per_page ? ' selected="' . $per_page . '"' : '';
2270
+		$entries_per_page_dropdown .= '
2271 2271
 						<option value="' . $max_entries . '"' . $selected . '>All&nbsp;&nbsp;</option>';
2272
-        $entries_per_page_dropdown .= '
2272
+		$entries_per_page_dropdown .= '
2273 2273
 					</select>
2274 2274
 					entries
2275 2275
 				</label>
2276 2276
 				<input id="entries-per-page-btn" class="button-secondary" type="submit" value="Go" >
2277 2277
 			</div>
2278 2278
 		';
2279
-        return $entries_per_page_dropdown;
2280
-    }
2281
-
2282
-
2283
-    /**
2284
-     *        _set_search_attributes
2285
-     *
2286
-     * @return        void
2287
-     */
2288
-    public function _set_search_attributes()
2289
-    {
2290
-        $this->_template_args['search']['btn_label'] = sprintf(
2291
-            esc_html__('Search %s', 'event_espresso'),
2292
-            empty($this->_search_btn_label) ? $this->page_label
2293
-                : $this->_search_btn_label
2294
-        );
2295
-        $this->_template_args['search']['callback'] = 'search_' . $this->page_slug;
2296
-    }
2297
-
2298
-
2299
-
2300
-    /*** END LIST TABLE METHODS **/
2301
-
2302
-
2303
-    /**
2304
-     * _add_registered_metaboxes
2305
-     *  this loads any registered metaboxes via the 'metaboxes' index in the _page_config property array.
2306
-     *
2307
-     * @link   http://codex.wordpress.org/Function_Reference/add_meta_box
2308
-     * @return void
2309
-     * @throws EE_Error
2310
-     */
2311
-    private function _add_registered_meta_boxes()
2312
-    {
2313
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2314
-        // we only add meta boxes if the page_route calls for it
2315
-        if (is_array($this->_route_config) && isset($this->_route_config['metaboxes'])
2316
-            && is_array(
2317
-                $this->_route_config['metaboxes']
2318
-            )
2319
-        ) {
2320
-            // this simply loops through the callbacks provided
2321
-            // and checks if there is a corresponding callback registered by the child
2322
-            // if there is then we go ahead and process the metabox loader.
2323
-            foreach ($this->_route_config['metaboxes'] as $metabox_callback) {
2324
-                // first check for Closures
2325
-                if ($metabox_callback instanceof Closure) {
2326
-                    $result = $metabox_callback();
2327
-                } elseif (is_array($metabox_callback) && isset($metabox_callback[0], $metabox_callback[1])) {
2328
-                    $result = call_user_func(array($metabox_callback[0], $metabox_callback[1]));
2329
-                } else {
2330
-                    $result = $this->{$metabox_callback}();
2331
-                }
2332
-                if ($result === false) {
2333
-                    // user error msg
2334
-                    $error_msg = esc_html__(
2335
-                        'An error occurred. The  requested metabox could not be found.',
2336
-                        'event_espresso'
2337
-                    );
2338
-                    // developer error msg
2339
-                    $error_msg .= '||'
2340
-                                  . sprintf(
2341
-                                      esc_html__(
2342
-                                          'The metabox with the string "%s" could not be called. Check that the spelling for method names and actions in the "_page_config[\'metaboxes\']" array are all correct.',
2343
-                                          'event_espresso'
2344
-                                      ),
2345
-                                      $metabox_callback
2346
-                                  );
2347
-                    throw new EE_Error($error_msg);
2348
-                }
2349
-            }
2350
-        }
2351
-    }
2352
-
2353
-
2354
-    /**
2355
-     * _add_screen_columns
2356
-     * This will check the _page_config array and if there is "columns" key index indicated, we'll set the template as
2357
-     * the dynamic column template and we'll setup the column options for the page.
2358
-     *
2359
-     * @return void
2360
-     */
2361
-    private function _add_screen_columns()
2362
-    {
2363
-        if (is_array($this->_route_config)
2364
-            && isset($this->_route_config['columns'])
2365
-            && is_array($this->_route_config['columns'])
2366
-            && count($this->_route_config['columns']) === 2
2367
-        ) {
2368
-            add_screen_option(
2369
-                'layout_columns',
2370
-                array(
2371
-                    'max'     => (int) $this->_route_config['columns'][0],
2372
-                    'default' => (int) $this->_route_config['columns'][1],
2373
-                )
2374
-            );
2375
-            $this->_template_args['num_columns'] = $this->_route_config['columns'][0];
2376
-            $screen_id = $this->_current_screen->id;
2377
-            $screen_columns = (int) get_user_option("screen_layout_{$screen_id}");
2378
-            $total_columns = ! empty($screen_columns)
2379
-                ? $screen_columns
2380
-                : $this->_route_config['columns'][1];
2381
-            $this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns;
2382
-            $this->_template_args['current_page'] = $this->_wp_page_slug;
2383
-            $this->_template_args['screen'] = $this->_current_screen;
2384
-            $this->_column_template_path = EE_ADMIN_TEMPLATE
2385
-                                           . 'admin_details_metabox_column_wrapper.template.php';
2386
-            // finally if we don't have has_metaboxes set in the route config
2387
-            // let's make sure it IS set other wise the necessary hidden fields for this won't be loaded.
2388
-            $this->_route_config['has_metaboxes'] = true;
2389
-        }
2390
-    }
2391
-
2392
-
2393
-
2394
-    /** GLOBALLY AVAILABLE METABOXES **/
2395
-
2396
-
2397
-    /**
2398
-     * In this section we put any globally available EE metaboxes for all EE Admin pages.  They are called by simply
2399
-     * referencing the callback in the _page_config array property.  This way you can be very specific about what pages
2400
-     * these get loaded on.
2401
-     */
2402
-    private function _espresso_news_post_box()
2403
-    {
2404
-        $news_box_title = apply_filters(
2405
-            'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2406
-            esc_html__('New @ Event Espresso', 'event_espresso')
2407
-        );
2408
-        add_meta_box(
2409
-            'espresso_news_post_box',
2410
-            $news_box_title,
2411
-            array(
2412
-                $this,
2413
-                'espresso_news_post_box',
2414
-            ),
2415
-            $this->_wp_page_slug,
2416
-            'side'
2417
-        );
2418
-    }
2419
-
2420
-
2421
-    /**
2422
-     * Code for setting up espresso ratings request metabox.
2423
-     */
2424
-    protected function _espresso_ratings_request()
2425
-    {
2426
-        if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2427
-            return;
2428
-        }
2429
-        $ratings_box_title = apply_filters(
2430
-            'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2431
-            esc_html__('Keep Event Espresso Decaf Free', 'event_espresso')
2432
-        );
2433
-        add_meta_box(
2434
-            'espresso_ratings_request',
2435
-            $ratings_box_title,
2436
-            array(
2437
-                $this,
2438
-                'espresso_ratings_request',
2439
-            ),
2440
-            $this->_wp_page_slug,
2441
-            'side'
2442
-        );
2443
-    }
2444
-
2445
-
2446
-    /**
2447
-     * Code for setting up espresso ratings request metabox content.
2448
-     *
2449
-     * @throws DomainException
2450
-     */
2451
-    public function espresso_ratings_request()
2452
-    {
2453
-        EEH_Template::display_template(EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php');
2454
-    }
2455
-
2456
-
2457
-    public static function cached_rss_display($rss_id, $url)
2458
-    {
2459
-        $loading = '<p class="widget-loading hide-if-no-js">'
2460
-                   . __('Loading&#8230;', 'event_espresso')
2461
-                   . '</p><p class="hide-if-js">'
2462
-                   . esc_html__('This widget requires JavaScript.', 'event_espresso')
2463
-                   . '</p>';
2464
-        $pre = '<div class="espresso-rss-display">' . "\n\t";
2465
-        $pre .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>';
2466
-        $post = '</div>' . "\n";
2467
-        $cache_key = 'ee_rss_' . md5($rss_id);
2468
-        $output = get_transient($cache_key);
2469
-        if ($output !== false) {
2470
-            echo $pre . $output . $post;
2471
-            return true;
2472
-        }
2473
-        if (! (defined('DOING_AJAX') && DOING_AJAX)) {
2474
-            echo $pre . $loading . $post;
2475
-            return false;
2476
-        }
2477
-        ob_start();
2478
-        wp_widget_rss_output($url, array('show_date' => 0, 'items' => 5));
2479
-        set_transient($cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS);
2480
-        return true;
2481
-    }
2482
-
2483
-
2484
-    public function espresso_news_post_box()
2485
-    {
2486
-        ?>
2279
+		return $entries_per_page_dropdown;
2280
+	}
2281
+
2282
+
2283
+	/**
2284
+	 *        _set_search_attributes
2285
+	 *
2286
+	 * @return        void
2287
+	 */
2288
+	public function _set_search_attributes()
2289
+	{
2290
+		$this->_template_args['search']['btn_label'] = sprintf(
2291
+			esc_html__('Search %s', 'event_espresso'),
2292
+			empty($this->_search_btn_label) ? $this->page_label
2293
+				: $this->_search_btn_label
2294
+		);
2295
+		$this->_template_args['search']['callback'] = 'search_' . $this->page_slug;
2296
+	}
2297
+
2298
+
2299
+
2300
+	/*** END LIST TABLE METHODS **/
2301
+
2302
+
2303
+	/**
2304
+	 * _add_registered_metaboxes
2305
+	 *  this loads any registered metaboxes via the 'metaboxes' index in the _page_config property array.
2306
+	 *
2307
+	 * @link   http://codex.wordpress.org/Function_Reference/add_meta_box
2308
+	 * @return void
2309
+	 * @throws EE_Error
2310
+	 */
2311
+	private function _add_registered_meta_boxes()
2312
+	{
2313
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2314
+		// we only add meta boxes if the page_route calls for it
2315
+		if (is_array($this->_route_config) && isset($this->_route_config['metaboxes'])
2316
+			&& is_array(
2317
+				$this->_route_config['metaboxes']
2318
+			)
2319
+		) {
2320
+			// this simply loops through the callbacks provided
2321
+			// and checks if there is a corresponding callback registered by the child
2322
+			// if there is then we go ahead and process the metabox loader.
2323
+			foreach ($this->_route_config['metaboxes'] as $metabox_callback) {
2324
+				// first check for Closures
2325
+				if ($metabox_callback instanceof Closure) {
2326
+					$result = $metabox_callback();
2327
+				} elseif (is_array($metabox_callback) && isset($metabox_callback[0], $metabox_callback[1])) {
2328
+					$result = call_user_func(array($metabox_callback[0], $metabox_callback[1]));
2329
+				} else {
2330
+					$result = $this->{$metabox_callback}();
2331
+				}
2332
+				if ($result === false) {
2333
+					// user error msg
2334
+					$error_msg = esc_html__(
2335
+						'An error occurred. The  requested metabox could not be found.',
2336
+						'event_espresso'
2337
+					);
2338
+					// developer error msg
2339
+					$error_msg .= '||'
2340
+								  . sprintf(
2341
+									  esc_html__(
2342
+										  'The metabox with the string "%s" could not be called. Check that the spelling for method names and actions in the "_page_config[\'metaboxes\']" array are all correct.',
2343
+										  'event_espresso'
2344
+									  ),
2345
+									  $metabox_callback
2346
+								  );
2347
+					throw new EE_Error($error_msg);
2348
+				}
2349
+			}
2350
+		}
2351
+	}
2352
+
2353
+
2354
+	/**
2355
+	 * _add_screen_columns
2356
+	 * This will check the _page_config array and if there is "columns" key index indicated, we'll set the template as
2357
+	 * the dynamic column template and we'll setup the column options for the page.
2358
+	 *
2359
+	 * @return void
2360
+	 */
2361
+	private function _add_screen_columns()
2362
+	{
2363
+		if (is_array($this->_route_config)
2364
+			&& isset($this->_route_config['columns'])
2365
+			&& is_array($this->_route_config['columns'])
2366
+			&& count($this->_route_config['columns']) === 2
2367
+		) {
2368
+			add_screen_option(
2369
+				'layout_columns',
2370
+				array(
2371
+					'max'     => (int) $this->_route_config['columns'][0],
2372
+					'default' => (int) $this->_route_config['columns'][1],
2373
+				)
2374
+			);
2375
+			$this->_template_args['num_columns'] = $this->_route_config['columns'][0];
2376
+			$screen_id = $this->_current_screen->id;
2377
+			$screen_columns = (int) get_user_option("screen_layout_{$screen_id}");
2378
+			$total_columns = ! empty($screen_columns)
2379
+				? $screen_columns
2380
+				: $this->_route_config['columns'][1];
2381
+			$this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns;
2382
+			$this->_template_args['current_page'] = $this->_wp_page_slug;
2383
+			$this->_template_args['screen'] = $this->_current_screen;
2384
+			$this->_column_template_path = EE_ADMIN_TEMPLATE
2385
+										   . 'admin_details_metabox_column_wrapper.template.php';
2386
+			// finally if we don't have has_metaboxes set in the route config
2387
+			// let's make sure it IS set other wise the necessary hidden fields for this won't be loaded.
2388
+			$this->_route_config['has_metaboxes'] = true;
2389
+		}
2390
+	}
2391
+
2392
+
2393
+
2394
+	/** GLOBALLY AVAILABLE METABOXES **/
2395
+
2396
+
2397
+	/**
2398
+	 * In this section we put any globally available EE metaboxes for all EE Admin pages.  They are called by simply
2399
+	 * referencing the callback in the _page_config array property.  This way you can be very specific about what pages
2400
+	 * these get loaded on.
2401
+	 */
2402
+	private function _espresso_news_post_box()
2403
+	{
2404
+		$news_box_title = apply_filters(
2405
+			'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2406
+			esc_html__('New @ Event Espresso', 'event_espresso')
2407
+		);
2408
+		add_meta_box(
2409
+			'espresso_news_post_box',
2410
+			$news_box_title,
2411
+			array(
2412
+				$this,
2413
+				'espresso_news_post_box',
2414
+			),
2415
+			$this->_wp_page_slug,
2416
+			'side'
2417
+		);
2418
+	}
2419
+
2420
+
2421
+	/**
2422
+	 * Code for setting up espresso ratings request metabox.
2423
+	 */
2424
+	protected function _espresso_ratings_request()
2425
+	{
2426
+		if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2427
+			return;
2428
+		}
2429
+		$ratings_box_title = apply_filters(
2430
+			'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2431
+			esc_html__('Keep Event Espresso Decaf Free', 'event_espresso')
2432
+		);
2433
+		add_meta_box(
2434
+			'espresso_ratings_request',
2435
+			$ratings_box_title,
2436
+			array(
2437
+				$this,
2438
+				'espresso_ratings_request',
2439
+			),
2440
+			$this->_wp_page_slug,
2441
+			'side'
2442
+		);
2443
+	}
2444
+
2445
+
2446
+	/**
2447
+	 * Code for setting up espresso ratings request metabox content.
2448
+	 *
2449
+	 * @throws DomainException
2450
+	 */
2451
+	public function espresso_ratings_request()
2452
+	{
2453
+		EEH_Template::display_template(EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php');
2454
+	}
2455
+
2456
+
2457
+	public static function cached_rss_display($rss_id, $url)
2458
+	{
2459
+		$loading = '<p class="widget-loading hide-if-no-js">'
2460
+				   . __('Loading&#8230;', 'event_espresso')
2461
+				   . '</p><p class="hide-if-js">'
2462
+				   . esc_html__('This widget requires JavaScript.', 'event_espresso')
2463
+				   . '</p>';
2464
+		$pre = '<div class="espresso-rss-display">' . "\n\t";
2465
+		$pre .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>';
2466
+		$post = '</div>' . "\n";
2467
+		$cache_key = 'ee_rss_' . md5($rss_id);
2468
+		$output = get_transient($cache_key);
2469
+		if ($output !== false) {
2470
+			echo $pre . $output . $post;
2471
+			return true;
2472
+		}
2473
+		if (! (defined('DOING_AJAX') && DOING_AJAX)) {
2474
+			echo $pre . $loading . $post;
2475
+			return false;
2476
+		}
2477
+		ob_start();
2478
+		wp_widget_rss_output($url, array('show_date' => 0, 'items' => 5));
2479
+		set_transient($cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS);
2480
+		return true;
2481
+	}
2482
+
2483
+
2484
+	public function espresso_news_post_box()
2485
+	{
2486
+		?>
2487 2487
         <div class="padding">
2488 2488
             <div id="espresso_news_post_box_content" class="infolinks">
2489 2489
                 <?php
2490
-                // Get RSS Feed(s)
2491
-                EE_Admin_Page::cached_rss_display(
2492
-                    'espresso_news_post_box_content',
2493
-                    urlencode(
2494
-                        apply_filters(
2495
-                            'FHEE__EE_Admin_Page__espresso_news_post_box__feed_url',
2496
-                            'http://eventespresso.com/feed/'
2497
-                        )
2498
-                    )
2499
-                );
2500
-                ?>
2490
+				// Get RSS Feed(s)
2491
+				EE_Admin_Page::cached_rss_display(
2492
+					'espresso_news_post_box_content',
2493
+					urlencode(
2494
+						apply_filters(
2495
+							'FHEE__EE_Admin_Page__espresso_news_post_box__feed_url',
2496
+							'http://eventespresso.com/feed/'
2497
+						)
2498
+					)
2499
+				);
2500
+				?>
2501 2501
             </div>
2502 2502
             <?php do_action('AHEE__EE_Admin_Page__espresso_news_post_box__after_content'); ?>
2503 2503
         </div>
2504 2504
         <?php
2505
-    }
2506
-
2507
-
2508
-    private function _espresso_links_post_box()
2509
-    {
2510
-        // Hiding until we actually have content to put in here...
2511
-        // add_meta_box('espresso_links_post_box', esc_html__('Helpful Plugin Links', 'event_espresso'), array( $this, 'espresso_links_post_box'), $this->_wp_page_slug, 'side');
2512
-    }
2513
-
2514
-
2515
-    public function espresso_links_post_box()
2516
-    {
2517
-        // Hiding until we actually have content to put in here...
2518
-        // EEH_Template::display_template(
2519
-        //     EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_links.template.php'
2520
-        // );
2521
-    }
2522
-
2523
-
2524
-    protected function _espresso_sponsors_post_box()
2525
-    {
2526
-        if (apply_filters('FHEE_show_sponsors_meta_box', true)) {
2527
-            add_meta_box(
2528
-                'espresso_sponsors_post_box',
2529
-                esc_html__('Event Espresso Highlights', 'event_espresso'),
2530
-                array($this, 'espresso_sponsors_post_box'),
2531
-                $this->_wp_page_slug,
2532
-                'side'
2533
-            );
2534
-        }
2535
-    }
2536
-
2537
-
2538
-    public function espresso_sponsors_post_box()
2539
-    {
2540
-        EEH_Template::display_template(
2541
-            EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php'
2542
-        );
2543
-    }
2544
-
2545
-
2546
-    private function _publish_post_box()
2547
-    {
2548
-        $meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview';
2549
-        // if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array
2550
-        // then we'll use that for the metabox label.
2551
-        // Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes)
2552
-        if (! empty($this->_labels['publishbox'])) {
2553
-            $box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][ $this->_req_action ]
2554
-                : $this->_labels['publishbox'];
2555
-        } else {
2556
-            $box_label = esc_html__('Publish', 'event_espresso');
2557
-        }
2558
-        $box_label = apply_filters(
2559
-            'FHEE__EE_Admin_Page___publish_post_box__box_label',
2560
-            $box_label,
2561
-            $this->_req_action,
2562
-            $this
2563
-        );
2564
-        add_meta_box(
2565
-            $meta_box_ref,
2566
-            $box_label,
2567
-            array($this, 'editor_overview'),
2568
-            $this->_current_screen->id,
2569
-            'side',
2570
-            'high'
2571
-        );
2572
-    }
2573
-
2574
-
2575
-    public function editor_overview()
2576
-    {
2577
-        // if we have extra content set let's add it in if not make sure its empty
2578
-        $this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2579
-            ? $this->_template_args['publish_box_extra_content']
2580
-            : '';
2581
-        echo EEH_Template::display_template(
2582
-            EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php',
2583
-            $this->_template_args,
2584
-            true
2585
-        );
2586
-    }
2587
-
2588
-
2589
-    /** end of globally available metaboxes section **/
2590
-
2591
-
2592
-    /**
2593
-     * Public wrapper for the protected method.  Allows plugins/addons to externally call the
2594
-     * protected method.
2595
-     *
2596
-     * @see   $this->_set_publish_post_box_vars for param details
2597
-     * @since 4.6.0
2598
-     * @param string $name
2599
-     * @param int    $id
2600
-     * @param bool   $delete
2601
-     * @param string $save_close_redirect_URL
2602
-     * @param bool   $both_btns
2603
-     * @throws EE_Error
2604
-     * @throws InvalidArgumentException
2605
-     * @throws InvalidDataTypeException
2606
-     * @throws InvalidInterfaceException
2607
-     */
2608
-    public function set_publish_post_box_vars(
2609
-        $name = '',
2610
-        $id = 0,
2611
-        $delete = false,
2612
-        $save_close_redirect_URL = '',
2613
-        $both_btns = true
2614
-    ) {
2615
-        $this->_set_publish_post_box_vars(
2616
-            $name,
2617
-            $id,
2618
-            $delete,
2619
-            $save_close_redirect_URL,
2620
-            $both_btns
2621
-        );
2622
-    }
2623
-
2624
-
2625
-    /**
2626
-     * Sets the _template_args arguments used by the _publish_post_box shortcut
2627
-     * Note: currently there is no validation for this.  However if you want the delete button, the
2628
-     * save, and save and close buttons to work properly, then you will want to include a
2629
-     * values for the name and id arguments.
2630
-     *
2631
-     * @todo  Add in validation for name/id arguments.
2632
-     * @param    string  $name                    key used for the action ID (i.e. event_id)
2633
-     * @param    int     $id                      id attached to the item published
2634
-     * @param    string  $delete                  page route callback for the delete action
2635
-     * @param    string  $save_close_redirect_URL custom URL to redirect to after Save & Close has been completed
2636
-     * @param    boolean $both_btns               whether to display BOTH the "Save & Close" and "Save" buttons or just
2637
-     *                                            the Save button
2638
-     * @throws EE_Error
2639
-     * @throws InvalidArgumentException
2640
-     * @throws InvalidDataTypeException
2641
-     * @throws InvalidInterfaceException
2642
-     */
2643
-    protected function _set_publish_post_box_vars(
2644
-        $name = '',
2645
-        $id = 0,
2646
-        $delete = '',
2647
-        $save_close_redirect_URL = '',
2648
-        $both_btns = true
2649
-    ) {
2650
-        // if Save & Close, use a custom redirect URL or default to the main page?
2651
-        $save_close_redirect_URL = ! empty($save_close_redirect_URL)
2652
-            ? $save_close_redirect_URL
2653
-            : $this->_admin_base_url;
2654
-        // create the Save & Close and Save buttons
2655
-        $this->_set_save_buttons($both_btns, array(), array(), $save_close_redirect_URL);
2656
-        // if we have extra content set let's add it in if not make sure its empty
2657
-        $this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2658
-            ? $this->_template_args['publish_box_extra_content']
2659
-            : '';
2660
-        if ($delete && ! empty($id)) {
2661
-            // make sure we have a default if just true is sent.
2662
-            $delete = ! empty($delete) ? $delete : 'delete';
2663
-            $delete_link_args = array($name => $id);
2664
-            $delete = $this->get_action_link_or_button(
2665
-                $delete,
2666
-                $delete,
2667
-                $delete_link_args,
2668
-                'submitdelete deletion'
2669
-            );
2670
-        }
2671
-        $this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : '';
2672
-        if (! empty($name) && ! empty($id)) {
2673
-            $hidden_field_arr[ $name ] = array(
2674
-                'type'  => 'hidden',
2675
-                'value' => $id,
2676
-            );
2677
-            $hf = $this->_generate_admin_form_fields($hidden_field_arr, 'array');
2678
-        } else {
2679
-            $hf = '';
2680
-        }
2681
-        // add hidden field
2682
-        $this->_template_args['publish_hidden_fields'] = is_array($hf) && ! empty($name)
2683
-            ? $hf[ $name ]['field']
2684
-            : $hf;
2685
-    }
2686
-
2687
-
2688
-    /**
2689
-     * displays an error message to ppl who have javascript disabled
2690
-     *
2691
-     * @return void
2692
-     */
2693
-    private function _display_no_javascript_warning()
2694
-    {
2695
-        ?>
2505
+	}
2506
+
2507
+
2508
+	private function _espresso_links_post_box()
2509
+	{
2510
+		// Hiding until we actually have content to put in here...
2511
+		// add_meta_box('espresso_links_post_box', esc_html__('Helpful Plugin Links', 'event_espresso'), array( $this, 'espresso_links_post_box'), $this->_wp_page_slug, 'side');
2512
+	}
2513
+
2514
+
2515
+	public function espresso_links_post_box()
2516
+	{
2517
+		// Hiding until we actually have content to put in here...
2518
+		// EEH_Template::display_template(
2519
+		//     EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_links.template.php'
2520
+		// );
2521
+	}
2522
+
2523
+
2524
+	protected function _espresso_sponsors_post_box()
2525
+	{
2526
+		if (apply_filters('FHEE_show_sponsors_meta_box', true)) {
2527
+			add_meta_box(
2528
+				'espresso_sponsors_post_box',
2529
+				esc_html__('Event Espresso Highlights', 'event_espresso'),
2530
+				array($this, 'espresso_sponsors_post_box'),
2531
+				$this->_wp_page_slug,
2532
+				'side'
2533
+			);
2534
+		}
2535
+	}
2536
+
2537
+
2538
+	public function espresso_sponsors_post_box()
2539
+	{
2540
+		EEH_Template::display_template(
2541
+			EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php'
2542
+		);
2543
+	}
2544
+
2545
+
2546
+	private function _publish_post_box()
2547
+	{
2548
+		$meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview';
2549
+		// if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array
2550
+		// then we'll use that for the metabox label.
2551
+		// Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes)
2552
+		if (! empty($this->_labels['publishbox'])) {
2553
+			$box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][ $this->_req_action ]
2554
+				: $this->_labels['publishbox'];
2555
+		} else {
2556
+			$box_label = esc_html__('Publish', 'event_espresso');
2557
+		}
2558
+		$box_label = apply_filters(
2559
+			'FHEE__EE_Admin_Page___publish_post_box__box_label',
2560
+			$box_label,
2561
+			$this->_req_action,
2562
+			$this
2563
+		);
2564
+		add_meta_box(
2565
+			$meta_box_ref,
2566
+			$box_label,
2567
+			array($this, 'editor_overview'),
2568
+			$this->_current_screen->id,
2569
+			'side',
2570
+			'high'
2571
+		);
2572
+	}
2573
+
2574
+
2575
+	public function editor_overview()
2576
+	{
2577
+		// if we have extra content set let's add it in if not make sure its empty
2578
+		$this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2579
+			? $this->_template_args['publish_box_extra_content']
2580
+			: '';
2581
+		echo EEH_Template::display_template(
2582
+			EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php',
2583
+			$this->_template_args,
2584
+			true
2585
+		);
2586
+	}
2587
+
2588
+
2589
+	/** end of globally available metaboxes section **/
2590
+
2591
+
2592
+	/**
2593
+	 * Public wrapper for the protected method.  Allows plugins/addons to externally call the
2594
+	 * protected method.
2595
+	 *
2596
+	 * @see   $this->_set_publish_post_box_vars for param details
2597
+	 * @since 4.6.0
2598
+	 * @param string $name
2599
+	 * @param int    $id
2600
+	 * @param bool   $delete
2601
+	 * @param string $save_close_redirect_URL
2602
+	 * @param bool   $both_btns
2603
+	 * @throws EE_Error
2604
+	 * @throws InvalidArgumentException
2605
+	 * @throws InvalidDataTypeException
2606
+	 * @throws InvalidInterfaceException
2607
+	 */
2608
+	public function set_publish_post_box_vars(
2609
+		$name = '',
2610
+		$id = 0,
2611
+		$delete = false,
2612
+		$save_close_redirect_URL = '',
2613
+		$both_btns = true
2614
+	) {
2615
+		$this->_set_publish_post_box_vars(
2616
+			$name,
2617
+			$id,
2618
+			$delete,
2619
+			$save_close_redirect_URL,
2620
+			$both_btns
2621
+		);
2622
+	}
2623
+
2624
+
2625
+	/**
2626
+	 * Sets the _template_args arguments used by the _publish_post_box shortcut
2627
+	 * Note: currently there is no validation for this.  However if you want the delete button, the
2628
+	 * save, and save and close buttons to work properly, then you will want to include a
2629
+	 * values for the name and id arguments.
2630
+	 *
2631
+	 * @todo  Add in validation for name/id arguments.
2632
+	 * @param    string  $name                    key used for the action ID (i.e. event_id)
2633
+	 * @param    int     $id                      id attached to the item published
2634
+	 * @param    string  $delete                  page route callback for the delete action
2635
+	 * @param    string  $save_close_redirect_URL custom URL to redirect to after Save & Close has been completed
2636
+	 * @param    boolean $both_btns               whether to display BOTH the "Save & Close" and "Save" buttons or just
2637
+	 *                                            the Save button
2638
+	 * @throws EE_Error
2639
+	 * @throws InvalidArgumentException
2640
+	 * @throws InvalidDataTypeException
2641
+	 * @throws InvalidInterfaceException
2642
+	 */
2643
+	protected function _set_publish_post_box_vars(
2644
+		$name = '',
2645
+		$id = 0,
2646
+		$delete = '',
2647
+		$save_close_redirect_URL = '',
2648
+		$both_btns = true
2649
+	) {
2650
+		// if Save & Close, use a custom redirect URL or default to the main page?
2651
+		$save_close_redirect_URL = ! empty($save_close_redirect_URL)
2652
+			? $save_close_redirect_URL
2653
+			: $this->_admin_base_url;
2654
+		// create the Save & Close and Save buttons
2655
+		$this->_set_save_buttons($both_btns, array(), array(), $save_close_redirect_URL);
2656
+		// if we have extra content set let's add it in if not make sure its empty
2657
+		$this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2658
+			? $this->_template_args['publish_box_extra_content']
2659
+			: '';
2660
+		if ($delete && ! empty($id)) {
2661
+			// make sure we have a default if just true is sent.
2662
+			$delete = ! empty($delete) ? $delete : 'delete';
2663
+			$delete_link_args = array($name => $id);
2664
+			$delete = $this->get_action_link_or_button(
2665
+				$delete,
2666
+				$delete,
2667
+				$delete_link_args,
2668
+				'submitdelete deletion'
2669
+			);
2670
+		}
2671
+		$this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : '';
2672
+		if (! empty($name) && ! empty($id)) {
2673
+			$hidden_field_arr[ $name ] = array(
2674
+				'type'  => 'hidden',
2675
+				'value' => $id,
2676
+			);
2677
+			$hf = $this->_generate_admin_form_fields($hidden_field_arr, 'array');
2678
+		} else {
2679
+			$hf = '';
2680
+		}
2681
+		// add hidden field
2682
+		$this->_template_args['publish_hidden_fields'] = is_array($hf) && ! empty($name)
2683
+			? $hf[ $name ]['field']
2684
+			: $hf;
2685
+	}
2686
+
2687
+
2688
+	/**
2689
+	 * displays an error message to ppl who have javascript disabled
2690
+	 *
2691
+	 * @return void
2692
+	 */
2693
+	private function _display_no_javascript_warning()
2694
+	{
2695
+		?>
2696 2696
         <noscript>
2697 2697
             <div id="no-js-message" class="error">
2698 2698
                 <p style="font-size:1.3em;">
2699 2699
                     <span style="color:red;"><?php esc_html_e('Warning!', 'event_espresso'); ?></span>
2700 2700
                     <?php esc_html_e(
2701
-                        'Javascript is currently turned off for your browser. Javascript must be enabled in order for all of the features on this page to function properly. Please turn your javascript back on.',
2702
-                        'event_espresso'
2703
-                    ); ?>
2701
+						'Javascript is currently turned off for your browser. Javascript must be enabled in order for all of the features on this page to function properly. Please turn your javascript back on.',
2702
+						'event_espresso'
2703
+					); ?>
2704 2704
                 </p>
2705 2705
             </div>
2706 2706
         </noscript>
2707 2707
         <?php
2708
-    }
2709
-
2710
-
2711
-    /**
2712
-     * displays espresso success and/or error notices
2713
-     *
2714
-     * @return void
2715
-     */
2716
-    private function _display_espresso_notices()
2717
-    {
2718
-        $notices = $this->_get_transient(true);
2719
-        echo stripslashes($notices);
2720
-    }
2721
-
2722
-
2723
-    /**
2724
-     * spinny things pacify the masses
2725
-     *
2726
-     * @return void
2727
-     */
2728
-    protected function _add_admin_page_ajax_loading_img()
2729
-    {
2730
-        ?>
2708
+	}
2709
+
2710
+
2711
+	/**
2712
+	 * displays espresso success and/or error notices
2713
+	 *
2714
+	 * @return void
2715
+	 */
2716
+	private function _display_espresso_notices()
2717
+	{
2718
+		$notices = $this->_get_transient(true);
2719
+		echo stripslashes($notices);
2720
+	}
2721
+
2722
+
2723
+	/**
2724
+	 * spinny things pacify the masses
2725
+	 *
2726
+	 * @return void
2727
+	 */
2728
+	protected function _add_admin_page_ajax_loading_img()
2729
+	{
2730
+		?>
2731 2731
         <div id="espresso-ajax-loading" class="ajax-loading-grey">
2732 2732
             <span class="ee-spinner ee-spin"></span><span class="hidden"><?php
2733
-                esc_html_e('loading...', 'event_espresso'); ?></span>
2733
+				esc_html_e('loading...', 'event_espresso'); ?></span>
2734 2734
         </div>
2735 2735
         <?php
2736
-    }
2736
+	}
2737 2737
 
2738 2738
 
2739
-    /**
2740
-     * add admin page overlay for modal boxes
2741
-     *
2742
-     * @return void
2743
-     */
2744
-    protected function _add_admin_page_overlay()
2745
-    {
2746
-        ?>
2739
+	/**
2740
+	 * add admin page overlay for modal boxes
2741
+	 *
2742
+	 * @return void
2743
+	 */
2744
+	protected function _add_admin_page_overlay()
2745
+	{
2746
+		?>
2747 2747
         <div id="espresso-admin-page-overlay-dv" class=""></div>
2748 2748
         <?php
2749
-    }
2750
-
2751
-
2752
-    /**
2753
-     * facade for add_meta_box
2754
-     *
2755
-     * @param string  $action        where the metabox get's displayed
2756
-     * @param string  $title         Title of Metabox (output in metabox header)
2757
-     * @param string  $callback      If not empty and $create_fun is set to false then we'll use a custom callback
2758
-     *                               instead of the one created in here.
2759
-     * @param array   $callback_args an array of args supplied for the metabox
2760
-     * @param string  $column        what metabox column
2761
-     * @param string  $priority      give this metabox a priority (using accepted priorities for wp meta boxes)
2762
-     * @param boolean $create_func   default is true.  Basically we can say we don't WANT to have the runtime function
2763
-     *                               created but just set our own callback for wp's add_meta_box.
2764
-     * @throws DomainException
2765
-     */
2766
-    public function _add_admin_page_meta_box(
2767
-        $action,
2768
-        $title,
2769
-        $callback,
2770
-        $callback_args,
2771
-        $column = 'normal',
2772
-        $priority = 'high',
2773
-        $create_func = true
2774
-    ) {
2775
-        do_action('AHEE_log', __FILE__, __FUNCTION__, $callback);
2776
-        // if we have empty callback args and we want to automatically create the metabox callback then we need to make sure the callback args are generated.
2777
-        if (empty($callback_args) && $create_func) {
2778
-            $callback_args = array(
2779
-                'template_path' => $this->_template_path,
2780
-                'template_args' => $this->_template_args,
2781
-            );
2782
-        }
2783
-        // if $create_func is true (default) then we automatically create the function for displaying the actual meta box.  If false then we take the $callback reference passed through and use it instead (so callers can define their own callback function/method if they wish)
2784
-        $call_back_func = $create_func
2785
-            ? static function ($post, $metabox) {
2786
-                do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2787
-                echo EEH_Template::display_template(
2788
-                    $metabox['args']['template_path'],
2789
-                    $metabox['args']['template_args'],
2790
-                    true
2791
-                );
2792
-            }
2793
-            : $callback;
2794
-        add_meta_box(
2795
-            str_replace('_', '-', $action) . '-mbox',
2796
-            $title,
2797
-            $call_back_func,
2798
-            $this->_wp_page_slug,
2799
-            $column,
2800
-            $priority,
2801
-            $callback_args
2802
-        );
2803
-    }
2804
-
2805
-
2806
-    /**
2807
-     * generates HTML wrapper for and admin details page that contains metaboxes in columns
2808
-     *
2809
-     * @throws DomainException
2810
-     * @throws EE_Error
2811
-     * @throws InvalidArgumentException
2812
-     * @throws InvalidDataTypeException
2813
-     * @throws InvalidInterfaceException
2814
-     */
2815
-    public function display_admin_page_with_metabox_columns()
2816
-    {
2817
-        $this->_template_args['post_body_content'] = $this->_template_args['admin_page_content'];
2818
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2819
-            $this->_column_template_path,
2820
-            $this->_template_args,
2821
-            true
2822
-        );
2823
-        // the final wrapper
2824
-        $this->admin_page_wrapper();
2825
-    }
2826
-
2827
-
2828
-    /**
2829
-     * generates  HTML wrapper for an admin details page
2830
-     *
2831
-     * @return void
2832
-     * @throws DomainException
2833
-     * @throws EE_Error
2834
-     * @throws InvalidArgumentException
2835
-     * @throws InvalidDataTypeException
2836
-     * @throws InvalidInterfaceException
2837
-     */
2838
-    public function display_admin_page_with_sidebar()
2839
-    {
2840
-        $this->_display_admin_page(true);
2841
-    }
2842
-
2843
-
2844
-    /**
2845
-     * generates  HTML wrapper for an admin details page (except no sidebar)
2846
-     *
2847
-     * @return void
2848
-     * @throws DomainException
2849
-     * @throws EE_Error
2850
-     * @throws InvalidArgumentException
2851
-     * @throws InvalidDataTypeException
2852
-     * @throws InvalidInterfaceException
2853
-     */
2854
-    public function display_admin_page_with_no_sidebar()
2855
-    {
2856
-        $this->_display_admin_page();
2857
-    }
2858
-
2859
-
2860
-    /**
2861
-     * generates HTML wrapper for an EE about admin page (no sidebar)
2862
-     *
2863
-     * @return void
2864
-     * @throws DomainException
2865
-     * @throws EE_Error
2866
-     * @throws InvalidArgumentException
2867
-     * @throws InvalidDataTypeException
2868
-     * @throws InvalidInterfaceException
2869
-     */
2870
-    public function display_about_admin_page()
2871
-    {
2872
-        $this->_display_admin_page(false, true);
2873
-    }
2874
-
2875
-
2876
-    /**
2877
-     * display_admin_page
2878
-     * contains the code for actually displaying an admin page
2879
-     *
2880
-     * @param boolean $sidebar true with sidebar, false without
2881
-     * @param boolean $about   use the about admin wrapper instead of the default.
2882
-     * @return void
2883
-     * @throws DomainException
2884
-     * @throws EE_Error
2885
-     * @throws InvalidArgumentException
2886
-     * @throws InvalidDataTypeException
2887
-     * @throws InvalidInterfaceException
2888
-     */
2889
-    private function _display_admin_page($sidebar = false, $about = false)
2890
-    {
2891
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2892
-        // custom remove metaboxes hook to add or remove any metaboxes to/from Admin pages.
2893
-        do_action('AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes');
2894
-        // set current wp page slug - looks like: event-espresso_page_event_categories
2895
-        // keep in mind "event-espresso" COULD be something else if the top level menu label has been translated.
2896
-        $this->_template_args['current_page'] = $this->_wp_page_slug;
2897
-        $this->_template_args['admin_page_wrapper_div_id'] = $this->_cpt_route
2898
-            ? 'poststuff'
2899
-            : 'espresso-default-admin';
2900
-        $template_path = $sidebar
2901
-            ? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php'
2902
-            : EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php';
2903
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2904
-            $template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php';
2905
-        }
2906
-        $template_path = ! empty($this->_column_template_path)
2907
-            ? $this->_column_template_path : $template_path;
2908
-        $this->_template_args['post_body_content'] = isset($this->_template_args['admin_page_content'])
2909
-            ? $this->_template_args['admin_page_content']
2910
-            : '';
2911
-        $this->_template_args['before_admin_page_content'] = isset($this->_template_args['before_admin_page_content'])
2912
-            ? $this->_template_args['before_admin_page_content']
2913
-            : '';
2914
-        $this->_template_args['after_admin_page_content'] = isset($this->_template_args['after_admin_page_content'])
2915
-            ? $this->_template_args['after_admin_page_content']
2916
-            : '';
2917
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2918
-            $template_path,
2919
-            $this->_template_args,
2920
-            true
2921
-        );
2922
-        // the final template wrapper
2923
-        $this->admin_page_wrapper($about);
2924
-    }
2925
-
2926
-
2927
-    /**
2928
-     * This is used to display caf preview pages.
2929
-     *
2930
-     * @since 4.3.2
2931
-     * @param string $utm_campaign_source what is the key used for google analytics link
2932
-     * @param bool   $display_sidebar     whether to use the sidebar template or the full template for the page.  TRUE
2933
-     *                                    = SHOW sidebar, FALSE = no sidebar. Default no sidebar.
2934
-     * @return void
2935
-     * @throws DomainException
2936
-     * @throws EE_Error
2937
-     * @throws InvalidArgumentException
2938
-     * @throws InvalidDataTypeException
2939
-     * @throws InvalidInterfaceException
2940
-     */
2941
-    public function display_admin_caf_preview_page($utm_campaign_source = '', $display_sidebar = true)
2942
-    {
2943
-        // let's generate a default preview action button if there isn't one already present.
2944
-        $this->_labels['buttons']['buy_now'] = esc_html__(
2945
-            'Upgrade to Event Espresso 4 Right Now',
2946
-            'event_espresso'
2947
-        );
2948
-        $buy_now_url = add_query_arg(
2949
-            array(
2950
-                'ee_ver'       => 'ee4',
2951
-                'utm_source'   => 'ee4_plugin_admin',
2952
-                'utm_medium'   => 'link',
2953
-                'utm_campaign' => $utm_campaign_source,
2954
-                'utm_content'  => 'buy_now_button',
2955
-            ),
2956
-            'http://eventespresso.com/pricing/'
2957
-        );
2958
-        $this->_template_args['preview_action_button'] = ! isset($this->_template_args['preview_action_button'])
2959
-            ? $this->get_action_link_or_button(
2960
-                '',
2961
-                'buy_now',
2962
-                array(),
2963
-                'button-primary button-large',
2964
-                $buy_now_url,
2965
-                true
2966
-            )
2967
-            : $this->_template_args['preview_action_button'];
2968
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2969
-            EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php',
2970
-            $this->_template_args,
2971
-            true
2972
-        );
2973
-        $this->_display_admin_page($display_sidebar);
2974
-    }
2975
-
2976
-
2977
-    /**
2978
-     * display_admin_list_table_page_with_sidebar
2979
-     * generates HTML wrapper for an admin_page with list_table
2980
-     *
2981
-     * @return void
2982
-     * @throws DomainException
2983
-     * @throws EE_Error
2984
-     * @throws InvalidArgumentException
2985
-     * @throws InvalidDataTypeException
2986
-     * @throws InvalidInterfaceException
2987
-     */
2988
-    public function display_admin_list_table_page_with_sidebar()
2989
-    {
2990
-        $this->_display_admin_list_table_page(true);
2991
-    }
2992
-
2993
-
2994
-    /**
2995
-     * display_admin_list_table_page_with_no_sidebar
2996
-     * generates HTML wrapper for an admin_page with list_table (but with no sidebar)
2997
-     *
2998
-     * @return void
2999
-     * @throws DomainException
3000
-     * @throws EE_Error
3001
-     * @throws InvalidArgumentException
3002
-     * @throws InvalidDataTypeException
3003
-     * @throws InvalidInterfaceException
3004
-     */
3005
-    public function display_admin_list_table_page_with_no_sidebar()
3006
-    {
3007
-        $this->_display_admin_list_table_page();
3008
-    }
3009
-
3010
-
3011
-    /**
3012
-     * generates html wrapper for an admin_list_table page
3013
-     *
3014
-     * @param boolean $sidebar whether to display with sidebar or not.
3015
-     * @return void
3016
-     * @throws DomainException
3017
-     * @throws EE_Error
3018
-     * @throws InvalidArgumentException
3019
-     * @throws InvalidDataTypeException
3020
-     * @throws InvalidInterfaceException
3021
-     */
3022
-    private function _display_admin_list_table_page($sidebar = false)
3023
-    {
3024
-        // setup search attributes
3025
-        $this->_set_search_attributes();
3026
-        $this->_template_args['current_page'] = $this->_wp_page_slug;
3027
-        $template_path = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php';
3028
-        $this->_template_args['table_url'] = defined('DOING_AJAX')
3029
-            ? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url)
3030
-            : add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url);
3031
-        $this->_template_args['list_table'] = $this->_list_table_object;
3032
-        $this->_template_args['current_route'] = $this->_req_action;
3033
-        $this->_template_args['list_table_class'] = get_class($this->_list_table_object);
3034
-        $ajax_sorting_callback = $this->_list_table_object->get_ajax_sorting_callback();
3035
-        if (! empty($ajax_sorting_callback)) {
3036
-            $sortable_list_table_form_fields = wp_nonce_field(
3037
-                $ajax_sorting_callback . '_nonce',
3038
-                $ajax_sorting_callback . '_nonce',
3039
-                false,
3040
-                false
3041
-            );
3042
-            $sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_page" name="ajax_table_sort_page" value="'
3043
-                                                . $this->page_slug
3044
-                                                . '" />';
3045
-            $sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_action" name="ajax_table_sort_action" value="'
3046
-                                                . $ajax_sorting_callback
3047
-                                                . '" />';
3048
-        } else {
3049
-            $sortable_list_table_form_fields = '';
3050
-        }
3051
-        $this->_template_args['sortable_list_table_form_fields'] = $sortable_list_table_form_fields;
3052
-        $hidden_form_fields = isset($this->_template_args['list_table_hidden_fields'])
3053
-            ? $this->_template_args['list_table_hidden_fields']
3054
-            : '';
3055
-        $nonce_ref = $this->_req_action . '_nonce';
3056
-        $hidden_form_fields .= '<input type="hidden" name="'
3057
-                               . $nonce_ref
3058
-                               . '" value="'
3059
-                               . wp_create_nonce($nonce_ref)
3060
-                               . '">';
3061
-        $this->_template_args['list_table_hidden_fields'] = $hidden_form_fields;
3062
-        // display message about search results?
3063
-        $this->_template_args['before_list_table'] .= ! empty($this->_req_data['s'])
3064
-            ? '<p class="ee-search-results">' . sprintf(
3065
-                esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'),
3066
-                trim($this->_req_data['s'], '%')
3067
-            ) . '</p>'
3068
-            : '';
3069
-        // filter before_list_table template arg
3070
-        $this->_template_args['before_list_table'] = apply_filters(
3071
-            'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_arg',
3072
-            $this->_template_args['before_list_table'],
3073
-            $this->page_slug,
3074
-            $this->_req_data,
3075
-            $this->_req_action
3076
-        );
3077
-        // convert to array and filter again
3078
-        // arrays are easier to inject new items in a specific location,
3079
-        // but would not be backwards compatible, so we have to add a new filter
3080
-        $this->_template_args['before_list_table'] = implode(
3081
-            " \n",
3082
-            (array) apply_filters(
3083
-                'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_args_array',
3084
-                (array) $this->_template_args['before_list_table'],
3085
-                $this->page_slug,
3086
-                $this->_req_data,
3087
-                $this->_req_action
3088
-            )
3089
-        );
3090
-        // filter after_list_table template arg
3091
-        $this->_template_args['after_list_table'] = apply_filters(
3092
-            'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_arg',
3093
-            $this->_template_args['after_list_table'],
3094
-            $this->page_slug,
3095
-            $this->_req_data,
3096
-            $this->_req_action
3097
-        );
3098
-        // convert to array and filter again
3099
-        // arrays are easier to inject new items in a specific location,
3100
-        // but would not be backwards compatible, so we have to add a new filter
3101
-        $this->_template_args['after_list_table'] = implode(
3102
-            " \n",
3103
-            (array) apply_filters(
3104
-                'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_args_array',
3105
-                (array) $this->_template_args['after_list_table'],
3106
-                $this->page_slug,
3107
-                $this->_req_data,
3108
-                $this->_req_action
3109
-            )
3110
-        );
3111
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
3112
-            $template_path,
3113
-            $this->_template_args,
3114
-            true
3115
-        );
3116
-        // the final template wrapper
3117
-        if ($sidebar) {
3118
-            $this->display_admin_page_with_sidebar();
3119
-        } else {
3120
-            $this->display_admin_page_with_no_sidebar();
3121
-        }
3122
-    }
3123
-
3124
-
3125
-    /**
3126
-     * This just prepares a legend using the given items and the admin_details_legend.template.php file and returns the
3127
-     * html string for the legend.
3128
-     * $items are expected in an array in the following format:
3129
-     * $legend_items = array(
3130
-     *        'item_id' => array(
3131
-     *            'icon' => 'http://url_to_icon_being_described.png',
3132
-     *            'desc' => esc_html__('localized description of item');
3133
-     *        )
3134
-     * );
3135
-     *
3136
-     * @param  array $items see above for format of array
3137
-     * @return string html string of legend
3138
-     * @throws DomainException
3139
-     */
3140
-    protected function _display_legend($items)
3141
-    {
3142
-        $this->_template_args['items'] = apply_filters(
3143
-            'FHEE__EE_Admin_Page___display_legend__items',
3144
-            (array) $items,
3145
-            $this
3146
-        );
3147
-        $this->_template_args['status_change_notice'] = EEH_Template::display_template(
3148
-            EE_ADMIN_TEMPLATE . 'status_change_notice.template.php',
3149
-            [ 'context' => '__admin-legend' ],
3150
-            true
3151
-        );
3152
-        return EEH_Template::display_template(
3153
-            EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php',
3154
-            $this->_template_args,
3155
-            true
3156
-        );
3157
-    }
3158
-
3159
-
3160
-    /**
3161
-     * This is used whenever we're DOING_AJAX to return a formatted json array that our calling javascript can expect
3162
-     * The returned json object is created from an array in the following format:
3163
-     * array(
3164
-     *  'error' => FALSE, //(default FALSE), contains any errors and/or exceptions (exceptions return json early),
3165
-     *  'success' => FALSE, //(default FALSE) - contains any special success message.
3166
-     *  'notices' => '', // - contains any EE_Error formatted notices
3167
-     *  'content' => 'string can be html', //this is a string of formatted content (can be html)
3168
-     *  'data' => array() //this can be any key/value pairs that a method returns for later json parsing by the js.
3169
-     *  We're also going to include the template args with every package (so js can pick out any specific template args
3170
-     *  that might be included in here)
3171
-     * )
3172
-     * The json object is populated by whatever is set in the $_template_args property.
3173
-     *
3174
-     * @param bool  $sticky_notices    Used to indicate whether you want to ensure notices are added to a transient
3175
-     *                                 instead of displayed.
3176
-     * @param array $notices_arguments Use this to pass any additional args on to the _process_notices.
3177
-     * @return void
3178
-     * @throws EE_Error
3179
-     * @throws InvalidArgumentException
3180
-     * @throws InvalidDataTypeException
3181
-     * @throws InvalidInterfaceException
3182
-     */
3183
-    protected function _return_json($sticky_notices = false, $notices_arguments = array())
3184
-    {
3185
-        // make sure any EE_Error notices have been handled.
3186
-        $this->_process_notices($notices_arguments, true, $sticky_notices);
3187
-        $data = isset($this->_template_args['data']) ? $this->_template_args['data'] : array();
3188
-        unset($this->_template_args['data']);
3189
-        $json = array(
3190
-            'error'     => isset($this->_template_args['error']) ? $this->_template_args['error'] : false,
3191
-            'success'   => isset($this->_template_args['success']) ? $this->_template_args['success'] : false,
3192
-            'errors'    => isset($this->_template_args['errors']) ? $this->_template_args['errors'] : false,
3193
-            'attention' => isset($this->_template_args['attention']) ? $this->_template_args['attention'] : false,
3194
-            'notices'   => EE_Error::get_notices(),
3195
-            'content'   => isset($this->_template_args['admin_page_content'])
3196
-                ? $this->_template_args['admin_page_content'] : '',
3197
-            'data'      => array_merge($data, array('template_args' => $this->_template_args)),
3198
-            'isEEajax'  => true
3199
-            // special flag so any ajax.Success methods in js can identify this return package as a EEajax package.
3200
-        );
3201
-        // make sure there are no php errors or headers_sent.  Then we can set correct json header.
3202
-        if (null === error_get_last() || ! headers_sent()) {
3203
-            header('Content-Type: application/json; charset=UTF-8');
3204
-        }
3205
-        echo wp_json_encode($json);
3206
-        exit();
3207
-    }
3208
-
3209
-
3210
-    /**
3211
-     * Simply a wrapper for the protected method so we can call this outside the class (ONLY when doing ajax)
3212
-     *
3213
-     * @return void
3214
-     * @throws EE_Error
3215
-     * @throws InvalidArgumentException
3216
-     * @throws InvalidDataTypeException
3217
-     * @throws InvalidInterfaceException
3218
-     */
3219
-    public function return_json()
3220
-    {
3221
-        if (defined('DOING_AJAX') && DOING_AJAX) {
3222
-            $this->_return_json();
3223
-        } else {
3224
-            throw new EE_Error(
3225
-                sprintf(
3226
-                    esc_html__('The public %s method can only be called when DOING_AJAX = TRUE', 'event_espresso'),
3227
-                    __FUNCTION__
3228
-                )
3229
-            );
3230
-        }
3231
-    }
3232
-
3233
-
3234
-    /**
3235
-     * This provides a way for child hook classes to send along themselves by reference so methods/properties within
3236
-     * them can be accessed by EE_Admin_child pages. This is assigned to the $_hook_obj property.
3237
-     *
3238
-     * @param EE_Admin_Hooks $hook_obj This will be the object for the EE_Admin_Hooks child
3239
-     */
3240
-    public function set_hook_object(EE_Admin_Hooks $hook_obj)
3241
-    {
3242
-        $this->_hook_obj = $hook_obj;
3243
-    }
3244
-
3245
-
3246
-    /**
3247
-     *        generates  HTML wrapper with Tabbed nav for an admin page
3248
-     *
3249
-     * @param boolean $about whether to use the special about page wrapper or default.
3250
-     * @return void
3251
-     * @throws DomainException
3252
-     * @throws EE_Error
3253
-     * @throws InvalidArgumentException
3254
-     * @throws InvalidDataTypeException
3255
-     * @throws InvalidInterfaceException
3256
-     */
3257
-    public function admin_page_wrapper($about = false)
3258
-    {
3259
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3260
-        $this->_nav_tabs = $this->_get_main_nav_tabs();
3261
-        $this->_template_args['nav_tabs'] = $this->_nav_tabs;
3262
-        $this->_template_args['admin_page_title'] = $this->_admin_page_title;
3263
-        $this->_template_args['before_admin_page_content'] = apply_filters(
3264
-            "FHEE_before_admin_page_content{$this->_current_page}{$this->_current_view}",
3265
-            isset($this->_template_args['before_admin_page_content'])
3266
-                ? $this->_template_args['before_admin_page_content']
3267
-                : ''
3268
-        );
3269
-        $this->_template_args['after_admin_page_content'] = apply_filters(
3270
-            "FHEE_after_admin_page_content{$this->_current_page}{$this->_current_view}",
3271
-            isset($this->_template_args['after_admin_page_content'])
3272
-                ? $this->_template_args['after_admin_page_content']
3273
-                : ''
3274
-        );
3275
-        $this->_template_args['after_admin_page_content'] .= $this->_set_help_popup_content();
3276
-        // load settings page wrapper template
3277
-        $template_path = ! defined('DOING_AJAX')
3278
-            ? EE_ADMIN_TEMPLATE . 'admin_wrapper.template.php'
3279
-            : EE_ADMIN_TEMPLATE
3280
-              . 'admin_wrapper_ajax.template.php';
3281
-        // about page?
3282
-        $template_path = $about
3283
-            ? EE_ADMIN_TEMPLATE . 'about_admin_wrapper.template.php'
3284
-            : $template_path;
3285
-        if (defined('DOING_AJAX')) {
3286
-            $this->_template_args['admin_page_content'] = EEH_Template::display_template(
3287
-                $template_path,
3288
-                $this->_template_args,
3289
-                true
3290
-            );
3291
-            $this->_return_json();
3292
-        } else {
3293
-            EEH_Template::display_template($template_path, $this->_template_args);
3294
-        }
3295
-    }
3296
-
3297
-
3298
-    /**
3299
-     * This returns the admin_nav tabs html using the configuration in the _nav_tabs property
3300
-     *
3301
-     * @return string html
3302
-     * @throws EE_Error
3303
-     */
3304
-    protected function _get_main_nav_tabs()
3305
-    {
3306
-        // let's generate the html using the EEH_Tabbed_Content helper.
3307
-        // We do this here so that it's possible for child classes to add in nav tabs dynamically at the last minute
3308
-        // (rather than setting in the page_routes array)
3309
-        return EEH_Tabbed_Content::display_admin_nav_tabs($this->_nav_tabs);
3310
-    }
3311
-
3312
-
3313
-    /**
3314
-     *        sort nav tabs
3315
-     *
3316
-     * @param $a
3317
-     * @param $b
3318
-     * @return int
3319
-     */
3320
-    private function _sort_nav_tabs($a, $b)
3321
-    {
3322
-        if ($a['order'] === $b['order']) {
3323
-            return 0;
3324
-        }
3325
-        return ($a['order'] < $b['order']) ? -1 : 1;
3326
-    }
3327
-
3328
-
3329
-    /**
3330
-     *    generates HTML for the forms used on admin pages
3331
-     *
3332
-     * @param    array $input_vars - array of input field details
3333
-     * @param string   $generator  (options are 'string' or 'array', basically use this to indicate which generator to
3334
-     *                             use)
3335
-     * @param bool     $id
3336
-     * @return string
3337
-     * @uses   EEH_Form_Fields::get_form_fields (/helper/EEH_Form_Fields.helper.php)
3338
-     * @uses   EEH_Form_Fields::get_form_fields_array (/helper/EEH_Form_Fields.helper.php)
3339
-     */
3340
-    protected function _generate_admin_form_fields($input_vars = array(), $generator = 'string', $id = false)
3341
-    {
3342
-        return $generator === 'string'
3343
-            ? EEH_Form_Fields::get_form_fields($input_vars, $id)
3344
-            : EEH_Form_Fields::get_form_fields_array($input_vars);
3345
-    }
3346
-
3347
-
3348
-    /**
3349
-     * generates the "Save" and "Save & Close" buttons for edit forms
3350
-     *
3351
-     * @param bool             $both     if true then both buttons will be generated.  If false then just the "Save &
3352
-     *                                   Close" button.
3353
-     * @param array            $text     if included, generator will use the given text for the buttons ( array([0] =>
3354
-     *                                   'Save', [1] => 'save & close')
3355
-     * @param array            $actions  if included allows us to set the actions that each button will carry out (i.e.
3356
-     *                                   via the "name" value in the button).  We can also use this to just dump
3357
-     *                                   default actions by submitting some other value.
3358
-     * @param bool|string|null $referrer if false then we just do the default action on save and close.  Other wise it
3359
-     *                                   will use the $referrer string. IF null, then we don't do ANYTHING on save and
3360
-     *                                   close (normal form handling).
3361
-     */
3362
-    protected function _set_save_buttons($both = true, $text = array(), $actions = array(), $referrer = null)
3363
-    {
3364
-        // make sure $text and $actions are in an array
3365
-        $text = (array) $text;
3366
-        $actions = (array) $actions;
3367
-        $referrer_url = empty($referrer)
3368
-            ? '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3369
-              . $_SERVER['REQUEST_URI']
3370
-              . '" />'
3371
-            : '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3372
-              . $referrer
3373
-              . '" />';
3374
-        $button_text = ! empty($text)
3375
-            ? $text
3376
-            : array(
3377
-                esc_html__('Save', 'event_espresso'),
3378
-                esc_html__('Save and Close', 'event_espresso'),
3379
-            );
3380
-        $default_names = array('save', 'save_and_close');
3381
-        // add in a hidden index for the current page (so save and close redirects properly)
3382
-        $this->_template_args['save_buttons'] = $referrer_url;
3383
-        foreach ($button_text as $key => $button) {
3384
-            $ref = $default_names[ $key ];
3385
-            $this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary '
3386
-                                                     . $ref
3387
-                                                     . '" value="'
3388
-                                                     . $button
3389
-                                                     . '" name="'
3390
-                                                     . (! empty($actions) ? $actions[ $key ] : $ref)
3391
-                                                     . '" id="'
3392
-                                                     . $this->_current_view . '_' . $ref
3393
-                                                     . '" />';
3394
-            if (! $both) {
3395
-                break;
3396
-            }
3397
-        }
3398
-    }
3399
-
3400
-
3401
-    /**
3402
-     * Wrapper for the protected function.  Allows plugins/addons to call this to set the form tags.
3403
-     *
3404
-     * @see   $this->_set_add_edit_form_tags() for details on params
3405
-     * @since 4.6.0
3406
-     * @param string $route
3407
-     * @param array  $additional_hidden_fields
3408
-     */
3409
-    public function set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3410
-    {
3411
-        $this->_set_add_edit_form_tags($route, $additional_hidden_fields);
3412
-    }
3413
-
3414
-
3415
-    /**
3416
-     * set form open and close tags on add/edit pages.
3417
-     *
3418
-     * @param string $route                    the route you want the form to direct to
3419
-     * @param array  $additional_hidden_fields any additional hidden fields required in the form header
3420
-     * @return void
3421
-     */
3422
-    protected function _set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3423
-    {
3424
-        if (empty($route)) {
3425
-            $user_msg = esc_html__(
3426
-                'An error occurred. No action was set for this page\'s form.',
3427
-                'event_espresso'
3428
-            );
3429
-            $dev_msg = $user_msg . "\n"
3430
-                       . sprintf(
3431
-                           esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'),
3432
-                           __FUNCTION__,
3433
-                           EE_Admin_Page::class
3434
-                       );
3435
-            EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
3436
-        }
3437
-        // open form
3438
-        $this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="'
3439
-                                                             . $this->_admin_base_url
3440
-                                                             . '" id="'
3441
-                                                             . $route
3442
-                                                             . '_event_form" >';
3443
-        // add nonce
3444
-        $nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false);
3445
-        $this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce;
3446
-        // add REQUIRED form action
3447
-        $hidden_fields = array(
3448
-            'action' => array('type' => 'hidden', 'value' => $route),
3449
-        );
3450
-        // merge arrays
3451
-        $hidden_fields = is_array($additional_hidden_fields)
3452
-            ? array_merge($hidden_fields, $additional_hidden_fields)
3453
-            : $hidden_fields;
3454
-        // generate form fields
3455
-        $form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array');
3456
-        // add fields to form
3457
-        foreach ((array) $form_fields as $field_name => $form_field) {
3458
-            $this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field'];
3459
-        }
3460
-        // close form
3461
-        $this->_template_args['after_admin_page_content'] = '</form>';
3462
-    }
3463
-
3464
-
3465
-    /**
3466
-     * Public Wrapper for _redirect_after_action() method since its
3467
-     * discovered it would be useful for external code to have access.
3468
-     *
3469
-     * @param bool   $success
3470
-     * @param string $what
3471
-     * @param string $action_desc
3472
-     * @param array  $query_args
3473
-     * @param bool   $override_overwrite
3474
-     * @throws EE_Error
3475
-     * @throws InvalidArgumentException
3476
-     * @throws InvalidDataTypeException
3477
-     * @throws InvalidInterfaceException
3478
-     * @see   EE_Admin_Page::_redirect_after_action() for params.
3479
-     * @since 4.5.0
3480
-     */
3481
-    public function redirect_after_action(
3482
-        $success = false,
3483
-        $what = 'item',
3484
-        $action_desc = 'processed',
3485
-        $query_args = array(),
3486
-        $override_overwrite = false
3487
-    ) {
3488
-        $this->_redirect_after_action(
3489
-            $success,
3490
-            $what,
3491
-            $action_desc,
3492
-            $query_args,
3493
-            $override_overwrite
3494
-        );
3495
-    }
3496
-
3497
-
3498
-    /**
3499
-     * Helper method for merging existing request data with the returned redirect url.
3500
-     *
3501
-     * This is typically used for redirects after an action so that if the original view was a filtered view those
3502
-     * filters are still applied.
3503
-     *
3504
-     * @param array $new_route_data
3505
-     * @return array
3506
-     */
3507
-    protected function mergeExistingRequestParamsWithRedirectArgs(array $new_route_data)
3508
-    {
3509
-        foreach ($this->_req_data as $ref => $value) {
3510
-            // unset nonces
3511
-            if (strpos($ref, 'nonce') !== false) {
3512
-                unset($this->_req_data[ $ref ]);
3513
-                continue;
3514
-            }
3515
-            // urlencode values.
3516
-            $value = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
3517
-            $this->_req_data[ $ref ] = $value;
3518
-        }
3519
-        return array_merge($this->_req_data, $new_route_data);
3520
-    }
3521
-
3522
-
3523
-    /**
3524
-     *    _redirect_after_action
3525
-     *
3526
-     * @param int    $success            - whether success was for two or more records, or just one, or none
3527
-     * @param string $what               - what the action was performed on
3528
-     * @param string $action_desc        - what was done ie: updated, deleted, etc
3529
-     * @param array  $query_args         - an array of query_args to be added to the URL to redirect to after the admin
3530
-     *                                   action is completed
3531
-     * @param BOOL   $override_overwrite by default all EE_Error::success messages are overwritten, this allows you to
3532
-     *                                   override this so that they show.
3533
-     * @return void
3534
-     * @throws EE_Error
3535
-     * @throws InvalidArgumentException
3536
-     * @throws InvalidDataTypeException
3537
-     * @throws InvalidInterfaceException
3538
-     */
3539
-    protected function _redirect_after_action(
3540
-        $success = 0,
3541
-        $what = 'item',
3542
-        $action_desc = 'processed',
3543
-        $query_args = array(),
3544
-        $override_overwrite = false
3545
-    ) {
3546
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3547
-        // class name for actions/filters.
3548
-        $classname = get_class($this);
3549
-        // set redirect url.
3550
-        // Note if there is a "page" index in the $query_args then we go with vanilla admin.php route,
3551
-        // otherwise we go with whatever is set as the _admin_base_url
3552
-        $redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url;
3553
-        $notices = EE_Error::get_notices(false);
3554
-        // overwrite default success messages //BUT ONLY if overwrite not overridden
3555
-        if (! $override_overwrite || ! empty($notices['errors'])) {
3556
-            EE_Error::overwrite_success();
3557
-        }
3558
-        if (! empty($what) && ! empty($action_desc) && empty($notices['errors'])) {
3559
-            // how many records affected ? more than one record ? or just one ?
3560
-            if ($success > 1) {
3561
-                // set plural msg
3562
-                EE_Error::add_success(
3563
-                    sprintf(
3564
-                        esc_html__('The "%s" have been successfully %s.', 'event_espresso'),
3565
-                        $what,
3566
-                        $action_desc
3567
-                    ),
3568
-                    __FILE__,
3569
-                    __FUNCTION__,
3570
-                    __LINE__
3571
-                );
3572
-            } elseif ($success === 1) {
3573
-                // set singular msg
3574
-                EE_Error::add_success(
3575
-                    sprintf(
3576
-                        esc_html__('The "%s" has been successfully %s.', 'event_espresso'),
3577
-                        $what,
3578
-                        $action_desc
3579
-                    ),
3580
-                    __FILE__,
3581
-                    __FUNCTION__,
3582
-                    __LINE__
3583
-                );
3584
-            }
3585
-        }
3586
-        // check that $query_args isn't something crazy
3587
-        if (! is_array($query_args)) {
3588
-            $query_args = array();
3589
-        }
3590
-        /**
3591
-         * Allow injecting actions before the query_args are modified for possible different
3592
-         * redirections on save and close actions
3593
-         *
3594
-         * @since 4.2.0
3595
-         * @param array $query_args       The original query_args array coming into the
3596
-         *                                method.
3597
-         */
3598
-        do_action(
3599
-            "AHEE__{$classname}___redirect_after_action__before_redirect_modification_{$this->_req_action}",
3600
-            $query_args
3601
-        );
3602
-        // calculate where we're going (if we have a "save and close" button pushed)
3603
-        if (isset($this->_req_data['save_and_close'], $this->_req_data['save_and_close_referrer'])) {
3604
-            // even though we have the save_and_close referrer, we need to parse the url for the action in order to generate a nonce
3605
-            $parsed_url = parse_url($this->_req_data['save_and_close_referrer']);
3606
-            // regenerate query args array from referrer URL
3607
-            parse_str($parsed_url['query'], $query_args);
3608
-            // correct page and action will be in the query args now
3609
-            $redirect_url = admin_url('admin.php');
3610
-        }
3611
-        // merge any default query_args set in _default_route_query_args property
3612
-        if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3613
-            $args_to_merge = array();
3614
-            foreach ($this->_default_route_query_args as $query_param => $query_value) {
3615
-                // is there a wp_referer array in our _default_route_query_args property?
3616
-                if ($query_param === 'wp_referer') {
3617
-                    $query_value = (array) $query_value;
3618
-                    foreach ($query_value as $reference => $value) {
3619
-                        if (strpos($reference, 'nonce') !== false) {
3620
-                            continue;
3621
-                        }
3622
-                        // finally we will override any arguments in the referer with
3623
-                        // what might be set on the _default_route_query_args array.
3624
-                        if (isset($this->_default_route_query_args[ $reference ])) {
3625
-                            $args_to_merge[ $reference ] = urlencode($this->_default_route_query_args[ $reference ]);
3626
-                        } else {
3627
-                            $args_to_merge[ $reference ] = urlencode($value);
3628
-                        }
3629
-                    }
3630
-                    continue;
3631
-                }
3632
-                $args_to_merge[ $query_param ] = $query_value;
3633
-            }
3634
-            // now let's merge these arguments but override with what was specifically sent in to the
3635
-            // redirect.
3636
-            $query_args = array_merge($args_to_merge, $query_args);
3637
-        }
3638
-        $this->_process_notices($query_args);
3639
-        // generate redirect url
3640
-        // if redirecting to anything other than the main page, add a nonce
3641
-        if (isset($query_args['action'])) {
3642
-            // manually generate wp_nonce and merge that with the query vars
3643
-            // becuz the wp_nonce_url function wrecks havoc on some vars
3644
-            $query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce');
3645
-        }
3646
-        // we're adding some hooks and filters in here for processing any things just before redirects
3647
-        // (example: an admin page has done an insert or update and we want to run something after that).
3648
-        do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args);
3649
-        $redirect_url = apply_filters(
3650
-            'FHEE_redirect_' . $classname . $this->_req_action,
3651
-            EE_Admin_Page::add_query_args_and_nonce($query_args, $redirect_url),
3652
-            $query_args
3653
-        );
3654
-        // check if we're doing ajax.  If we are then lets just return the results and js can handle how it wants.
3655
-        if (defined('DOING_AJAX')) {
3656
-            $default_data = array(
3657
-                'close'        => true,
3658
-                'redirect_url' => $redirect_url,
3659
-                'where'        => 'main',
3660
-                'what'         => 'append',
3661
-            );
3662
-            $this->_template_args['success'] = $success;
3663
-            $this->_template_args['data'] = ! empty($this->_template_args['data']) ? array_merge(
3664
-                $default_data,
3665
-                $this->_template_args['data']
3666
-            ) : $default_data;
3667
-            $this->_return_json();
3668
-        }
3669
-        wp_safe_redirect($redirect_url);
3670
-        exit();
3671
-    }
3672
-
3673
-
3674
-    /**
3675
-     * process any notices before redirecting (or returning ajax request)
3676
-     * This method sets the $this->_template_args['notices'] attribute;
3677
-     *
3678
-     * @param array $query_args         any query args that need to be used for notice transient ('action')
3679
-     * @param bool  $skip_route_verify  This is typically used when we are processing notices REALLY early and
3680
-     *                                  page_routes haven't been defined yet.
3681
-     * @param bool  $sticky_notices     This is used to flag that regardless of whether this is doing_ajax or not, we
3682
-     *                                  still save a transient for the notice.
3683
-     * @return void
3684
-     * @throws EE_Error
3685
-     * @throws InvalidArgumentException
3686
-     * @throws InvalidDataTypeException
3687
-     * @throws InvalidInterfaceException
3688
-     */
3689
-    protected function _process_notices($query_args = array(), $skip_route_verify = false, $sticky_notices = true)
3690
-    {
3691
-        // first let's set individual error properties if doing_ajax and the properties aren't already set.
3692
-        if (defined('DOING_AJAX') && DOING_AJAX) {
3693
-            $notices = EE_Error::get_notices(false);
3694
-            if (empty($this->_template_args['success'])) {
3695
-                $this->_template_args['success'] = isset($notices['success']) ? $notices['success'] : false;
3696
-            }
3697
-            if (empty($this->_template_args['errors'])) {
3698
-                $this->_template_args['errors'] = isset($notices['errors']) ? $notices['errors'] : false;
3699
-            }
3700
-            if (empty($this->_template_args['attention'])) {
3701
-                $this->_template_args['attention'] = isset($notices['attention']) ? $notices['attention'] : false;
3702
-            }
3703
-        }
3704
-        $this->_template_args['notices'] = EE_Error::get_notices();
3705
-        // IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true)
3706
-        if (! defined('DOING_AJAX') || $sticky_notices) {
3707
-            $route = isset($query_args['action']) ? $query_args['action'] : 'default';
3708
-            $this->_add_transient(
3709
-                $route,
3710
-                $this->_template_args['notices'],
3711
-                true,
3712
-                $skip_route_verify
3713
-            );
3714
-        }
3715
-    }
3716
-
3717
-
3718
-    /**
3719
-     * get_action_link_or_button
3720
-     * returns the button html for adding, editing, or deleting an item (depending on given type)
3721
-     *
3722
-     * @param string $action        use this to indicate which action the url is generated with.
3723
-     * @param string $type          accepted strings must be defined in the $_labels['button'] array(as the key)
3724
-     *                              property.
3725
-     * @param array  $extra_request if the button requires extra params you can include them in $key=>$value pairs.
3726
-     * @param string $class         Use this to give the class for the button. Defaults to 'button-primary'
3727
-     * @param string $base_url      If this is not provided
3728
-     *                              the _admin_base_url will be used as the default for the button base_url.
3729
-     *                              Otherwise this value will be used.
3730
-     * @param bool   $exclude_nonce If true then no nonce will be in the generated button link.
3731
-     * @return string
3732
-     * @throws InvalidArgumentException
3733
-     * @throws InvalidInterfaceException
3734
-     * @throws InvalidDataTypeException
3735
-     * @throws EE_Error
3736
-     */
3737
-    public function get_action_link_or_button(
3738
-        $action,
3739
-        $type = 'add',
3740
-        $extra_request = array(),
3741
-        $class = 'button-primary',
3742
-        $base_url = '',
3743
-        $exclude_nonce = false
3744
-    ) {
3745
-        // first let's validate the action (if $base_url is FALSE otherwise validation will happen further along)
3746
-        if (empty($base_url) && ! isset($this->_page_routes[ $action ])) {
3747
-            throw new EE_Error(
3748
-                sprintf(
3749
-                    esc_html__(
3750
-                        'There is no page route for given action for the button.  This action was given: %s',
3751
-                        'event_espresso'
3752
-                    ),
3753
-                    $action
3754
-                )
3755
-            );
3756
-        }
3757
-        if (! isset($this->_labels['buttons'][ $type ])) {
3758
-            throw new EE_Error(
3759
-                sprintf(
3760
-                    __(
3761
-                        'There is no label for the given button type (%s). Labels are set in the <code>_page_config</code> property.',
3762
-                        'event_espresso'
3763
-                    ),
3764
-                    $type
3765
-                )
3766
-            );
3767
-        }
3768
-        // finally check user access for this button.
3769
-        $has_access = $this->check_user_access($action, true);
3770
-        if (! $has_access) {
3771
-            return '';
3772
-        }
3773
-        $_base_url = ! $base_url ? $this->_admin_base_url : $base_url;
3774
-        $query_args = array(
3775
-            'action' => $action,
3776
-        );
3777
-        // merge extra_request args but make sure our original action takes precedence and doesn't get overwritten.
3778
-        if (! empty($extra_request)) {
3779
-            $query_args = array_merge($extra_request, $query_args);
3780
-        }
3781
-        $url = EE_Admin_Page::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce);
3782
-        return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][ $type ], $class);
3783
-    }
3784
-
3785
-
3786
-    /**
3787
-     * _per_page_screen_option
3788
-     * Utility function for adding in a per_page_option in the screen_options_dropdown.
3789
-     *
3790
-     * @return void
3791
-     * @throws InvalidArgumentException
3792
-     * @throws InvalidInterfaceException
3793
-     * @throws InvalidDataTypeException
3794
-     */
3795
-    protected function _per_page_screen_option()
3796
-    {
3797
-        $option = 'per_page';
3798
-        $args = array(
3799
-            'label'   => apply_filters(
3800
-                'FHEE__EE_Admin_Page___per_page_screen_options___label',
3801
-                $this->_admin_page_title,
3802
-                $this
3803
-            ),
3804
-            'default' => (int) apply_filters(
3805
-                'FHEE__EE_Admin_Page___per_page_screen_options__default',
3806
-                20
3807
-            ),
3808
-            'option'  => $this->_current_page . '_' . $this->_current_view . '_per_page',
3809
-        );
3810
-        // ONLY add the screen option if the user has access to it.
3811
-        if ($this->check_user_access($this->_current_view, true)) {
3812
-            add_screen_option($option, $args);
3813
-        }
3814
-    }
3815
-
3816
-
3817
-    /**
3818
-     * set_per_page_screen_option
3819
-     * All this does is make sure that WordPress saves any per_page screen options (if set) for the current page.
3820
-     * we have to do this rather than running inside the 'set-screen-options' hook because it runs earlier than
3821
-     * admin_menu.
3822
-     *
3823
-     * @return void
3824
-     */
3825
-    private function _set_per_page_screen_options()
3826
-    {
3827
-        if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) {
3828
-            check_admin_referer('screen-options-nonce', 'screenoptionnonce');
3829
-            if (! $user = wp_get_current_user()) {
3830
-                return;
3831
-            }
3832
-            $option = $_POST['wp_screen_options']['option'];
3833
-            $value = $_POST['wp_screen_options']['value'];
3834
-            if ($option !== sanitize_key($option)) {
3835
-                return;
3836
-            }
3837
-            $map_option = $option;
3838
-            $option = str_replace('-', '_', $option);
3839
-            switch ($map_option) {
3840
-                case $this->_current_page . '_' . $this->_current_view . '_per_page':
3841
-                    $value = (int) $value;
3842
-                    $max_value = apply_filters(
3843
-                        'FHEE__EE_Admin_Page___set_per_page_screen_options__max_value',
3844
-                        999,
3845
-                        $this->_current_page,
3846
-                        $this->_current_view
3847
-                    );
3848
-                    if ($value < 1) {
3849
-                        return;
3850
-                    }
3851
-                    $value = min($value, $max_value);
3852
-                    break;
3853
-                default:
3854
-                    $value = apply_filters(
3855
-                        'FHEE__EE_Admin_Page___set_per_page_screen_options__value',
3856
-                        false,
3857
-                        $option,
3858
-                        $value
3859
-                    );
3860
-                    if (false === $value) {
3861
-                        return;
3862
-                    }
3863
-                    break;
3864
-            }
3865
-            update_user_meta($user->ID, $option, $value);
3866
-            wp_safe_redirect(remove_query_arg(array('pagenum', 'apage', 'paged'), wp_get_referer()));
3867
-            exit;
3868
-        }
3869
-    }
3870
-
3871
-
3872
-    /**
3873
-     * This just allows for setting the $_template_args property if it needs to be set outside the object
3874
-     *
3875
-     * @param array $data array that will be assigned to template args.
3876
-     */
3877
-    public function set_template_args($data)
3878
-    {
3879
-        $this->_template_args = array_merge($this->_template_args, (array) $data);
3880
-    }
3881
-
3882
-
3883
-    /**
3884
-     * This makes available the WP transient system for temporarily moving data between routes
3885
-     *
3886
-     * @param string $route             the route that should receive the transient
3887
-     * @param array  $data              the data that gets sent
3888
-     * @param bool   $notices           If this is for notices then we use this to indicate so, otherwise its just a
3889
-     *                                  normal route transient.
3890
-     * @param bool   $skip_route_verify Used to indicate we want to skip route verification.  This is usually ONLY used
3891
-     *                                  when we are adding a transient before page_routes have been defined.
3892
-     * @return void
3893
-     * @throws EE_Error
3894
-     */
3895
-    protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false)
3896
-    {
3897
-        $user_id = get_current_user_id();
3898
-        if (! $skip_route_verify) {
3899
-            $this->_verify_route($route);
3900
-        }
3901
-        // now let's set the string for what kind of transient we're setting
3902
-        $transient = $notices
3903
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3904
-            : 'rte_tx_' . $route . '_' . $user_id;
3905
-        $data = $notices ? array('notices' => $data) : $data;
3906
-        // is there already a transient for this route?  If there is then let's ADD to that transient
3907
-        $existing = is_multisite() && is_network_admin()
3908
-            ? get_site_transient($transient)
3909
-            : get_transient($transient);
3910
-        if ($existing) {
3911
-            $data = array_merge((array) $data, (array) $existing);
3912
-        }
3913
-        if (is_multisite() && is_network_admin()) {
3914
-            set_site_transient($transient, $data, 8);
3915
-        } else {
3916
-            set_transient($transient, $data, 8);
3917
-        }
3918
-    }
3919
-
3920
-
3921
-    /**
3922
-     * this retrieves the temporary transient that has been set for moving data between routes.
3923
-     *
3924
-     * @param bool   $notices true we get notices transient. False we just return normal route transient
3925
-     * @param string $route
3926
-     * @return mixed data
3927
-     */
3928
-    protected function _get_transient($notices = false, $route = '')
3929
-    {
3930
-        $user_id = get_current_user_id();
3931
-        $route = ! $route ? $this->_req_action : $route;
3932
-        $transient = $notices
3933
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3934
-            : 'rte_tx_' . $route . '_' . $user_id;
3935
-        $data = is_multisite() && is_network_admin()
3936
-            ? get_site_transient($transient)
3937
-            : get_transient($transient);
3938
-        // delete transient after retrieval (just in case it hasn't expired);
3939
-        if (is_multisite() && is_network_admin()) {
3940
-            delete_site_transient($transient);
3941
-        } else {
3942
-            delete_transient($transient);
3943
-        }
3944
-        return $notices && isset($data['notices']) ? $data['notices'] : $data;
3945
-    }
3946
-
3947
-
3948
-    /**
3949
-     * The purpose of this method is just to run garbage collection on any EE transients that might have expired but
3950
-     * would not be called later. This will be assigned to run on a specific EE Admin page. (place the method in the
3951
-     * default route callback on the EE_Admin page you want it run.)
3952
-     *
3953
-     * @return void
3954
-     */
3955
-    protected function _transient_garbage_collection()
3956
-    {
3957
-        global $wpdb;
3958
-        // retrieve all existing transients
3959
-        $query = "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%rte_tx_%' OR option_name LIKE '%rte_n_tx_%'";
3960
-        if ($results = $wpdb->get_results($query)) {
3961
-            foreach ($results as $result) {
3962
-                $transient = str_replace('_transient_', '', $result->option_name);
3963
-                get_transient($transient);
3964
-                if (is_multisite() && is_network_admin()) {
3965
-                    get_site_transient($transient);
3966
-                }
3967
-            }
3968
-        }
3969
-    }
3970
-
3971
-
3972
-    /**
3973
-     * get_view
3974
-     *
3975
-     * @return string content of _view property
3976
-     */
3977
-    public function get_view()
3978
-    {
3979
-        return $this->_view;
3980
-    }
3981
-
3982
-
3983
-    /**
3984
-     * getter for the protected $_views property
3985
-     *
3986
-     * @return array
3987
-     */
3988
-    public function get_views()
3989
-    {
3990
-        return $this->_views;
3991
-    }
3992
-
3993
-
3994
-    /**
3995
-     * get_current_page
3996
-     *
3997
-     * @return string _current_page property value
3998
-     */
3999
-    public function get_current_page()
4000
-    {
4001
-        return $this->_current_page;
4002
-    }
4003
-
4004
-
4005
-    /**
4006
-     * get_current_view
4007
-     *
4008
-     * @return string _current_view property value
4009
-     */
4010
-    public function get_current_view()
4011
-    {
4012
-        return $this->_current_view;
4013
-    }
4014
-
4015
-
4016
-    /**
4017
-     * get_current_screen
4018
-     *
4019
-     * @return object The current WP_Screen object
4020
-     */
4021
-    public function get_current_screen()
4022
-    {
4023
-        return $this->_current_screen;
4024
-    }
4025
-
4026
-
4027
-    /**
4028
-     * get_current_page_view_url
4029
-     *
4030
-     * @return string This returns the url for the current_page_view.
4031
-     */
4032
-    public function get_current_page_view_url()
4033
-    {
4034
-        return $this->_current_page_view_url;
4035
-    }
4036
-
4037
-
4038
-    /**
4039
-     * just returns the _req_data property
4040
-     *
4041
-     * @return array
4042
-     */
4043
-    public function get_request_data()
4044
-    {
4045
-        return $this->_req_data;
4046
-    }
4047
-
4048
-
4049
-    /**
4050
-     * returns the _req_data protected property
4051
-     *
4052
-     * @return string
4053
-     */
4054
-    public function get_req_action()
4055
-    {
4056
-        return $this->_req_action;
4057
-    }
4058
-
4059
-
4060
-    /**
4061
-     * @return bool  value of $_is_caf property
4062
-     */
4063
-    public function is_caf()
4064
-    {
4065
-        return $this->_is_caf;
4066
-    }
4067
-
4068
-
4069
-    /**
4070
-     * @return mixed
4071
-     */
4072
-    public function default_espresso_metaboxes()
4073
-    {
4074
-        return $this->_default_espresso_metaboxes;
4075
-    }
4076
-
4077
-
4078
-    /**
4079
-     * @return mixed
4080
-     */
4081
-    public function admin_base_url()
4082
-    {
4083
-        return $this->_admin_base_url;
4084
-    }
4085
-
4086
-
4087
-    /**
4088
-     * @return mixed
4089
-     */
4090
-    public function wp_page_slug()
4091
-    {
4092
-        return $this->_wp_page_slug;
4093
-    }
4094
-
4095
-
4096
-    /**
4097
-     * updates  espresso configuration settings
4098
-     *
4099
-     * @param string                   $tab
4100
-     * @param EE_Config_Base|EE_Config $config
4101
-     * @param string                   $file file where error occurred
4102
-     * @param string                   $func function  where error occurred
4103
-     * @param string                   $line line no where error occurred
4104
-     * @return boolean
4105
-     */
4106
-    protected function _update_espresso_configuration($tab, $config, $file = '', $func = '', $line = '')
4107
-    {
4108
-        // remove any options that are NOT going to be saved with the config settings.
4109
-        if (isset($config->core->ee_ueip_optin)) {
4110
-            // TODO: remove the following two lines and make sure values are migrated from 3.1
4111
-            update_option('ee_ueip_optin', $config->core->ee_ueip_optin);
4112
-            update_option('ee_ueip_has_notified', true);
4113
-        }
4114
-        // and save it (note we're also doing the network save here)
4115
-        $net_saved = is_main_site() ? EE_Network_Config::instance()->update_config(false, false) : true;
4116
-        $config_saved = EE_Config::instance()->update_espresso_config(false, false);
4117
-        if ($config_saved && $net_saved) {
4118
-            EE_Error::add_success(sprintf(__('"%s" have been successfully updated.', 'event_espresso'), $tab));
4119
-            return true;
4120
-        }
4121
-        EE_Error::add_error(sprintf(__('The "%s" were not updated.', 'event_espresso'), $tab), $file, $func, $line);
4122
-        return false;
4123
-    }
4124
-
4125
-
4126
-    /**
4127
-     * Returns an array to be used for EE_FOrm_Fields.helper.php's select_input as the $values argument.
4128
-     *
4129
-     * @return array
4130
-     */
4131
-    public function get_yes_no_values()
4132
-    {
4133
-        return $this->_yes_no_values;
4134
-    }
4135
-
4136
-
4137
-    /**
4138
-     * @return string
4139
-     * @throws ReflectionException
4140
-     * @since $VID:$
4141
-     */
4142
-    protected function _get_dir()
4143
-    {
4144
-        $reflector = new ReflectionClass(get_class($this));
4145
-        return dirname($reflector->getFileName());
4146
-    }
4147
-
4148
-
4149
-    /**
4150
-     * A helper for getting a "next link".
4151
-     *
4152
-     * @param string $url   The url to link to
4153
-     * @param string $class The class to use.
4154
-     * @return string
4155
-     */
4156
-    protected function _next_link($url, $class = 'dashicons dashicons-arrow-right')
4157
-    {
4158
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4159
-    }
4160
-
4161
-
4162
-    /**
4163
-     * A helper for getting a "previous link".
4164
-     *
4165
-     * @param string $url   The url to link to
4166
-     * @param string $class The class to use.
4167
-     * @return string
4168
-     */
4169
-    protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left')
4170
-    {
4171
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4172
-    }
4173
-
4174
-
4175
-
4176
-
4177
-
4178
-
4179
-
4180
-    // below are some messages related methods that should be available across the EE_Admin system.  Note, these methods are NOT page specific
4181
-
4182
-
4183
-    /**
4184
-     * This processes an request to resend a registration and assumes we have a _REG_ID for doing so. So if the caller
4185
-     * knows that the _REG_ID isn't in the req_data array but CAN obtain it, the caller should ADD the _REG_ID to the
4186
-     * _req_data array.
4187
-     *
4188
-     * @return bool success/fail
4189
-     * @throws EE_Error
4190
-     * @throws InvalidArgumentException
4191
-     * @throws ReflectionException
4192
-     * @throws InvalidDataTypeException
4193
-     * @throws InvalidInterfaceException
4194
-     */
4195
-    protected function _process_resend_registration()
4196
-    {
4197
-        $this->_template_args['success'] = EED_Messages::process_resend($this->_req_data);
4198
-        do_action(
4199
-            'AHEE__EE_Admin_Page___process_resend_registration',
4200
-            $this->_template_args['success'],
4201
-            $this->_req_data
4202
-        );
4203
-        return $this->_template_args['success'];
4204
-    }
4205
-
4206
-
4207
-    /**
4208
-     * This automatically processes any payment message notifications when manual payment has been applied.
4209
-     *
4210
-     * @param EE_Payment $payment
4211
-     * @return bool success/fail
4212
-     */
4213
-    protected function _process_payment_notification(EE_Payment $payment)
4214
-    {
4215
-        add_filter('FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', '__return_true');
4216
-        do_action('AHEE__EE_Admin_Page___process_admin_payment_notification', $payment);
4217
-        $this->_template_args['success'] = apply_filters(
4218
-            'FHEE__EE_Admin_Page___process_admin_payment_notification__success',
4219
-            false,
4220
-            $payment
4221
-        );
4222
-        return $this->_template_args['success'];
4223
-    }
2749
+	}
2750
+
2751
+
2752
+	/**
2753
+	 * facade for add_meta_box
2754
+	 *
2755
+	 * @param string  $action        where the metabox get's displayed
2756
+	 * @param string  $title         Title of Metabox (output in metabox header)
2757
+	 * @param string  $callback      If not empty and $create_fun is set to false then we'll use a custom callback
2758
+	 *                               instead of the one created in here.
2759
+	 * @param array   $callback_args an array of args supplied for the metabox
2760
+	 * @param string  $column        what metabox column
2761
+	 * @param string  $priority      give this metabox a priority (using accepted priorities for wp meta boxes)
2762
+	 * @param boolean $create_func   default is true.  Basically we can say we don't WANT to have the runtime function
2763
+	 *                               created but just set our own callback for wp's add_meta_box.
2764
+	 * @throws DomainException
2765
+	 */
2766
+	public function _add_admin_page_meta_box(
2767
+		$action,
2768
+		$title,
2769
+		$callback,
2770
+		$callback_args,
2771
+		$column = 'normal',
2772
+		$priority = 'high',
2773
+		$create_func = true
2774
+	) {
2775
+		do_action('AHEE_log', __FILE__, __FUNCTION__, $callback);
2776
+		// if we have empty callback args and we want to automatically create the metabox callback then we need to make sure the callback args are generated.
2777
+		if (empty($callback_args) && $create_func) {
2778
+			$callback_args = array(
2779
+				'template_path' => $this->_template_path,
2780
+				'template_args' => $this->_template_args,
2781
+			);
2782
+		}
2783
+		// if $create_func is true (default) then we automatically create the function for displaying the actual meta box.  If false then we take the $callback reference passed through and use it instead (so callers can define their own callback function/method if they wish)
2784
+		$call_back_func = $create_func
2785
+			? static function ($post, $metabox) {
2786
+				do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2787
+				echo EEH_Template::display_template(
2788
+					$metabox['args']['template_path'],
2789
+					$metabox['args']['template_args'],
2790
+					true
2791
+				);
2792
+			}
2793
+			: $callback;
2794
+		add_meta_box(
2795
+			str_replace('_', '-', $action) . '-mbox',
2796
+			$title,
2797
+			$call_back_func,
2798
+			$this->_wp_page_slug,
2799
+			$column,
2800
+			$priority,
2801
+			$callback_args
2802
+		);
2803
+	}
2804
+
2805
+
2806
+	/**
2807
+	 * generates HTML wrapper for and admin details page that contains metaboxes in columns
2808
+	 *
2809
+	 * @throws DomainException
2810
+	 * @throws EE_Error
2811
+	 * @throws InvalidArgumentException
2812
+	 * @throws InvalidDataTypeException
2813
+	 * @throws InvalidInterfaceException
2814
+	 */
2815
+	public function display_admin_page_with_metabox_columns()
2816
+	{
2817
+		$this->_template_args['post_body_content'] = $this->_template_args['admin_page_content'];
2818
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2819
+			$this->_column_template_path,
2820
+			$this->_template_args,
2821
+			true
2822
+		);
2823
+		// the final wrapper
2824
+		$this->admin_page_wrapper();
2825
+	}
2826
+
2827
+
2828
+	/**
2829
+	 * generates  HTML wrapper for an admin details page
2830
+	 *
2831
+	 * @return void
2832
+	 * @throws DomainException
2833
+	 * @throws EE_Error
2834
+	 * @throws InvalidArgumentException
2835
+	 * @throws InvalidDataTypeException
2836
+	 * @throws InvalidInterfaceException
2837
+	 */
2838
+	public function display_admin_page_with_sidebar()
2839
+	{
2840
+		$this->_display_admin_page(true);
2841
+	}
2842
+
2843
+
2844
+	/**
2845
+	 * generates  HTML wrapper for an admin details page (except no sidebar)
2846
+	 *
2847
+	 * @return void
2848
+	 * @throws DomainException
2849
+	 * @throws EE_Error
2850
+	 * @throws InvalidArgumentException
2851
+	 * @throws InvalidDataTypeException
2852
+	 * @throws InvalidInterfaceException
2853
+	 */
2854
+	public function display_admin_page_with_no_sidebar()
2855
+	{
2856
+		$this->_display_admin_page();
2857
+	}
2858
+
2859
+
2860
+	/**
2861
+	 * generates HTML wrapper for an EE about admin page (no sidebar)
2862
+	 *
2863
+	 * @return void
2864
+	 * @throws DomainException
2865
+	 * @throws EE_Error
2866
+	 * @throws InvalidArgumentException
2867
+	 * @throws InvalidDataTypeException
2868
+	 * @throws InvalidInterfaceException
2869
+	 */
2870
+	public function display_about_admin_page()
2871
+	{
2872
+		$this->_display_admin_page(false, true);
2873
+	}
2874
+
2875
+
2876
+	/**
2877
+	 * display_admin_page
2878
+	 * contains the code for actually displaying an admin page
2879
+	 *
2880
+	 * @param boolean $sidebar true with sidebar, false without
2881
+	 * @param boolean $about   use the about admin wrapper instead of the default.
2882
+	 * @return void
2883
+	 * @throws DomainException
2884
+	 * @throws EE_Error
2885
+	 * @throws InvalidArgumentException
2886
+	 * @throws InvalidDataTypeException
2887
+	 * @throws InvalidInterfaceException
2888
+	 */
2889
+	private function _display_admin_page($sidebar = false, $about = false)
2890
+	{
2891
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2892
+		// custom remove metaboxes hook to add or remove any metaboxes to/from Admin pages.
2893
+		do_action('AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes');
2894
+		// set current wp page slug - looks like: event-espresso_page_event_categories
2895
+		// keep in mind "event-espresso" COULD be something else if the top level menu label has been translated.
2896
+		$this->_template_args['current_page'] = $this->_wp_page_slug;
2897
+		$this->_template_args['admin_page_wrapper_div_id'] = $this->_cpt_route
2898
+			? 'poststuff'
2899
+			: 'espresso-default-admin';
2900
+		$template_path = $sidebar
2901
+			? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php'
2902
+			: EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php';
2903
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2904
+			$template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php';
2905
+		}
2906
+		$template_path = ! empty($this->_column_template_path)
2907
+			? $this->_column_template_path : $template_path;
2908
+		$this->_template_args['post_body_content'] = isset($this->_template_args['admin_page_content'])
2909
+			? $this->_template_args['admin_page_content']
2910
+			: '';
2911
+		$this->_template_args['before_admin_page_content'] = isset($this->_template_args['before_admin_page_content'])
2912
+			? $this->_template_args['before_admin_page_content']
2913
+			: '';
2914
+		$this->_template_args['after_admin_page_content'] = isset($this->_template_args['after_admin_page_content'])
2915
+			? $this->_template_args['after_admin_page_content']
2916
+			: '';
2917
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2918
+			$template_path,
2919
+			$this->_template_args,
2920
+			true
2921
+		);
2922
+		// the final template wrapper
2923
+		$this->admin_page_wrapper($about);
2924
+	}
2925
+
2926
+
2927
+	/**
2928
+	 * This is used to display caf preview pages.
2929
+	 *
2930
+	 * @since 4.3.2
2931
+	 * @param string $utm_campaign_source what is the key used for google analytics link
2932
+	 * @param bool   $display_sidebar     whether to use the sidebar template or the full template for the page.  TRUE
2933
+	 *                                    = SHOW sidebar, FALSE = no sidebar. Default no sidebar.
2934
+	 * @return void
2935
+	 * @throws DomainException
2936
+	 * @throws EE_Error
2937
+	 * @throws InvalidArgumentException
2938
+	 * @throws InvalidDataTypeException
2939
+	 * @throws InvalidInterfaceException
2940
+	 */
2941
+	public function display_admin_caf_preview_page($utm_campaign_source = '', $display_sidebar = true)
2942
+	{
2943
+		// let's generate a default preview action button if there isn't one already present.
2944
+		$this->_labels['buttons']['buy_now'] = esc_html__(
2945
+			'Upgrade to Event Espresso 4 Right Now',
2946
+			'event_espresso'
2947
+		);
2948
+		$buy_now_url = add_query_arg(
2949
+			array(
2950
+				'ee_ver'       => 'ee4',
2951
+				'utm_source'   => 'ee4_plugin_admin',
2952
+				'utm_medium'   => 'link',
2953
+				'utm_campaign' => $utm_campaign_source,
2954
+				'utm_content'  => 'buy_now_button',
2955
+			),
2956
+			'http://eventespresso.com/pricing/'
2957
+		);
2958
+		$this->_template_args['preview_action_button'] = ! isset($this->_template_args['preview_action_button'])
2959
+			? $this->get_action_link_or_button(
2960
+				'',
2961
+				'buy_now',
2962
+				array(),
2963
+				'button-primary button-large',
2964
+				$buy_now_url,
2965
+				true
2966
+			)
2967
+			: $this->_template_args['preview_action_button'];
2968
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2969
+			EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php',
2970
+			$this->_template_args,
2971
+			true
2972
+		);
2973
+		$this->_display_admin_page($display_sidebar);
2974
+	}
2975
+
2976
+
2977
+	/**
2978
+	 * display_admin_list_table_page_with_sidebar
2979
+	 * generates HTML wrapper for an admin_page with list_table
2980
+	 *
2981
+	 * @return void
2982
+	 * @throws DomainException
2983
+	 * @throws EE_Error
2984
+	 * @throws InvalidArgumentException
2985
+	 * @throws InvalidDataTypeException
2986
+	 * @throws InvalidInterfaceException
2987
+	 */
2988
+	public function display_admin_list_table_page_with_sidebar()
2989
+	{
2990
+		$this->_display_admin_list_table_page(true);
2991
+	}
2992
+
2993
+
2994
+	/**
2995
+	 * display_admin_list_table_page_with_no_sidebar
2996
+	 * generates HTML wrapper for an admin_page with list_table (but with no sidebar)
2997
+	 *
2998
+	 * @return void
2999
+	 * @throws DomainException
3000
+	 * @throws EE_Error
3001
+	 * @throws InvalidArgumentException
3002
+	 * @throws InvalidDataTypeException
3003
+	 * @throws InvalidInterfaceException
3004
+	 */
3005
+	public function display_admin_list_table_page_with_no_sidebar()
3006
+	{
3007
+		$this->_display_admin_list_table_page();
3008
+	}
3009
+
3010
+
3011
+	/**
3012
+	 * generates html wrapper for an admin_list_table page
3013
+	 *
3014
+	 * @param boolean $sidebar whether to display with sidebar or not.
3015
+	 * @return void
3016
+	 * @throws DomainException
3017
+	 * @throws EE_Error
3018
+	 * @throws InvalidArgumentException
3019
+	 * @throws InvalidDataTypeException
3020
+	 * @throws InvalidInterfaceException
3021
+	 */
3022
+	private function _display_admin_list_table_page($sidebar = false)
3023
+	{
3024
+		// setup search attributes
3025
+		$this->_set_search_attributes();
3026
+		$this->_template_args['current_page'] = $this->_wp_page_slug;
3027
+		$template_path = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php';
3028
+		$this->_template_args['table_url'] = defined('DOING_AJAX')
3029
+			? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url)
3030
+			: add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url);
3031
+		$this->_template_args['list_table'] = $this->_list_table_object;
3032
+		$this->_template_args['current_route'] = $this->_req_action;
3033
+		$this->_template_args['list_table_class'] = get_class($this->_list_table_object);
3034
+		$ajax_sorting_callback = $this->_list_table_object->get_ajax_sorting_callback();
3035
+		if (! empty($ajax_sorting_callback)) {
3036
+			$sortable_list_table_form_fields = wp_nonce_field(
3037
+				$ajax_sorting_callback . '_nonce',
3038
+				$ajax_sorting_callback . '_nonce',
3039
+				false,
3040
+				false
3041
+			);
3042
+			$sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_page" name="ajax_table_sort_page" value="'
3043
+												. $this->page_slug
3044
+												. '" />';
3045
+			$sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_action" name="ajax_table_sort_action" value="'
3046
+												. $ajax_sorting_callback
3047
+												. '" />';
3048
+		} else {
3049
+			$sortable_list_table_form_fields = '';
3050
+		}
3051
+		$this->_template_args['sortable_list_table_form_fields'] = $sortable_list_table_form_fields;
3052
+		$hidden_form_fields = isset($this->_template_args['list_table_hidden_fields'])
3053
+			? $this->_template_args['list_table_hidden_fields']
3054
+			: '';
3055
+		$nonce_ref = $this->_req_action . '_nonce';
3056
+		$hidden_form_fields .= '<input type="hidden" name="'
3057
+							   . $nonce_ref
3058
+							   . '" value="'
3059
+							   . wp_create_nonce($nonce_ref)
3060
+							   . '">';
3061
+		$this->_template_args['list_table_hidden_fields'] = $hidden_form_fields;
3062
+		// display message about search results?
3063
+		$this->_template_args['before_list_table'] .= ! empty($this->_req_data['s'])
3064
+			? '<p class="ee-search-results">' . sprintf(
3065
+				esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'),
3066
+				trim($this->_req_data['s'], '%')
3067
+			) . '</p>'
3068
+			: '';
3069
+		// filter before_list_table template arg
3070
+		$this->_template_args['before_list_table'] = apply_filters(
3071
+			'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_arg',
3072
+			$this->_template_args['before_list_table'],
3073
+			$this->page_slug,
3074
+			$this->_req_data,
3075
+			$this->_req_action
3076
+		);
3077
+		// convert to array and filter again
3078
+		// arrays are easier to inject new items in a specific location,
3079
+		// but would not be backwards compatible, so we have to add a new filter
3080
+		$this->_template_args['before_list_table'] = implode(
3081
+			" \n",
3082
+			(array) apply_filters(
3083
+				'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_args_array',
3084
+				(array) $this->_template_args['before_list_table'],
3085
+				$this->page_slug,
3086
+				$this->_req_data,
3087
+				$this->_req_action
3088
+			)
3089
+		);
3090
+		// filter after_list_table template arg
3091
+		$this->_template_args['after_list_table'] = apply_filters(
3092
+			'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_arg',
3093
+			$this->_template_args['after_list_table'],
3094
+			$this->page_slug,
3095
+			$this->_req_data,
3096
+			$this->_req_action
3097
+		);
3098
+		// convert to array and filter again
3099
+		// arrays are easier to inject new items in a specific location,
3100
+		// but would not be backwards compatible, so we have to add a new filter
3101
+		$this->_template_args['after_list_table'] = implode(
3102
+			" \n",
3103
+			(array) apply_filters(
3104
+				'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_args_array',
3105
+				(array) $this->_template_args['after_list_table'],
3106
+				$this->page_slug,
3107
+				$this->_req_data,
3108
+				$this->_req_action
3109
+			)
3110
+		);
3111
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
3112
+			$template_path,
3113
+			$this->_template_args,
3114
+			true
3115
+		);
3116
+		// the final template wrapper
3117
+		if ($sidebar) {
3118
+			$this->display_admin_page_with_sidebar();
3119
+		} else {
3120
+			$this->display_admin_page_with_no_sidebar();
3121
+		}
3122
+	}
3123
+
3124
+
3125
+	/**
3126
+	 * This just prepares a legend using the given items and the admin_details_legend.template.php file and returns the
3127
+	 * html string for the legend.
3128
+	 * $items are expected in an array in the following format:
3129
+	 * $legend_items = array(
3130
+	 *        'item_id' => array(
3131
+	 *            'icon' => 'http://url_to_icon_being_described.png',
3132
+	 *            'desc' => esc_html__('localized description of item');
3133
+	 *        )
3134
+	 * );
3135
+	 *
3136
+	 * @param  array $items see above for format of array
3137
+	 * @return string html string of legend
3138
+	 * @throws DomainException
3139
+	 */
3140
+	protected function _display_legend($items)
3141
+	{
3142
+		$this->_template_args['items'] = apply_filters(
3143
+			'FHEE__EE_Admin_Page___display_legend__items',
3144
+			(array) $items,
3145
+			$this
3146
+		);
3147
+		$this->_template_args['status_change_notice'] = EEH_Template::display_template(
3148
+			EE_ADMIN_TEMPLATE . 'status_change_notice.template.php',
3149
+			[ 'context' => '__admin-legend' ],
3150
+			true
3151
+		);
3152
+		return EEH_Template::display_template(
3153
+			EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php',
3154
+			$this->_template_args,
3155
+			true
3156
+		);
3157
+	}
3158
+
3159
+
3160
+	/**
3161
+	 * This is used whenever we're DOING_AJAX to return a formatted json array that our calling javascript can expect
3162
+	 * The returned json object is created from an array in the following format:
3163
+	 * array(
3164
+	 *  'error' => FALSE, //(default FALSE), contains any errors and/or exceptions (exceptions return json early),
3165
+	 *  'success' => FALSE, //(default FALSE) - contains any special success message.
3166
+	 *  'notices' => '', // - contains any EE_Error formatted notices
3167
+	 *  'content' => 'string can be html', //this is a string of formatted content (can be html)
3168
+	 *  'data' => array() //this can be any key/value pairs that a method returns for later json parsing by the js.
3169
+	 *  We're also going to include the template args with every package (so js can pick out any specific template args
3170
+	 *  that might be included in here)
3171
+	 * )
3172
+	 * The json object is populated by whatever is set in the $_template_args property.
3173
+	 *
3174
+	 * @param bool  $sticky_notices    Used to indicate whether you want to ensure notices are added to a transient
3175
+	 *                                 instead of displayed.
3176
+	 * @param array $notices_arguments Use this to pass any additional args on to the _process_notices.
3177
+	 * @return void
3178
+	 * @throws EE_Error
3179
+	 * @throws InvalidArgumentException
3180
+	 * @throws InvalidDataTypeException
3181
+	 * @throws InvalidInterfaceException
3182
+	 */
3183
+	protected function _return_json($sticky_notices = false, $notices_arguments = array())
3184
+	{
3185
+		// make sure any EE_Error notices have been handled.
3186
+		$this->_process_notices($notices_arguments, true, $sticky_notices);
3187
+		$data = isset($this->_template_args['data']) ? $this->_template_args['data'] : array();
3188
+		unset($this->_template_args['data']);
3189
+		$json = array(
3190
+			'error'     => isset($this->_template_args['error']) ? $this->_template_args['error'] : false,
3191
+			'success'   => isset($this->_template_args['success']) ? $this->_template_args['success'] : false,
3192
+			'errors'    => isset($this->_template_args['errors']) ? $this->_template_args['errors'] : false,
3193
+			'attention' => isset($this->_template_args['attention']) ? $this->_template_args['attention'] : false,
3194
+			'notices'   => EE_Error::get_notices(),
3195
+			'content'   => isset($this->_template_args['admin_page_content'])
3196
+				? $this->_template_args['admin_page_content'] : '',
3197
+			'data'      => array_merge($data, array('template_args' => $this->_template_args)),
3198
+			'isEEajax'  => true
3199
+			// special flag so any ajax.Success methods in js can identify this return package as a EEajax package.
3200
+		);
3201
+		// make sure there are no php errors or headers_sent.  Then we can set correct json header.
3202
+		if (null === error_get_last() || ! headers_sent()) {
3203
+			header('Content-Type: application/json; charset=UTF-8');
3204
+		}
3205
+		echo wp_json_encode($json);
3206
+		exit();
3207
+	}
3208
+
3209
+
3210
+	/**
3211
+	 * Simply a wrapper for the protected method so we can call this outside the class (ONLY when doing ajax)
3212
+	 *
3213
+	 * @return void
3214
+	 * @throws EE_Error
3215
+	 * @throws InvalidArgumentException
3216
+	 * @throws InvalidDataTypeException
3217
+	 * @throws InvalidInterfaceException
3218
+	 */
3219
+	public function return_json()
3220
+	{
3221
+		if (defined('DOING_AJAX') && DOING_AJAX) {
3222
+			$this->_return_json();
3223
+		} else {
3224
+			throw new EE_Error(
3225
+				sprintf(
3226
+					esc_html__('The public %s method can only be called when DOING_AJAX = TRUE', 'event_espresso'),
3227
+					__FUNCTION__
3228
+				)
3229
+			);
3230
+		}
3231
+	}
3232
+
3233
+
3234
+	/**
3235
+	 * This provides a way for child hook classes to send along themselves by reference so methods/properties within
3236
+	 * them can be accessed by EE_Admin_child pages. This is assigned to the $_hook_obj property.
3237
+	 *
3238
+	 * @param EE_Admin_Hooks $hook_obj This will be the object for the EE_Admin_Hooks child
3239
+	 */
3240
+	public function set_hook_object(EE_Admin_Hooks $hook_obj)
3241
+	{
3242
+		$this->_hook_obj = $hook_obj;
3243
+	}
3244
+
3245
+
3246
+	/**
3247
+	 *        generates  HTML wrapper with Tabbed nav for an admin page
3248
+	 *
3249
+	 * @param boolean $about whether to use the special about page wrapper or default.
3250
+	 * @return void
3251
+	 * @throws DomainException
3252
+	 * @throws EE_Error
3253
+	 * @throws InvalidArgumentException
3254
+	 * @throws InvalidDataTypeException
3255
+	 * @throws InvalidInterfaceException
3256
+	 */
3257
+	public function admin_page_wrapper($about = false)
3258
+	{
3259
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3260
+		$this->_nav_tabs = $this->_get_main_nav_tabs();
3261
+		$this->_template_args['nav_tabs'] = $this->_nav_tabs;
3262
+		$this->_template_args['admin_page_title'] = $this->_admin_page_title;
3263
+		$this->_template_args['before_admin_page_content'] = apply_filters(
3264
+			"FHEE_before_admin_page_content{$this->_current_page}{$this->_current_view}",
3265
+			isset($this->_template_args['before_admin_page_content'])
3266
+				? $this->_template_args['before_admin_page_content']
3267
+				: ''
3268
+		);
3269
+		$this->_template_args['after_admin_page_content'] = apply_filters(
3270
+			"FHEE_after_admin_page_content{$this->_current_page}{$this->_current_view}",
3271
+			isset($this->_template_args['after_admin_page_content'])
3272
+				? $this->_template_args['after_admin_page_content']
3273
+				: ''
3274
+		);
3275
+		$this->_template_args['after_admin_page_content'] .= $this->_set_help_popup_content();
3276
+		// load settings page wrapper template
3277
+		$template_path = ! defined('DOING_AJAX')
3278
+			? EE_ADMIN_TEMPLATE . 'admin_wrapper.template.php'
3279
+			: EE_ADMIN_TEMPLATE
3280
+			  . 'admin_wrapper_ajax.template.php';
3281
+		// about page?
3282
+		$template_path = $about
3283
+			? EE_ADMIN_TEMPLATE . 'about_admin_wrapper.template.php'
3284
+			: $template_path;
3285
+		if (defined('DOING_AJAX')) {
3286
+			$this->_template_args['admin_page_content'] = EEH_Template::display_template(
3287
+				$template_path,
3288
+				$this->_template_args,
3289
+				true
3290
+			);
3291
+			$this->_return_json();
3292
+		} else {
3293
+			EEH_Template::display_template($template_path, $this->_template_args);
3294
+		}
3295
+	}
3296
+
3297
+
3298
+	/**
3299
+	 * This returns the admin_nav tabs html using the configuration in the _nav_tabs property
3300
+	 *
3301
+	 * @return string html
3302
+	 * @throws EE_Error
3303
+	 */
3304
+	protected function _get_main_nav_tabs()
3305
+	{
3306
+		// let's generate the html using the EEH_Tabbed_Content helper.
3307
+		// We do this here so that it's possible for child classes to add in nav tabs dynamically at the last minute
3308
+		// (rather than setting in the page_routes array)
3309
+		return EEH_Tabbed_Content::display_admin_nav_tabs($this->_nav_tabs);
3310
+	}
3311
+
3312
+
3313
+	/**
3314
+	 *        sort nav tabs
3315
+	 *
3316
+	 * @param $a
3317
+	 * @param $b
3318
+	 * @return int
3319
+	 */
3320
+	private function _sort_nav_tabs($a, $b)
3321
+	{
3322
+		if ($a['order'] === $b['order']) {
3323
+			return 0;
3324
+		}
3325
+		return ($a['order'] < $b['order']) ? -1 : 1;
3326
+	}
3327
+
3328
+
3329
+	/**
3330
+	 *    generates HTML for the forms used on admin pages
3331
+	 *
3332
+	 * @param    array $input_vars - array of input field details
3333
+	 * @param string   $generator  (options are 'string' or 'array', basically use this to indicate which generator to
3334
+	 *                             use)
3335
+	 * @param bool     $id
3336
+	 * @return string
3337
+	 * @uses   EEH_Form_Fields::get_form_fields (/helper/EEH_Form_Fields.helper.php)
3338
+	 * @uses   EEH_Form_Fields::get_form_fields_array (/helper/EEH_Form_Fields.helper.php)
3339
+	 */
3340
+	protected function _generate_admin_form_fields($input_vars = array(), $generator = 'string', $id = false)
3341
+	{
3342
+		return $generator === 'string'
3343
+			? EEH_Form_Fields::get_form_fields($input_vars, $id)
3344
+			: EEH_Form_Fields::get_form_fields_array($input_vars);
3345
+	}
3346
+
3347
+
3348
+	/**
3349
+	 * generates the "Save" and "Save & Close" buttons for edit forms
3350
+	 *
3351
+	 * @param bool             $both     if true then both buttons will be generated.  If false then just the "Save &
3352
+	 *                                   Close" button.
3353
+	 * @param array            $text     if included, generator will use the given text for the buttons ( array([0] =>
3354
+	 *                                   'Save', [1] => 'save & close')
3355
+	 * @param array            $actions  if included allows us to set the actions that each button will carry out (i.e.
3356
+	 *                                   via the "name" value in the button).  We can also use this to just dump
3357
+	 *                                   default actions by submitting some other value.
3358
+	 * @param bool|string|null $referrer if false then we just do the default action on save and close.  Other wise it
3359
+	 *                                   will use the $referrer string. IF null, then we don't do ANYTHING on save and
3360
+	 *                                   close (normal form handling).
3361
+	 */
3362
+	protected function _set_save_buttons($both = true, $text = array(), $actions = array(), $referrer = null)
3363
+	{
3364
+		// make sure $text and $actions are in an array
3365
+		$text = (array) $text;
3366
+		$actions = (array) $actions;
3367
+		$referrer_url = empty($referrer)
3368
+			? '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3369
+			  . $_SERVER['REQUEST_URI']
3370
+			  . '" />'
3371
+			: '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3372
+			  . $referrer
3373
+			  . '" />';
3374
+		$button_text = ! empty($text)
3375
+			? $text
3376
+			: array(
3377
+				esc_html__('Save', 'event_espresso'),
3378
+				esc_html__('Save and Close', 'event_espresso'),
3379
+			);
3380
+		$default_names = array('save', 'save_and_close');
3381
+		// add in a hidden index for the current page (so save and close redirects properly)
3382
+		$this->_template_args['save_buttons'] = $referrer_url;
3383
+		foreach ($button_text as $key => $button) {
3384
+			$ref = $default_names[ $key ];
3385
+			$this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary '
3386
+													 . $ref
3387
+													 . '" value="'
3388
+													 . $button
3389
+													 . '" name="'
3390
+													 . (! empty($actions) ? $actions[ $key ] : $ref)
3391
+													 . '" id="'
3392
+													 . $this->_current_view . '_' . $ref
3393
+													 . '" />';
3394
+			if (! $both) {
3395
+				break;
3396
+			}
3397
+		}
3398
+	}
3399
+
3400
+
3401
+	/**
3402
+	 * Wrapper for the protected function.  Allows plugins/addons to call this to set the form tags.
3403
+	 *
3404
+	 * @see   $this->_set_add_edit_form_tags() for details on params
3405
+	 * @since 4.6.0
3406
+	 * @param string $route
3407
+	 * @param array  $additional_hidden_fields
3408
+	 */
3409
+	public function set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3410
+	{
3411
+		$this->_set_add_edit_form_tags($route, $additional_hidden_fields);
3412
+	}
3413
+
3414
+
3415
+	/**
3416
+	 * set form open and close tags on add/edit pages.
3417
+	 *
3418
+	 * @param string $route                    the route you want the form to direct to
3419
+	 * @param array  $additional_hidden_fields any additional hidden fields required in the form header
3420
+	 * @return void
3421
+	 */
3422
+	protected function _set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3423
+	{
3424
+		if (empty($route)) {
3425
+			$user_msg = esc_html__(
3426
+				'An error occurred. No action was set for this page\'s form.',
3427
+				'event_espresso'
3428
+			);
3429
+			$dev_msg = $user_msg . "\n"
3430
+					   . sprintf(
3431
+						   esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'),
3432
+						   __FUNCTION__,
3433
+						   EE_Admin_Page::class
3434
+					   );
3435
+			EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
3436
+		}
3437
+		// open form
3438
+		$this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="'
3439
+															 . $this->_admin_base_url
3440
+															 . '" id="'
3441
+															 . $route
3442
+															 . '_event_form" >';
3443
+		// add nonce
3444
+		$nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false);
3445
+		$this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce;
3446
+		// add REQUIRED form action
3447
+		$hidden_fields = array(
3448
+			'action' => array('type' => 'hidden', 'value' => $route),
3449
+		);
3450
+		// merge arrays
3451
+		$hidden_fields = is_array($additional_hidden_fields)
3452
+			? array_merge($hidden_fields, $additional_hidden_fields)
3453
+			: $hidden_fields;
3454
+		// generate form fields
3455
+		$form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array');
3456
+		// add fields to form
3457
+		foreach ((array) $form_fields as $field_name => $form_field) {
3458
+			$this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field'];
3459
+		}
3460
+		// close form
3461
+		$this->_template_args['after_admin_page_content'] = '</form>';
3462
+	}
3463
+
3464
+
3465
+	/**
3466
+	 * Public Wrapper for _redirect_after_action() method since its
3467
+	 * discovered it would be useful for external code to have access.
3468
+	 *
3469
+	 * @param bool   $success
3470
+	 * @param string $what
3471
+	 * @param string $action_desc
3472
+	 * @param array  $query_args
3473
+	 * @param bool   $override_overwrite
3474
+	 * @throws EE_Error
3475
+	 * @throws InvalidArgumentException
3476
+	 * @throws InvalidDataTypeException
3477
+	 * @throws InvalidInterfaceException
3478
+	 * @see   EE_Admin_Page::_redirect_after_action() for params.
3479
+	 * @since 4.5.0
3480
+	 */
3481
+	public function redirect_after_action(
3482
+		$success = false,
3483
+		$what = 'item',
3484
+		$action_desc = 'processed',
3485
+		$query_args = array(),
3486
+		$override_overwrite = false
3487
+	) {
3488
+		$this->_redirect_after_action(
3489
+			$success,
3490
+			$what,
3491
+			$action_desc,
3492
+			$query_args,
3493
+			$override_overwrite
3494
+		);
3495
+	}
3496
+
3497
+
3498
+	/**
3499
+	 * Helper method for merging existing request data with the returned redirect url.
3500
+	 *
3501
+	 * This is typically used for redirects after an action so that if the original view was a filtered view those
3502
+	 * filters are still applied.
3503
+	 *
3504
+	 * @param array $new_route_data
3505
+	 * @return array
3506
+	 */
3507
+	protected function mergeExistingRequestParamsWithRedirectArgs(array $new_route_data)
3508
+	{
3509
+		foreach ($this->_req_data as $ref => $value) {
3510
+			// unset nonces
3511
+			if (strpos($ref, 'nonce') !== false) {
3512
+				unset($this->_req_data[ $ref ]);
3513
+				continue;
3514
+			}
3515
+			// urlencode values.
3516
+			$value = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
3517
+			$this->_req_data[ $ref ] = $value;
3518
+		}
3519
+		return array_merge($this->_req_data, $new_route_data);
3520
+	}
3521
+
3522
+
3523
+	/**
3524
+	 *    _redirect_after_action
3525
+	 *
3526
+	 * @param int    $success            - whether success was for two or more records, or just one, or none
3527
+	 * @param string $what               - what the action was performed on
3528
+	 * @param string $action_desc        - what was done ie: updated, deleted, etc
3529
+	 * @param array  $query_args         - an array of query_args to be added to the URL to redirect to after the admin
3530
+	 *                                   action is completed
3531
+	 * @param BOOL   $override_overwrite by default all EE_Error::success messages are overwritten, this allows you to
3532
+	 *                                   override this so that they show.
3533
+	 * @return void
3534
+	 * @throws EE_Error
3535
+	 * @throws InvalidArgumentException
3536
+	 * @throws InvalidDataTypeException
3537
+	 * @throws InvalidInterfaceException
3538
+	 */
3539
+	protected function _redirect_after_action(
3540
+		$success = 0,
3541
+		$what = 'item',
3542
+		$action_desc = 'processed',
3543
+		$query_args = array(),
3544
+		$override_overwrite = false
3545
+	) {
3546
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3547
+		// class name for actions/filters.
3548
+		$classname = get_class($this);
3549
+		// set redirect url.
3550
+		// Note if there is a "page" index in the $query_args then we go with vanilla admin.php route,
3551
+		// otherwise we go with whatever is set as the _admin_base_url
3552
+		$redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url;
3553
+		$notices = EE_Error::get_notices(false);
3554
+		// overwrite default success messages //BUT ONLY if overwrite not overridden
3555
+		if (! $override_overwrite || ! empty($notices['errors'])) {
3556
+			EE_Error::overwrite_success();
3557
+		}
3558
+		if (! empty($what) && ! empty($action_desc) && empty($notices['errors'])) {
3559
+			// how many records affected ? more than one record ? or just one ?
3560
+			if ($success > 1) {
3561
+				// set plural msg
3562
+				EE_Error::add_success(
3563
+					sprintf(
3564
+						esc_html__('The "%s" have been successfully %s.', 'event_espresso'),
3565
+						$what,
3566
+						$action_desc
3567
+					),
3568
+					__FILE__,
3569
+					__FUNCTION__,
3570
+					__LINE__
3571
+				);
3572
+			} elseif ($success === 1) {
3573
+				// set singular msg
3574
+				EE_Error::add_success(
3575
+					sprintf(
3576
+						esc_html__('The "%s" has been successfully %s.', 'event_espresso'),
3577
+						$what,
3578
+						$action_desc
3579
+					),
3580
+					__FILE__,
3581
+					__FUNCTION__,
3582
+					__LINE__
3583
+				);
3584
+			}
3585
+		}
3586
+		// check that $query_args isn't something crazy
3587
+		if (! is_array($query_args)) {
3588
+			$query_args = array();
3589
+		}
3590
+		/**
3591
+		 * Allow injecting actions before the query_args are modified for possible different
3592
+		 * redirections on save and close actions
3593
+		 *
3594
+		 * @since 4.2.0
3595
+		 * @param array $query_args       The original query_args array coming into the
3596
+		 *                                method.
3597
+		 */
3598
+		do_action(
3599
+			"AHEE__{$classname}___redirect_after_action__before_redirect_modification_{$this->_req_action}",
3600
+			$query_args
3601
+		);
3602
+		// calculate where we're going (if we have a "save and close" button pushed)
3603
+		if (isset($this->_req_data['save_and_close'], $this->_req_data['save_and_close_referrer'])) {
3604
+			// even though we have the save_and_close referrer, we need to parse the url for the action in order to generate a nonce
3605
+			$parsed_url = parse_url($this->_req_data['save_and_close_referrer']);
3606
+			// regenerate query args array from referrer URL
3607
+			parse_str($parsed_url['query'], $query_args);
3608
+			// correct page and action will be in the query args now
3609
+			$redirect_url = admin_url('admin.php');
3610
+		}
3611
+		// merge any default query_args set in _default_route_query_args property
3612
+		if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3613
+			$args_to_merge = array();
3614
+			foreach ($this->_default_route_query_args as $query_param => $query_value) {
3615
+				// is there a wp_referer array in our _default_route_query_args property?
3616
+				if ($query_param === 'wp_referer') {
3617
+					$query_value = (array) $query_value;
3618
+					foreach ($query_value as $reference => $value) {
3619
+						if (strpos($reference, 'nonce') !== false) {
3620
+							continue;
3621
+						}
3622
+						// finally we will override any arguments in the referer with
3623
+						// what might be set on the _default_route_query_args array.
3624
+						if (isset($this->_default_route_query_args[ $reference ])) {
3625
+							$args_to_merge[ $reference ] = urlencode($this->_default_route_query_args[ $reference ]);
3626
+						} else {
3627
+							$args_to_merge[ $reference ] = urlencode($value);
3628
+						}
3629
+					}
3630
+					continue;
3631
+				}
3632
+				$args_to_merge[ $query_param ] = $query_value;
3633
+			}
3634
+			// now let's merge these arguments but override with what was specifically sent in to the
3635
+			// redirect.
3636
+			$query_args = array_merge($args_to_merge, $query_args);
3637
+		}
3638
+		$this->_process_notices($query_args);
3639
+		// generate redirect url
3640
+		// if redirecting to anything other than the main page, add a nonce
3641
+		if (isset($query_args['action'])) {
3642
+			// manually generate wp_nonce and merge that with the query vars
3643
+			// becuz the wp_nonce_url function wrecks havoc on some vars
3644
+			$query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce');
3645
+		}
3646
+		// we're adding some hooks and filters in here for processing any things just before redirects
3647
+		// (example: an admin page has done an insert or update and we want to run something after that).
3648
+		do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args);
3649
+		$redirect_url = apply_filters(
3650
+			'FHEE_redirect_' . $classname . $this->_req_action,
3651
+			EE_Admin_Page::add_query_args_and_nonce($query_args, $redirect_url),
3652
+			$query_args
3653
+		);
3654
+		// check if we're doing ajax.  If we are then lets just return the results and js can handle how it wants.
3655
+		if (defined('DOING_AJAX')) {
3656
+			$default_data = array(
3657
+				'close'        => true,
3658
+				'redirect_url' => $redirect_url,
3659
+				'where'        => 'main',
3660
+				'what'         => 'append',
3661
+			);
3662
+			$this->_template_args['success'] = $success;
3663
+			$this->_template_args['data'] = ! empty($this->_template_args['data']) ? array_merge(
3664
+				$default_data,
3665
+				$this->_template_args['data']
3666
+			) : $default_data;
3667
+			$this->_return_json();
3668
+		}
3669
+		wp_safe_redirect($redirect_url);
3670
+		exit();
3671
+	}
3672
+
3673
+
3674
+	/**
3675
+	 * process any notices before redirecting (or returning ajax request)
3676
+	 * This method sets the $this->_template_args['notices'] attribute;
3677
+	 *
3678
+	 * @param array $query_args         any query args that need to be used for notice transient ('action')
3679
+	 * @param bool  $skip_route_verify  This is typically used when we are processing notices REALLY early and
3680
+	 *                                  page_routes haven't been defined yet.
3681
+	 * @param bool  $sticky_notices     This is used to flag that regardless of whether this is doing_ajax or not, we
3682
+	 *                                  still save a transient for the notice.
3683
+	 * @return void
3684
+	 * @throws EE_Error
3685
+	 * @throws InvalidArgumentException
3686
+	 * @throws InvalidDataTypeException
3687
+	 * @throws InvalidInterfaceException
3688
+	 */
3689
+	protected function _process_notices($query_args = array(), $skip_route_verify = false, $sticky_notices = true)
3690
+	{
3691
+		// first let's set individual error properties if doing_ajax and the properties aren't already set.
3692
+		if (defined('DOING_AJAX') && DOING_AJAX) {
3693
+			$notices = EE_Error::get_notices(false);
3694
+			if (empty($this->_template_args['success'])) {
3695
+				$this->_template_args['success'] = isset($notices['success']) ? $notices['success'] : false;
3696
+			}
3697
+			if (empty($this->_template_args['errors'])) {
3698
+				$this->_template_args['errors'] = isset($notices['errors']) ? $notices['errors'] : false;
3699
+			}
3700
+			if (empty($this->_template_args['attention'])) {
3701
+				$this->_template_args['attention'] = isset($notices['attention']) ? $notices['attention'] : false;
3702
+			}
3703
+		}
3704
+		$this->_template_args['notices'] = EE_Error::get_notices();
3705
+		// IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true)
3706
+		if (! defined('DOING_AJAX') || $sticky_notices) {
3707
+			$route = isset($query_args['action']) ? $query_args['action'] : 'default';
3708
+			$this->_add_transient(
3709
+				$route,
3710
+				$this->_template_args['notices'],
3711
+				true,
3712
+				$skip_route_verify
3713
+			);
3714
+		}
3715
+	}
3716
+
3717
+
3718
+	/**
3719
+	 * get_action_link_or_button
3720
+	 * returns the button html for adding, editing, or deleting an item (depending on given type)
3721
+	 *
3722
+	 * @param string $action        use this to indicate which action the url is generated with.
3723
+	 * @param string $type          accepted strings must be defined in the $_labels['button'] array(as the key)
3724
+	 *                              property.
3725
+	 * @param array  $extra_request if the button requires extra params you can include them in $key=>$value pairs.
3726
+	 * @param string $class         Use this to give the class for the button. Defaults to 'button-primary'
3727
+	 * @param string $base_url      If this is not provided
3728
+	 *                              the _admin_base_url will be used as the default for the button base_url.
3729
+	 *                              Otherwise this value will be used.
3730
+	 * @param bool   $exclude_nonce If true then no nonce will be in the generated button link.
3731
+	 * @return string
3732
+	 * @throws InvalidArgumentException
3733
+	 * @throws InvalidInterfaceException
3734
+	 * @throws InvalidDataTypeException
3735
+	 * @throws EE_Error
3736
+	 */
3737
+	public function get_action_link_or_button(
3738
+		$action,
3739
+		$type = 'add',
3740
+		$extra_request = array(),
3741
+		$class = 'button-primary',
3742
+		$base_url = '',
3743
+		$exclude_nonce = false
3744
+	) {
3745
+		// first let's validate the action (if $base_url is FALSE otherwise validation will happen further along)
3746
+		if (empty($base_url) && ! isset($this->_page_routes[ $action ])) {
3747
+			throw new EE_Error(
3748
+				sprintf(
3749
+					esc_html__(
3750
+						'There is no page route for given action for the button.  This action was given: %s',
3751
+						'event_espresso'
3752
+					),
3753
+					$action
3754
+				)
3755
+			);
3756
+		}
3757
+		if (! isset($this->_labels['buttons'][ $type ])) {
3758
+			throw new EE_Error(
3759
+				sprintf(
3760
+					__(
3761
+						'There is no label for the given button type (%s). Labels are set in the <code>_page_config</code> property.',
3762
+						'event_espresso'
3763
+					),
3764
+					$type
3765
+				)
3766
+			);
3767
+		}
3768
+		// finally check user access for this button.
3769
+		$has_access = $this->check_user_access($action, true);
3770
+		if (! $has_access) {
3771
+			return '';
3772
+		}
3773
+		$_base_url = ! $base_url ? $this->_admin_base_url : $base_url;
3774
+		$query_args = array(
3775
+			'action' => $action,
3776
+		);
3777
+		// merge extra_request args but make sure our original action takes precedence and doesn't get overwritten.
3778
+		if (! empty($extra_request)) {
3779
+			$query_args = array_merge($extra_request, $query_args);
3780
+		}
3781
+		$url = EE_Admin_Page::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce);
3782
+		return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][ $type ], $class);
3783
+	}
3784
+
3785
+
3786
+	/**
3787
+	 * _per_page_screen_option
3788
+	 * Utility function for adding in a per_page_option in the screen_options_dropdown.
3789
+	 *
3790
+	 * @return void
3791
+	 * @throws InvalidArgumentException
3792
+	 * @throws InvalidInterfaceException
3793
+	 * @throws InvalidDataTypeException
3794
+	 */
3795
+	protected function _per_page_screen_option()
3796
+	{
3797
+		$option = 'per_page';
3798
+		$args = array(
3799
+			'label'   => apply_filters(
3800
+				'FHEE__EE_Admin_Page___per_page_screen_options___label',
3801
+				$this->_admin_page_title,
3802
+				$this
3803
+			),
3804
+			'default' => (int) apply_filters(
3805
+				'FHEE__EE_Admin_Page___per_page_screen_options__default',
3806
+				20
3807
+			),
3808
+			'option'  => $this->_current_page . '_' . $this->_current_view . '_per_page',
3809
+		);
3810
+		// ONLY add the screen option if the user has access to it.
3811
+		if ($this->check_user_access($this->_current_view, true)) {
3812
+			add_screen_option($option, $args);
3813
+		}
3814
+	}
3815
+
3816
+
3817
+	/**
3818
+	 * set_per_page_screen_option
3819
+	 * All this does is make sure that WordPress saves any per_page screen options (if set) for the current page.
3820
+	 * we have to do this rather than running inside the 'set-screen-options' hook because it runs earlier than
3821
+	 * admin_menu.
3822
+	 *
3823
+	 * @return void
3824
+	 */
3825
+	private function _set_per_page_screen_options()
3826
+	{
3827
+		if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) {
3828
+			check_admin_referer('screen-options-nonce', 'screenoptionnonce');
3829
+			if (! $user = wp_get_current_user()) {
3830
+				return;
3831
+			}
3832
+			$option = $_POST['wp_screen_options']['option'];
3833
+			$value = $_POST['wp_screen_options']['value'];
3834
+			if ($option !== sanitize_key($option)) {
3835
+				return;
3836
+			}
3837
+			$map_option = $option;
3838
+			$option = str_replace('-', '_', $option);
3839
+			switch ($map_option) {
3840
+				case $this->_current_page . '_' . $this->_current_view . '_per_page':
3841
+					$value = (int) $value;
3842
+					$max_value = apply_filters(
3843
+						'FHEE__EE_Admin_Page___set_per_page_screen_options__max_value',
3844
+						999,
3845
+						$this->_current_page,
3846
+						$this->_current_view
3847
+					);
3848
+					if ($value < 1) {
3849
+						return;
3850
+					}
3851
+					$value = min($value, $max_value);
3852
+					break;
3853
+				default:
3854
+					$value = apply_filters(
3855
+						'FHEE__EE_Admin_Page___set_per_page_screen_options__value',
3856
+						false,
3857
+						$option,
3858
+						$value
3859
+					);
3860
+					if (false === $value) {
3861
+						return;
3862
+					}
3863
+					break;
3864
+			}
3865
+			update_user_meta($user->ID, $option, $value);
3866
+			wp_safe_redirect(remove_query_arg(array('pagenum', 'apage', 'paged'), wp_get_referer()));
3867
+			exit;
3868
+		}
3869
+	}
3870
+
3871
+
3872
+	/**
3873
+	 * This just allows for setting the $_template_args property if it needs to be set outside the object
3874
+	 *
3875
+	 * @param array $data array that will be assigned to template args.
3876
+	 */
3877
+	public function set_template_args($data)
3878
+	{
3879
+		$this->_template_args = array_merge($this->_template_args, (array) $data);
3880
+	}
3881
+
3882
+
3883
+	/**
3884
+	 * This makes available the WP transient system for temporarily moving data between routes
3885
+	 *
3886
+	 * @param string $route             the route that should receive the transient
3887
+	 * @param array  $data              the data that gets sent
3888
+	 * @param bool   $notices           If this is for notices then we use this to indicate so, otherwise its just a
3889
+	 *                                  normal route transient.
3890
+	 * @param bool   $skip_route_verify Used to indicate we want to skip route verification.  This is usually ONLY used
3891
+	 *                                  when we are adding a transient before page_routes have been defined.
3892
+	 * @return void
3893
+	 * @throws EE_Error
3894
+	 */
3895
+	protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false)
3896
+	{
3897
+		$user_id = get_current_user_id();
3898
+		if (! $skip_route_verify) {
3899
+			$this->_verify_route($route);
3900
+		}
3901
+		// now let's set the string for what kind of transient we're setting
3902
+		$transient = $notices
3903
+			? 'ee_rte_n_tx_' . $route . '_' . $user_id
3904
+			: 'rte_tx_' . $route . '_' . $user_id;
3905
+		$data = $notices ? array('notices' => $data) : $data;
3906
+		// is there already a transient for this route?  If there is then let's ADD to that transient
3907
+		$existing = is_multisite() && is_network_admin()
3908
+			? get_site_transient($transient)
3909
+			: get_transient($transient);
3910
+		if ($existing) {
3911
+			$data = array_merge((array) $data, (array) $existing);
3912
+		}
3913
+		if (is_multisite() && is_network_admin()) {
3914
+			set_site_transient($transient, $data, 8);
3915
+		} else {
3916
+			set_transient($transient, $data, 8);
3917
+		}
3918
+	}
3919
+
3920
+
3921
+	/**
3922
+	 * this retrieves the temporary transient that has been set for moving data between routes.
3923
+	 *
3924
+	 * @param bool   $notices true we get notices transient. False we just return normal route transient
3925
+	 * @param string $route
3926
+	 * @return mixed data
3927
+	 */
3928
+	protected function _get_transient($notices = false, $route = '')
3929
+	{
3930
+		$user_id = get_current_user_id();
3931
+		$route = ! $route ? $this->_req_action : $route;
3932
+		$transient = $notices
3933
+			? 'ee_rte_n_tx_' . $route . '_' . $user_id
3934
+			: 'rte_tx_' . $route . '_' . $user_id;
3935
+		$data = is_multisite() && is_network_admin()
3936
+			? get_site_transient($transient)
3937
+			: get_transient($transient);
3938
+		// delete transient after retrieval (just in case it hasn't expired);
3939
+		if (is_multisite() && is_network_admin()) {
3940
+			delete_site_transient($transient);
3941
+		} else {
3942
+			delete_transient($transient);
3943
+		}
3944
+		return $notices && isset($data['notices']) ? $data['notices'] : $data;
3945
+	}
3946
+
3947
+
3948
+	/**
3949
+	 * The purpose of this method is just to run garbage collection on any EE transients that might have expired but
3950
+	 * would not be called later. This will be assigned to run on a specific EE Admin page. (place the method in the
3951
+	 * default route callback on the EE_Admin page you want it run.)
3952
+	 *
3953
+	 * @return void
3954
+	 */
3955
+	protected function _transient_garbage_collection()
3956
+	{
3957
+		global $wpdb;
3958
+		// retrieve all existing transients
3959
+		$query = "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%rte_tx_%' OR option_name LIKE '%rte_n_tx_%'";
3960
+		if ($results = $wpdb->get_results($query)) {
3961
+			foreach ($results as $result) {
3962
+				$transient = str_replace('_transient_', '', $result->option_name);
3963
+				get_transient($transient);
3964
+				if (is_multisite() && is_network_admin()) {
3965
+					get_site_transient($transient);
3966
+				}
3967
+			}
3968
+		}
3969
+	}
3970
+
3971
+
3972
+	/**
3973
+	 * get_view
3974
+	 *
3975
+	 * @return string content of _view property
3976
+	 */
3977
+	public function get_view()
3978
+	{
3979
+		return $this->_view;
3980
+	}
3981
+
3982
+
3983
+	/**
3984
+	 * getter for the protected $_views property
3985
+	 *
3986
+	 * @return array
3987
+	 */
3988
+	public function get_views()
3989
+	{
3990
+		return $this->_views;
3991
+	}
3992
+
3993
+
3994
+	/**
3995
+	 * get_current_page
3996
+	 *
3997
+	 * @return string _current_page property value
3998
+	 */
3999
+	public function get_current_page()
4000
+	{
4001
+		return $this->_current_page;
4002
+	}
4003
+
4004
+
4005
+	/**
4006
+	 * get_current_view
4007
+	 *
4008
+	 * @return string _current_view property value
4009
+	 */
4010
+	public function get_current_view()
4011
+	{
4012
+		return $this->_current_view;
4013
+	}
4014
+
4015
+
4016
+	/**
4017
+	 * get_current_screen
4018
+	 *
4019
+	 * @return object The current WP_Screen object
4020
+	 */
4021
+	public function get_current_screen()
4022
+	{
4023
+		return $this->_current_screen;
4024
+	}
4025
+
4026
+
4027
+	/**
4028
+	 * get_current_page_view_url
4029
+	 *
4030
+	 * @return string This returns the url for the current_page_view.
4031
+	 */
4032
+	public function get_current_page_view_url()
4033
+	{
4034
+		return $this->_current_page_view_url;
4035
+	}
4036
+
4037
+
4038
+	/**
4039
+	 * just returns the _req_data property
4040
+	 *
4041
+	 * @return array
4042
+	 */
4043
+	public function get_request_data()
4044
+	{
4045
+		return $this->_req_data;
4046
+	}
4047
+
4048
+
4049
+	/**
4050
+	 * returns the _req_data protected property
4051
+	 *
4052
+	 * @return string
4053
+	 */
4054
+	public function get_req_action()
4055
+	{
4056
+		return $this->_req_action;
4057
+	}
4058
+
4059
+
4060
+	/**
4061
+	 * @return bool  value of $_is_caf property
4062
+	 */
4063
+	public function is_caf()
4064
+	{
4065
+		return $this->_is_caf;
4066
+	}
4067
+
4068
+
4069
+	/**
4070
+	 * @return mixed
4071
+	 */
4072
+	public function default_espresso_metaboxes()
4073
+	{
4074
+		return $this->_default_espresso_metaboxes;
4075
+	}
4076
+
4077
+
4078
+	/**
4079
+	 * @return mixed
4080
+	 */
4081
+	public function admin_base_url()
4082
+	{
4083
+		return $this->_admin_base_url;
4084
+	}
4085
+
4086
+
4087
+	/**
4088
+	 * @return mixed
4089
+	 */
4090
+	public function wp_page_slug()
4091
+	{
4092
+		return $this->_wp_page_slug;
4093
+	}
4094
+
4095
+
4096
+	/**
4097
+	 * updates  espresso configuration settings
4098
+	 *
4099
+	 * @param string                   $tab
4100
+	 * @param EE_Config_Base|EE_Config $config
4101
+	 * @param string                   $file file where error occurred
4102
+	 * @param string                   $func function  where error occurred
4103
+	 * @param string                   $line line no where error occurred
4104
+	 * @return boolean
4105
+	 */
4106
+	protected function _update_espresso_configuration($tab, $config, $file = '', $func = '', $line = '')
4107
+	{
4108
+		// remove any options that are NOT going to be saved with the config settings.
4109
+		if (isset($config->core->ee_ueip_optin)) {
4110
+			// TODO: remove the following two lines and make sure values are migrated from 3.1
4111
+			update_option('ee_ueip_optin', $config->core->ee_ueip_optin);
4112
+			update_option('ee_ueip_has_notified', true);
4113
+		}
4114
+		// and save it (note we're also doing the network save here)
4115
+		$net_saved = is_main_site() ? EE_Network_Config::instance()->update_config(false, false) : true;
4116
+		$config_saved = EE_Config::instance()->update_espresso_config(false, false);
4117
+		if ($config_saved && $net_saved) {
4118
+			EE_Error::add_success(sprintf(__('"%s" have been successfully updated.', 'event_espresso'), $tab));
4119
+			return true;
4120
+		}
4121
+		EE_Error::add_error(sprintf(__('The "%s" were not updated.', 'event_espresso'), $tab), $file, $func, $line);
4122
+		return false;
4123
+	}
4124
+
4125
+
4126
+	/**
4127
+	 * Returns an array to be used for EE_FOrm_Fields.helper.php's select_input as the $values argument.
4128
+	 *
4129
+	 * @return array
4130
+	 */
4131
+	public function get_yes_no_values()
4132
+	{
4133
+		return $this->_yes_no_values;
4134
+	}
4135
+
4136
+
4137
+	/**
4138
+	 * @return string
4139
+	 * @throws ReflectionException
4140
+	 * @since $VID:$
4141
+	 */
4142
+	protected function _get_dir()
4143
+	{
4144
+		$reflector = new ReflectionClass(get_class($this));
4145
+		return dirname($reflector->getFileName());
4146
+	}
4147
+
4148
+
4149
+	/**
4150
+	 * A helper for getting a "next link".
4151
+	 *
4152
+	 * @param string $url   The url to link to
4153
+	 * @param string $class The class to use.
4154
+	 * @return string
4155
+	 */
4156
+	protected function _next_link($url, $class = 'dashicons dashicons-arrow-right')
4157
+	{
4158
+		return '<a class="' . $class . '" href="' . $url . '"></a>';
4159
+	}
4160
+
4161
+
4162
+	/**
4163
+	 * A helper for getting a "previous link".
4164
+	 *
4165
+	 * @param string $url   The url to link to
4166
+	 * @param string $class The class to use.
4167
+	 * @return string
4168
+	 */
4169
+	protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left')
4170
+	{
4171
+		return '<a class="' . $class . '" href="' . $url . '"></a>';
4172
+	}
4173
+
4174
+
4175
+
4176
+
4177
+
4178
+
4179
+
4180
+	// below are some messages related methods that should be available across the EE_Admin system.  Note, these methods are NOT page specific
4181
+
4182
+
4183
+	/**
4184
+	 * This processes an request to resend a registration and assumes we have a _REG_ID for doing so. So if the caller
4185
+	 * knows that the _REG_ID isn't in the req_data array but CAN obtain it, the caller should ADD the _REG_ID to the
4186
+	 * _req_data array.
4187
+	 *
4188
+	 * @return bool success/fail
4189
+	 * @throws EE_Error
4190
+	 * @throws InvalidArgumentException
4191
+	 * @throws ReflectionException
4192
+	 * @throws InvalidDataTypeException
4193
+	 * @throws InvalidInterfaceException
4194
+	 */
4195
+	protected function _process_resend_registration()
4196
+	{
4197
+		$this->_template_args['success'] = EED_Messages::process_resend($this->_req_data);
4198
+		do_action(
4199
+			'AHEE__EE_Admin_Page___process_resend_registration',
4200
+			$this->_template_args['success'],
4201
+			$this->_req_data
4202
+		);
4203
+		return $this->_template_args['success'];
4204
+	}
4205
+
4206
+
4207
+	/**
4208
+	 * This automatically processes any payment message notifications when manual payment has been applied.
4209
+	 *
4210
+	 * @param EE_Payment $payment
4211
+	 * @return bool success/fail
4212
+	 */
4213
+	protected function _process_payment_notification(EE_Payment $payment)
4214
+	{
4215
+		add_filter('FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', '__return_true');
4216
+		do_action('AHEE__EE_Admin_Page___process_admin_payment_notification', $payment);
4217
+		$this->_template_args['success'] = apply_filters(
4218
+			'FHEE__EE_Admin_Page___process_admin_payment_notification__success',
4219
+			false,
4220
+			$payment
4221
+		);
4222
+		return $this->_template_args['success'];
4223
+	}
4224 4224
 }
Please login to merge, or discard this patch.
Spacing   +188 added lines, -188 removed lines patch added patch discarded remove patch
@@ -523,7 +523,7 @@  discard block
 block discarded – undo
523 523
         );
524 524
         global $ee_menu_slugs;
525 525
         $ee_menu_slugs = (array) $ee_menu_slugs;
526
-        if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[ $this->_current_page ]))) {
526
+        if ( ! defined('DOING_AJAX') && ( ! $this->_current_page || ! isset($ee_menu_slugs[$this->_current_page]))) {
527 527
             return;
528 528
         }
529 529
         // becuz WP List tables have two duplicate select inputs for choosing bulk actions, we need to copy the action from the second to the first
@@ -547,7 +547,7 @@  discard block
 block discarded – undo
547 547
             ? $this->_req_data['route']
548 548
             : $this->_req_action;
549 549
         $this->_current_view = $this->_req_action;
550
-        $this->_req_nonce = $this->_req_action . '_nonce';
550
+        $this->_req_nonce = $this->_req_action.'_nonce';
551 551
         $this->_define_page_props();
552 552
         $this->_current_page_view_url = add_query_arg(
553 553
             array('page' => $this->_current_page, 'action' => $this->_current_view),
@@ -581,21 +581,21 @@  discard block
 block discarded – undo
581 581
         }
582 582
         // filter routes and page_config so addons can add their stuff. Filtering done per class
583 583
         $this->_page_routes = apply_filters(
584
-            'FHEE__' . get_class($this) . '__page_setup__page_routes',
584
+            'FHEE__'.get_class($this).'__page_setup__page_routes',
585 585
             $this->_page_routes,
586 586
             $this
587 587
         );
588 588
         $this->_page_config = apply_filters(
589
-            'FHEE__' . get_class($this) . '__page_setup__page_config',
589
+            'FHEE__'.get_class($this).'__page_setup__page_config',
590 590
             $this->_page_config,
591 591
             $this
592 592
         );
593 593
         // if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present
594 594
         // then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action
595
-        if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)) {
595
+        if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_'.$this->_current_view)) {
596 596
             add_action(
597 597
                 'AHEE__EE_Admin_Page__route_admin_request',
598
-                array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view),
598
+                array($this, 'AHEE__EE_Admin_Page__route_admin_request_'.$this->_current_view),
599 599
                 10,
600 600
                 2
601 601
             );
@@ -608,8 +608,8 @@  discard block
 block discarded – undo
608 608
             if ($this->_is_UI_request) {
609 609
                 // admin_init stuff - global, all views for this page class, specific view
610 610
                 add_action('admin_init', array($this, 'admin_init'), 10);
611
-                if (method_exists($this, 'admin_init_' . $this->_current_view)) {
612
-                    add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15);
611
+                if (method_exists($this, 'admin_init_'.$this->_current_view)) {
612
+                    add_action('admin_init', array($this, 'admin_init_'.$this->_current_view), 15);
613 613
                 }
614 614
             } else {
615 615
                 // hijack regular WP loading and route admin request immediately
@@ -628,12 +628,12 @@  discard block
 block discarded – undo
628 628
      */
629 629
     private function _do_other_page_hooks()
630 630
     {
631
-        $registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array());
631
+        $registered_pages = apply_filters('FHEE_do_other_page_hooks_'.$this->page_slug, array());
632 632
         foreach ($registered_pages as $page) {
633 633
             // now let's setup the file name and class that should be present
634 634
             $classname = str_replace('.class.php', '', $page);
635 635
             // autoloaders should take care of loading file
636
-            if (! class_exists($classname)) {
636
+            if ( ! class_exists($classname)) {
637 637
                 $error_msg[] = sprintf(
638 638
                     esc_html__(
639 639
                         'Something went wrong with loading the %s admin hooks page.',
@@ -650,7 +650,7 @@  discard block
 block discarded – undo
650 650
                                    ),
651 651
                                    $page,
652 652
                                    '<br />',
653
-                                   '<strong>' . $classname . '</strong>'
653
+                                   '<strong>'.$classname.'</strong>'
654 654
                                );
655 655
                 throw new EE_Error(implode('||', $error_msg));
656 656
             }
@@ -698,13 +698,13 @@  discard block
 block discarded – undo
698 698
         // load admin_notices - global, page class, and view specific
699 699
         add_action('admin_notices', array($this, 'admin_notices_global'), 5);
700 700
         add_action('admin_notices', array($this, 'admin_notices'), 10);
701
-        if (method_exists($this, 'admin_notices_' . $this->_current_view)) {
702
-            add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15);
701
+        if (method_exists($this, 'admin_notices_'.$this->_current_view)) {
702
+            add_action('admin_notices', array($this, 'admin_notices_'.$this->_current_view), 15);
703 703
         }
704 704
         // load network admin_notices - global, page class, and view specific
705 705
         add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5);
706
-        if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) {
707
-            add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view));
706
+        if (method_exists($this, 'network_admin_notices_'.$this->_current_view)) {
707
+            add_action('network_admin_notices', array($this, 'network_admin_notices_'.$this->_current_view));
708 708
         }
709 709
         // this will save any per_page screen options if they are present
710 710
         $this->_set_per_page_screen_options();
@@ -825,7 +825,7 @@  discard block
 block discarded – undo
825 825
      */
826 826
     protected function _verify_routes()
827 827
     {
828
-        if (! $this->_current_page && ! defined('DOING_AJAX')) {
828
+        if ( ! $this->_current_page && ! defined('DOING_AJAX')) {
829 829
             return false;
830 830
         }
831 831
         $this->_route = false;
@@ -837,7 +837,7 @@  discard block
 block discarded – undo
837 837
                 $this->_admin_page_title
838 838
             );
839 839
             // developer error msg
840
-            $error_msg .= '||' . $error_msg
840
+            $error_msg .= '||'.$error_msg
841 841
                           . esc_html__(
842 842
                               ' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.',
843 843
                               'event_espresso'
@@ -846,9 +846,9 @@  discard block
 block discarded – undo
846 846
         }
847 847
         // and that the requested page route exists
848 848
         if (array_key_exists($this->_req_action, $this->_page_routes)) {
849
-            $this->_route = $this->_page_routes[ $this->_req_action ];
850
-            $this->_route_config = isset($this->_page_config[ $this->_req_action ])
851
-                ? $this->_page_config[ $this->_req_action ] : array();
849
+            $this->_route = $this->_page_routes[$this->_req_action];
850
+            $this->_route_config = isset($this->_page_config[$this->_req_action])
851
+                ? $this->_page_config[$this->_req_action] : array();
852 852
         } else {
853 853
             // user error msg
854 854
             $error_msg = sprintf(
@@ -859,7 +859,7 @@  discard block
 block discarded – undo
859 859
                 $this->_admin_page_title
860 860
             );
861 861
             // developer error msg
862
-            $error_msg .= '||' . $error_msg
862
+            $error_msg .= '||'.$error_msg
863 863
                           . sprintf(
864 864
                               esc_html__(
865 865
                                   ' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.',
@@ -870,7 +870,7 @@  discard block
 block discarded – undo
870 870
             throw new EE_Error($error_msg);
871 871
         }
872 872
         // and that a default route exists
873
-        if (! array_key_exists('default', $this->_page_routes)) {
873
+        if ( ! array_key_exists('default', $this->_page_routes)) {
874 874
             // user error msg
875 875
             $error_msg = sprintf(
876 876
                 esc_html__(
@@ -880,7 +880,7 @@  discard block
 block discarded – undo
880 880
                 $this->_admin_page_title
881 881
             );
882 882
             // developer error msg
883
-            $error_msg .= '||' . $error_msg
883
+            $error_msg .= '||'.$error_msg
884 884
                           . esc_html__(
885 885
                               ' Create a key in the "_page_routes" array named "default" and set its value to your default page method.',
886 886
                               'event_espresso'
@@ -920,7 +920,7 @@  discard block
 block discarded – undo
920 920
             $this->_admin_page_title
921 921
         );
922 922
         // developer error msg
923
-        $error_msg .= '||' . $error_msg
923
+        $error_msg .= '||'.$error_msg
924 924
                       . sprintf(
925 925
                           esc_html__(
926 926
                               ' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property',
@@ -948,7 +948,7 @@  discard block
 block discarded – undo
948 948
     protected function _verify_nonce($nonce, $nonce_ref)
949 949
     {
950 950
         // verify nonce against expected value
951
-        if (! wp_verify_nonce($nonce, $nonce_ref)) {
951
+        if ( ! wp_verify_nonce($nonce, $nonce_ref)) {
952 952
             // these are not the droids you are looking for !!!
953 953
             $msg = sprintf(
954 954
                 esc_html__('%sNonce Fail.%s', 'event_espresso'),
@@ -965,7 +965,7 @@  discard block
 block discarded – undo
965 965
                             EE_Admin_Page::class
966 966
                         );
967 967
             }
968
-            if (! defined('DOING_AJAX')) {
968
+            if ( ! defined('DOING_AJAX')) {
969 969
                 wp_die($msg);
970 970
             } else {
971 971
                 EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
@@ -990,7 +990,7 @@  discard block
 block discarded – undo
990 990
      */
991 991
     protected function _route_admin_request()
992 992
     {
993
-        if (! $this->_is_UI_request) {
993
+        if ( ! $this->_is_UI_request) {
994 994
             $this->_verify_routes();
995 995
         }
996 996
         $nonce_check = isset($this->_route_config['require_nonce'])
@@ -998,8 +998,8 @@  discard block
 block discarded – undo
998 998
             : true;
999 999
         if ($this->_req_action !== 'default' && $nonce_check) {
1000 1000
             // set nonce from post data
1001
-            $nonce = isset($this->_req_data[ $this->_req_nonce ])
1002
-                ? sanitize_text_field($this->_req_data[ $this->_req_nonce ])
1001
+            $nonce = isset($this->_req_data[$this->_req_nonce])
1002
+                ? sanitize_text_field($this->_req_data[$this->_req_nonce])
1003 1003
                 : '';
1004 1004
             $this->_verify_nonce($nonce, $this->_req_nonce);
1005 1005
         }
@@ -1014,7 +1014,7 @@  discard block
 block discarded – undo
1014 1014
         $error_msg = '';
1015 1015
         // action right before calling route
1016 1016
         // (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request')
1017
-        if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
1017
+        if ( ! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
1018 1018
             do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this);
1019 1019
         }
1020 1020
         // right before calling the route, let's remove _wp_http_referer from the
@@ -1023,7 +1023,7 @@  discard block
 block discarded – undo
1023 1023
             '_wp_http_referer',
1024 1024
             wp_unslash($_SERVER['REQUEST_URI'])
1025 1025
         );
1026
-        if (! empty($func)) {
1026
+        if ( ! empty($func)) {
1027 1027
             if (is_array($func)) {
1028 1028
                 list($class, $method) = $func;
1029 1029
             } elseif (strpos($func, '::') !== false) {
@@ -1032,7 +1032,7 @@  discard block
 block discarded – undo
1032 1032
                 $class = $this;
1033 1033
                 $method = $func;
1034 1034
             }
1035
-            if (! (is_object($class) && $class === $this)) {
1035
+            if ( ! (is_object($class) && $class === $this)) {
1036 1036
                 // send along this admin page object for access by addons.
1037 1037
                 $args['admin_page_object'] = $this;
1038 1038
             }
@@ -1065,7 +1065,7 @@  discard block
 block discarded – undo
1065 1065
                     $method
1066 1066
                 );
1067 1067
             }
1068
-            if (! empty($error_msg)) {
1068
+            if ( ! empty($error_msg)) {
1069 1069
                 throw new EE_Error($error_msg);
1070 1070
             }
1071 1071
         }
@@ -1148,7 +1148,7 @@  discard block
 block discarded – undo
1148 1148
                 if (strpos($key, 'nonce') !== false) {
1149 1149
                     continue;
1150 1150
                 }
1151
-                $args[ 'wp_referer[' . $key . ']' ] = $value;
1151
+                $args['wp_referer['.$key.']'] = $value;
1152 1152
             }
1153 1153
         }
1154 1154
         return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce);
@@ -1189,10 +1189,10 @@  discard block
 block discarded – undo
1189 1189
     protected function _add_help_tabs()
1190 1190
     {
1191 1191
         $tour_buttons = '';
1192
-        if (isset($this->_page_config[ $this->_req_action ])) {
1193
-            $config = $this->_page_config[ $this->_req_action ];
1192
+        if (isset($this->_page_config[$this->_req_action])) {
1193
+            $config = $this->_page_config[$this->_req_action];
1194 1194
             // is there a help tour for the current route?  if there is let's setup the tour buttons
1195
-            if (isset($this->_help_tour[ $this->_req_action ])) {
1195
+            if (isset($this->_help_tour[$this->_req_action])) {
1196 1196
                 $tb = array();
1197 1197
                 $tour_buttons = '<div class="ee-abs-container"><div class="ee-help-tour-restart-buttons">';
1198 1198
                 foreach ($this->_help_tour['tours'] as $tour) {
@@ -1212,7 +1212,7 @@  discard block
 block discarded – undo
1212 1212
             // let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well.
1213 1213
             if (is_array($config) && isset($config['help_sidebar'])) {
1214 1214
                 // check that the callback given is valid
1215
-                if (! method_exists($this, $config['help_sidebar'])) {
1215
+                if ( ! method_exists($this, $config['help_sidebar'])) {
1216 1216
                     throw new EE_Error(
1217 1217
                         sprintf(
1218 1218
                             esc_html__(
@@ -1225,7 +1225,7 @@  discard block
 block discarded – undo
1225 1225
                     );
1226 1226
                 }
1227 1227
                 $content = apply_filters(
1228
-                    'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar',
1228
+                    'FHEE__'.get_class($this).'__add_help_tabs__help_sidebar',
1229 1229
                     $this->{$config['help_sidebar']}()
1230 1230
                 );
1231 1231
                 $content .= $tour_buttons; // add help tour buttons.
@@ -1233,30 +1233,30 @@  discard block
 block discarded – undo
1233 1233
                 $this->_current_screen->set_help_sidebar($content);
1234 1234
             }
1235 1235
             // if there ARE tour buttons...
1236
-            if (! empty($tour_buttons)) {
1236
+            if ( ! empty($tour_buttons)) {
1237 1237
                 // if we DON'T have config help sidebar then we'll just add the tour buttons to the sidebar.
1238
-                if (! isset($config['help_sidebar'])) {
1238
+                if ( ! isset($config['help_sidebar'])) {
1239 1239
                     $this->_current_screen->set_help_sidebar($tour_buttons);
1240 1240
                 }
1241 1241
                 // handle if no help_tabs are set so the sidebar will still show for the help tour buttons
1242
-                if (! isset($config['help_tabs'])) {
1242
+                if ( ! isset($config['help_tabs'])) {
1243 1243
                     $_ht['id'] = $this->page_slug;
1244 1244
                     $_ht['title'] = esc_html__('Help Tours', 'event_espresso');
1245 1245
                     $_ht['content'] = '<p>'
1246 1246
                                       . esc_html__(
1247 1247
                                           'The buttons to the right allow you to start/restart any help tours available for this page',
1248 1248
                                           'event_espresso'
1249
-                                      ) . '</p>';
1249
+                                      ).'</p>';
1250 1250
                     $this->_current_screen->add_help_tab($_ht);
1251 1251
                 }
1252 1252
             }
1253
-            if (! isset($config['help_tabs'])) {
1253
+            if ( ! isset($config['help_tabs'])) {
1254 1254
                 return;
1255 1255
             } //no help tabs for this route
1256 1256
             foreach ((array) $config['help_tabs'] as $tab_id => $cfg) {
1257 1257
                 // we're here so there ARE help tabs!
1258 1258
                 // make sure we've got what we need
1259
-                if (! isset($cfg['title'])) {
1259
+                if ( ! isset($cfg['title'])) {
1260 1260
                     throw new EE_Error(
1261 1261
                         esc_html__(
1262 1262
                             'The _page_config array is not set up properly for help tabs.  It is missing a title',
@@ -1264,7 +1264,7 @@  discard block
 block discarded – undo
1264 1264
                         )
1265 1265
                     );
1266 1266
                 }
1267
-                if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1267
+                if ( ! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1268 1268
                     throw new EE_Error(
1269 1269
                         esc_html__(
1270 1270
                             'The _page_config array is not setup properly for help tabs. It is missing a either a filename reference, or a callback reference or a content reference so there is no way to know the content for the help tab',
@@ -1273,11 +1273,11 @@  discard block
 block discarded – undo
1273 1273
                     );
1274 1274
                 }
1275 1275
                 // first priority goes to content.
1276
-                if (! empty($cfg['content'])) {
1276
+                if ( ! empty($cfg['content'])) {
1277 1277
                     $content = ! empty($cfg['content']) ? $cfg['content'] : null;
1278 1278
                     // second priority goes to filename
1279
-                } elseif (! empty($cfg['filename'])) {
1280
-                    $file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php';
1279
+                } elseif ( ! empty($cfg['filename'])) {
1280
+                    $file_path = $this->_get_dir().'/help_tabs/'.$cfg['filename'].'.help_tab.php';
1281 1281
                     // it's possible that the file is located on decaf route (and above sets up for caf route, if this is the case then lets check decaf route too)
1282 1282
                     $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1283 1283
                                                              . basename($this->_get_dir())
@@ -1285,7 +1285,7 @@  discard block
 block discarded – undo
1285 1285
                                                              . $cfg['filename']
1286 1286
                                                              . '.help_tab.php' : $file_path;
1287 1287
                     // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1288
-                    if (! isset($cfg['callback']) && ! is_readable($file_path)) {
1288
+                    if ( ! isset($cfg['callback']) && ! is_readable($file_path)) {
1289 1289
                         EE_Error::add_error(
1290 1290
                             sprintf(
1291 1291
                                 esc_html__(
@@ -1331,7 +1331,7 @@  discard block
 block discarded – undo
1331 1331
                     return;
1332 1332
                 }
1333 1333
                 // setup config array for help tab method
1334
-                $id = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id;
1334
+                $id = $this->page_slug.'-'.$this->_req_action.'-'.$tab_id;
1335 1335
                 $_ht = array(
1336 1336
                     'id'       => $id,
1337 1337
                     'title'    => $cfg['title'],
@@ -1376,7 +1376,7 @@  discard block
 block discarded – undo
1376 1376
             }
1377 1377
             if (isset($config['help_tour'])) {
1378 1378
                 foreach ($config['help_tour'] as $tour) {
1379
-                    $file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php';
1379
+                    $file_path = $this->_get_dir().'/help_tours/'.$tour.'.class.php';
1380 1380
                     // let's see if we can get that file...
1381 1381
                     // if not its possible this is a decaf route not set in caffeinated
1382 1382
                     // so lets try and get the caffeinated equivalent
@@ -1386,7 +1386,7 @@  discard block
 block discarded – undo
1386 1386
                                                              . $tour
1387 1387
                                                              . '.class.php' : $file_path;
1388 1388
                     // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1389
-                    if (! is_readable($file_path)) {
1389
+                    if ( ! is_readable($file_path)) {
1390 1390
                         EE_Error::add_error(
1391 1391
                             sprintf(
1392 1392
                                 esc_html__(
@@ -1403,13 +1403,13 @@  discard block
 block discarded – undo
1403 1403
                         return;
1404 1404
                     }
1405 1405
                     require_once $file_path;
1406
-                    if (! class_exists($tour)) {
1406
+                    if ( ! class_exists($tour)) {
1407 1407
                         $error_msg = [];
1408 1408
                         $error_msg[] = sprintf(
1409 1409
                             esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'),
1410 1410
                             $tour
1411 1411
                         );
1412
-                        $error_msg[] = $error_msg[0] . "\r\n"
1412
+                        $error_msg[] = $error_msg[0]."\r\n"
1413 1413
                                        . sprintf(
1414 1414
                                            esc_html__(
1415 1415
                                                'There is no class in place for the %s help tour.%s Make sure you have <strong>%s</strong> defined in the "help_tour" array for the %s route of the % admin page.',
@@ -1425,16 +1425,16 @@  discard block
 block discarded – undo
1425 1425
                     }
1426 1426
                     $tour_obj = new $tour($this->_is_caf);
1427 1427
                     $tours[] = $tour_obj;
1428
-                    $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($tour_obj);
1428
+                    $this->_help_tour[$route][] = EEH_Template::help_tour_stops_generator($tour_obj);
1429 1429
                 }
1430 1430
                 // let's inject the end tour stop element common to all pages... this will only get seen once per machine.
1431 1431
                 $end_stop_tour = new EE_Help_Tour_final_stop($this->_is_caf);
1432 1432
                 $tours[] = $end_stop_tour;
1433
-                $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($end_stop_tour);
1433
+                $this->_help_tour[$route][] = EEH_Template::help_tour_stops_generator($end_stop_tour);
1434 1434
             }
1435 1435
         }
1436 1436
 
1437
-        if (! empty($tours)) {
1437
+        if ( ! empty($tours)) {
1438 1438
             $this->_help_tour['tours'] = $tours;
1439 1439
         }
1440 1440
         // that's it!  Now that the $_help_tours property is set (or not)
@@ -1462,8 +1462,8 @@  discard block
 block discarded – undo
1462 1462
             $qtips = (array) $this->_route_config['qtips'];
1463 1463
             // load qtip loader
1464 1464
             $path = array(
1465
-                $this->_get_dir() . '/qtips/',
1466
-                EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/',
1465
+                $this->_get_dir().'/qtips/',
1466
+                EE_ADMIN_PAGES.basename($this->_get_dir()).'/qtips/',
1467 1467
             );
1468 1468
             $qtip_loader = EEH_Qtip_Loader::instance();
1469 1469
             if ($qtip_loader instanceof EEH_Qtip_Loader) {
@@ -1488,7 +1488,7 @@  discard block
 block discarded – undo
1488 1488
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1489 1489
         $i = 0;
1490 1490
         foreach ($this->_page_config as $slug => $config) {
1491
-            if (! is_array($config)
1491
+            if ( ! is_array($config)
1492 1492
                 || (
1493 1493
                     is_array($config)
1494 1494
                     && (
@@ -1505,12 +1505,12 @@  discard block
 block discarded – undo
1505 1505
                 // nav tab is only to appear when route requested.
1506 1506
                 continue;
1507 1507
             }
1508
-            if (! $this->check_user_access($slug, true)) {
1508
+            if ( ! $this->check_user_access($slug, true)) {
1509 1509
                 // no nav tab because current user does not have access.
1510 1510
                 continue;
1511 1511
             }
1512
-            $css_class = isset($config['css_class']) ? $config['css_class'] . ' ' : '';
1513
-            $this->_nav_tabs[ $slug ] = array(
1512
+            $css_class = isset($config['css_class']) ? $config['css_class'].' ' : '';
1513
+            $this->_nav_tabs[$slug] = array(
1514 1514
                 'url'       => isset($config['nav']['url'])
1515 1515
                     ? $config['nav']['url']
1516 1516
                     : EE_Admin_Page::add_query_args_and_nonce(
@@ -1522,14 +1522,14 @@  discard block
 block discarded – undo
1522 1522
                     : ucwords(
1523 1523
                         str_replace('_', ' ', $slug)
1524 1524
                     ),
1525
-                'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class,
1525
+                'css_class' => $this->_req_action === $slug ? $css_class.'nav-tab-active' : $css_class,
1526 1526
                 'order'     => isset($config['nav']['order']) ? $config['nav']['order'] : $i,
1527 1527
             );
1528 1528
             $i++;
1529 1529
         }
1530 1530
         // if $this->_nav_tabs is empty then lets set the default
1531 1531
         if (empty($this->_nav_tabs)) {
1532
-            $this->_nav_tabs[ $this->_default_nav_tab_name ] = array(
1532
+            $this->_nav_tabs[$this->_default_nav_tab_name] = array(
1533 1533
                 'url'       => $this->_admin_base_url,
1534 1534
                 'link_text' => ucwords(str_replace('_', ' ', $this->_default_nav_tab_name)),
1535 1535
                 'css_class' => 'nav-tab-active',
@@ -1554,10 +1554,10 @@  discard block
 block discarded – undo
1554 1554
             foreach ($this->_route_config['labels'] as $label => $text) {
1555 1555
                 if (is_array($text)) {
1556 1556
                     foreach ($text as $sublabel => $subtext) {
1557
-                        $this->_labels[ $label ][ $sublabel ] = $subtext;
1557
+                        $this->_labels[$label][$sublabel] = $subtext;
1558 1558
                     }
1559 1559
                 } else {
1560
-                    $this->_labels[ $label ] = $text;
1560
+                    $this->_labels[$label] = $text;
1561 1561
                 }
1562 1562
             }
1563 1563
         }
@@ -1579,12 +1579,12 @@  discard block
 block discarded – undo
1579 1579
     {
1580 1580
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1581 1581
         $route_to_check = empty($route_to_check) ? $this->_req_action : $route_to_check;
1582
-        $capability = ! empty($route_to_check) && isset($this->_page_routes[ $route_to_check ])
1582
+        $capability = ! empty($route_to_check) && isset($this->_page_routes[$route_to_check])
1583 1583
                       && is_array(
1584
-                          $this->_page_routes[ $route_to_check ]
1584
+                          $this->_page_routes[$route_to_check]
1585 1585
                       )
1586
-                      && ! empty($this->_page_routes[ $route_to_check ]['capability'])
1587
-            ? $this->_page_routes[ $route_to_check ]['capability'] : null;
1586
+                      && ! empty($this->_page_routes[$route_to_check]['capability'])
1587
+            ? $this->_page_routes[$route_to_check]['capability'] : null;
1588 1588
         if (empty($capability) && empty($route_to_check)) {
1589 1589
             $capability = is_array($this->_route) && empty($this->_route['capability']) ? 'manage_options'
1590 1590
                 : $this->_route['capability'];
@@ -1592,7 +1592,7 @@  discard block
 block discarded – undo
1592 1592
             $capability = empty($capability) ? 'manage_options' : $capability;
1593 1593
         }
1594 1594
         $id = is_array($this->_route) && ! empty($this->_route['obj_id']) ? $this->_route['obj_id'] : 0;
1595
-        if (! defined('DOING_AJAX')
1595
+        if ( ! defined('DOING_AJAX')
1596 1596
             && (
1597 1597
                 ! function_exists('is_admin')
1598 1598
                 || ! EE_Registry::instance()->CAP->current_user_can(
@@ -1697,17 +1697,17 @@  discard block
 block discarded – undo
1697 1697
     public function admin_footer_global()
1698 1698
     {
1699 1699
         // dialog container for dialog helper
1700
-        $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n";
1700
+        $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">'."\n";
1701 1701
         $d_cont .= '<div class="ee-notices"></div>';
1702 1702
         $d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>';
1703 1703
         $d_cont .= '</div>';
1704 1704
         echo $d_cont;
1705 1705
         // help tour stuff?
1706
-        if (isset($this->_help_tour[ $this->_req_action ])) {
1707
-            echo implode('<br />', $this->_help_tour[ $this->_req_action ]);
1706
+        if (isset($this->_help_tour[$this->_req_action])) {
1707
+            echo implode('<br />', $this->_help_tour[$this->_req_action]);
1708 1708
         }
1709 1709
         // current set timezone for timezone js
1710
-        echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>';
1710
+        echo '<span id="current_timezone" class="hidden">'.EEH_DTT_Helper::get_timezone().'</span>';
1711 1711
     }
1712 1712
 
1713 1713
 
@@ -1741,7 +1741,7 @@  discard block
 block discarded – undo
1741 1741
         // loop through the array and setup content
1742 1742
         foreach ($help_array as $trigger => $help) {
1743 1743
             // make sure the array is setup properly
1744
-            if (! isset($help['title'], $help['content'])) {
1744
+            if ( ! isset($help['title'], $help['content'])) {
1745 1745
                 throw new EE_Error(
1746 1746
                     esc_html__(
1747 1747
                         'Does not look like the popup content array has been setup correctly.  Might want to double check that.  Read the comments for the _get_help_popup_content method found in "EE_Admin_Page" class',
@@ -1756,7 +1756,7 @@  discard block
 block discarded – undo
1756 1756
                 'help_popup_content' => $help['content'],
1757 1757
             );
1758 1758
             $content .= EEH_Template::display_template(
1759
-                EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php',
1759
+                EE_ADMIN_TEMPLATE.'admin_help_popup.template.php',
1760 1760
                 $template_args,
1761 1761
                 true
1762 1762
             );
@@ -1778,15 +1778,15 @@  discard block
 block discarded – undo
1778 1778
     private function _get_help_content()
1779 1779
     {
1780 1780
         // what is the method we're looking for?
1781
-        $method_name = '_help_popup_content_' . $this->_req_action;
1781
+        $method_name = '_help_popup_content_'.$this->_req_action;
1782 1782
         // if method doesn't exist let's get out.
1783
-        if (! method_exists($this, $method_name)) {
1783
+        if ( ! method_exists($this, $method_name)) {
1784 1784
             return array();
1785 1785
         }
1786 1786
         // k we're good to go let's retrieve the help array
1787 1787
         $help_array = $this->{$method_name}();
1788 1788
         // make sure we've got an array!
1789
-        if (! is_array($help_array)) {
1789
+        if ( ! is_array($help_array)) {
1790 1790
             throw new EE_Error(
1791 1791
                 esc_html__(
1792 1792
                     'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.',
@@ -1818,8 +1818,8 @@  discard block
 block discarded – undo
1818 1818
         // let's check and see if there is any content set for this popup.  If there isn't then we'll include a default title and content so that developers know something needs to be corrected
1819 1819
         $help_array = $this->_get_help_content();
1820 1820
         $help_content = '';
1821
-        if (empty($help_array) || ! isset($help_array[ $trigger_id ])) {
1822
-            $help_array[ $trigger_id ] = array(
1821
+        if (empty($help_array) || ! isset($help_array[$trigger_id])) {
1822
+            $help_array[$trigger_id] = array(
1823 1823
                 'title'   => esc_html__('Missing Content', 'event_espresso'),
1824 1824
                 'content' => esc_html__(
1825 1825
                     'A trigger has been set that doesn\'t have any corresponding content. Make sure you have set the help content. (see the "_set_help_popup_content" method in the EE_Admin_Page for instructions.)',
@@ -1895,15 +1895,15 @@  discard block
 block discarded – undo
1895 1895
         // register all styles
1896 1896
         wp_register_style(
1897 1897
             'espresso-ui-theme',
1898
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1898
+            EE_GLOBAL_ASSETS_URL.'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1899 1899
             array(),
1900 1900
             EVENT_ESPRESSO_VERSION
1901 1901
         );
1902
-        wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1902
+        wp_register_style('ee-admin-css', EE_ADMIN_URL.'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1903 1903
         // helpers styles
1904 1904
         wp_register_style(
1905 1905
             'ee-text-links',
1906
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css',
1906
+            EE_PLUGIN_DIR_URL.'core/helpers/assets/ee_text_list_helper.css',
1907 1907
             array(),
1908 1908
             EVENT_ESPRESSO_VERSION
1909 1909
         );
@@ -1911,21 +1911,21 @@  discard block
 block discarded – undo
1911 1911
         // register all scripts
1912 1912
         wp_register_script(
1913 1913
             'ee-dialog',
1914
-            EE_ADMIN_URL . 'assets/ee-dialog-helper.js',
1914
+            EE_ADMIN_URL.'assets/ee-dialog-helper.js',
1915 1915
             array('jquery', 'jquery-ui-draggable'),
1916 1916
             EVENT_ESPRESSO_VERSION,
1917 1917
             true
1918 1918
         );
1919 1919
         wp_register_script(
1920 1920
             'ee_admin_js',
1921
-            EE_ADMIN_URL . 'assets/ee-admin-page.js',
1921
+            EE_ADMIN_URL.'assets/ee-admin-page.js',
1922 1922
             array('espresso_core', 'ee-parse-uri', 'ee-dialog'),
1923 1923
             EVENT_ESPRESSO_VERSION,
1924 1924
             true
1925 1925
         );
1926 1926
         wp_register_script(
1927 1927
             'jquery-ui-timepicker-addon',
1928
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js',
1928
+            EE_GLOBAL_ASSETS_URL.'scripts/jquery-ui-timepicker-addon.js',
1929 1929
             array('jquery-ui-datepicker', 'jquery-ui-slider'),
1930 1930
             EVENT_ESPRESSO_VERSION,
1931 1931
             true
@@ -1936,7 +1936,7 @@  discard block
 block discarded – undo
1936 1936
         // script for sorting tables
1937 1937
         wp_register_script(
1938 1938
             'espresso_ajax_table_sorting',
1939
-            EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js',
1939
+            EE_ADMIN_URL.'assets/espresso_ajax_table_sorting.js',
1940 1940
             array('ee_admin_js', 'jquery-ui-sortable'),
1941 1941
             EVENT_ESPRESSO_VERSION,
1942 1942
             true
@@ -1944,7 +1944,7 @@  discard block
 block discarded – undo
1944 1944
         // script for parsing uri's
1945 1945
         wp_register_script(
1946 1946
             'ee-parse-uri',
1947
-            EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js',
1947
+            EE_GLOBAL_ASSETS_URL.'scripts/parseuri.js',
1948 1948
             array(),
1949 1949
             EVENT_ESPRESSO_VERSION,
1950 1950
             true
@@ -1952,7 +1952,7 @@  discard block
 block discarded – undo
1952 1952
         // and parsing associative serialized form elements
1953 1953
         wp_register_script(
1954 1954
             'ee-serialize-full-array',
1955
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js',
1955
+            EE_GLOBAL_ASSETS_URL.'scripts/jquery.serializefullarray.js',
1956 1956
             array('jquery'),
1957 1957
             EVENT_ESPRESSO_VERSION,
1958 1958
             true
@@ -1960,28 +1960,28 @@  discard block
 block discarded – undo
1960 1960
         // helpers scripts
1961 1961
         wp_register_script(
1962 1962
             'ee-text-links',
1963
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js',
1963
+            EE_PLUGIN_DIR_URL.'core/helpers/assets/ee_text_list_helper.js',
1964 1964
             array('jquery'),
1965 1965
             EVENT_ESPRESSO_VERSION,
1966 1966
             true
1967 1967
         );
1968 1968
         wp_register_script(
1969 1969
             'ee-moment-core',
1970
-            EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js',
1970
+            EE_THIRD_PARTY_URL.'moment/moment-with-locales.min.js',
1971 1971
             array(),
1972 1972
             EVENT_ESPRESSO_VERSION,
1973 1973
             true
1974 1974
         );
1975 1975
         wp_register_script(
1976 1976
             'ee-moment',
1977
-            EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js',
1977
+            EE_THIRD_PARTY_URL.'moment/moment-timezone-with-data.min.js',
1978 1978
             array('ee-moment-core'),
1979 1979
             EVENT_ESPRESSO_VERSION,
1980 1980
             true
1981 1981
         );
1982 1982
         wp_register_script(
1983 1983
             'ee-datepicker',
1984
-            EE_ADMIN_URL . 'assets/ee-datepicker.js',
1984
+            EE_ADMIN_URL.'assets/ee-datepicker.js',
1985 1985
             array('jquery-ui-timepicker-addon', 'ee-moment'),
1986 1986
             EVENT_ESPRESSO_VERSION,
1987 1987
             true
@@ -2013,11 +2013,11 @@  discard block
 block discarded – undo
2013 2013
         /**
2014 2014
          * help tour stuff
2015 2015
          */
2016
-        if (! empty($this->_help_tour)) {
2016
+        if ( ! empty($this->_help_tour)) {
2017 2017
             // register the js for kicking things off
2018 2018
             wp_enqueue_script(
2019 2019
                 'ee-help-tour',
2020
-                EE_ADMIN_URL . 'assets/ee-help-tour.js',
2020
+                EE_ADMIN_URL.'assets/ee-help-tour.js',
2021 2021
                 array('jquery-joyride'),
2022 2022
                 EVENT_ESPRESSO_VERSION,
2023 2023
                 true
@@ -2117,12 +2117,12 @@  discard block
 block discarded – undo
2117 2117
     protected function _set_list_table()
2118 2118
     {
2119 2119
         // first is this a list_table view?
2120
-        if (! isset($this->_route_config['list_table'])) {
2120
+        if ( ! isset($this->_route_config['list_table'])) {
2121 2121
             return;
2122 2122
         } //not a list_table view so get out.
2123 2123
         // list table functions are per view specific (because some admin pages might have more than one list table!)
2124
-        $list_table_view = '_set_list_table_views_' . $this->_req_action;
2125
-        if (! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) {
2124
+        $list_table_view = '_set_list_table_views_'.$this->_req_action;
2125
+        if ( ! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) {
2126 2126
             // user error msg
2127 2127
             $error_msg = esc_html__(
2128 2128
                 'An error occurred. The requested list table views could not be found.',
@@ -2142,10 +2142,10 @@  discard block
 block discarded – undo
2142 2142
         }
2143 2143
         // let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally
2144 2144
         $this->_views = apply_filters(
2145
-            'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action,
2145
+            'FHEE_list_table_views_'.$this->page_slug.'_'.$this->_req_action,
2146 2146
             $this->_views
2147 2147
         );
2148
-        $this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views);
2148
+        $this->_views = apply_filters('FHEE_list_table_views_'.$this->page_slug, $this->_views);
2149 2149
         $this->_views = apply_filters('FHEE_list_table_views', $this->_views);
2150 2150
         $this->_set_list_table_view();
2151 2151
         $this->_set_list_table_object();
@@ -2161,7 +2161,7 @@  discard block
 block discarded – undo
2161 2161
     {
2162 2162
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2163 2163
         // looking at active items or dumpster diving ?
2164
-        if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2164
+        if ( ! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2165 2165
             $this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all';
2166 2166
         } else {
2167 2167
             $this->_view = sanitize_key($this->_req_data['status']);
@@ -2182,7 +2182,7 @@  discard block
 block discarded – undo
2182 2182
     protected function _set_list_table_object()
2183 2183
     {
2184 2184
         if (isset($this->_route_config['list_table'])) {
2185
-            if (! class_exists($this->_route_config['list_table'])) {
2185
+            if ( ! class_exists($this->_route_config['list_table'])) {
2186 2186
                 throw new EE_Error(
2187 2187
                     sprintf(
2188 2188
                         esc_html__(
@@ -2220,17 +2220,17 @@  discard block
 block discarded – undo
2220 2220
         foreach ($this->_views as $key => $view) {
2221 2221
             $query_args = array();
2222 2222
             // check for current view
2223
-            $this->_views[ $key ]['class'] = $this->_view === $view['slug'] ? 'current' : '';
2223
+            $this->_views[$key]['class'] = $this->_view === $view['slug'] ? 'current' : '';
2224 2224
             $query_args['action'] = $this->_req_action;
2225
-            $query_args[ $this->_req_action . '_nonce' ] = wp_create_nonce($query_args['action'] . '_nonce');
2225
+            $query_args[$this->_req_action.'_nonce'] = wp_create_nonce($query_args['action'].'_nonce');
2226 2226
             $query_args['status'] = $view['slug'];
2227 2227
             // merge any other arguments sent in.
2228
-            if (isset($extra_query_args[ $view['slug'] ])) {
2229
-                foreach ($extra_query_args[ $view['slug'] ] as $extra_query_arg) {
2228
+            if (isset($extra_query_args[$view['slug']])) {
2229
+                foreach ($extra_query_args[$view['slug']] as $extra_query_arg) {
2230 2230
                     $query_args[] = $extra_query_arg;
2231 2231
                 }
2232 2232
             }
2233
-            $this->_views[ $key ]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2233
+            $this->_views[$key]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2234 2234
         }
2235 2235
         return $this->_views;
2236 2236
     }
@@ -2249,7 +2249,7 @@  discard block
 block discarded – undo
2249 2249
     {
2250 2250
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2251 2251
         $values = array(10, 25, 50, 100);
2252
-        $per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2252
+        $per_page = ( ! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2253 2253
         if ($max_entries) {
2254 2254
             $values[] = $max_entries;
2255 2255
             sort($values);
@@ -2261,14 +2261,14 @@  discard block
 block discarded – undo
2261 2261
 					<select id="entries-per-page-slct" name="entries-per-page-slct">';
2262 2262
         foreach ($values as $value) {
2263 2263
             if ($value < $max_entries) {
2264
-                $selected = $value === $per_page ? ' selected="' . $per_page . '"' : '';
2264
+                $selected = $value === $per_page ? ' selected="'.$per_page.'"' : '';
2265 2265
                 $entries_per_page_dropdown .= '
2266
-						<option value="' . $value . '"' . $selected . '>' . $value . '&nbsp;&nbsp;</option>';
2266
+						<option value="' . $value.'"'.$selected.'>'.$value.'&nbsp;&nbsp;</option>';
2267 2267
             }
2268 2268
         }
2269
-        $selected = $max_entries === $per_page ? ' selected="' . $per_page . '"' : '';
2269
+        $selected = $max_entries === $per_page ? ' selected="'.$per_page.'"' : '';
2270 2270
         $entries_per_page_dropdown .= '
2271
-						<option value="' . $max_entries . '"' . $selected . '>All&nbsp;&nbsp;</option>';
2271
+						<option value="' . $max_entries.'"'.$selected.'>All&nbsp;&nbsp;</option>';
2272 2272
         $entries_per_page_dropdown .= '
2273 2273
 					</select>
2274 2274
 					entries
@@ -2292,7 +2292,7 @@  discard block
 block discarded – undo
2292 2292
             empty($this->_search_btn_label) ? $this->page_label
2293 2293
                 : $this->_search_btn_label
2294 2294
         );
2295
-        $this->_template_args['search']['callback'] = 'search_' . $this->page_slug;
2295
+        $this->_template_args['search']['callback'] = 'search_'.$this->page_slug;
2296 2296
     }
2297 2297
 
2298 2298
 
@@ -2378,7 +2378,7 @@  discard block
 block discarded – undo
2378 2378
             $total_columns = ! empty($screen_columns)
2379 2379
                 ? $screen_columns
2380 2380
                 : $this->_route_config['columns'][1];
2381
-            $this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns;
2381
+            $this->_template_args['current_screen_widget_class'] = 'columns-'.$total_columns;
2382 2382
             $this->_template_args['current_page'] = $this->_wp_page_slug;
2383 2383
             $this->_template_args['screen'] = $this->_current_screen;
2384 2384
             $this->_column_template_path = EE_ADMIN_TEMPLATE
@@ -2423,7 +2423,7 @@  discard block
 block discarded – undo
2423 2423
      */
2424 2424
     protected function _espresso_ratings_request()
2425 2425
     {
2426
-        if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2426
+        if ( ! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2427 2427
             return;
2428 2428
         }
2429 2429
         $ratings_box_title = apply_filters(
@@ -2450,7 +2450,7 @@  discard block
 block discarded – undo
2450 2450
      */
2451 2451
     public function espresso_ratings_request()
2452 2452
     {
2453
-        EEH_Template::display_template(EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php');
2453
+        EEH_Template::display_template(EE_ADMIN_TEMPLATE.'espresso_ratings_request_content.template.php');
2454 2454
     }
2455 2455
 
2456 2456
 
@@ -2461,17 +2461,17 @@  discard block
 block discarded – undo
2461 2461
                    . '</p><p class="hide-if-js">'
2462 2462
                    . esc_html__('This widget requires JavaScript.', 'event_espresso')
2463 2463
                    . '</p>';
2464
-        $pre = '<div class="espresso-rss-display">' . "\n\t";
2465
-        $pre .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>';
2466
-        $post = '</div>' . "\n";
2467
-        $cache_key = 'ee_rss_' . md5($rss_id);
2464
+        $pre = '<div class="espresso-rss-display">'."\n\t";
2465
+        $pre .= '<span id="'.$rss_id.'_url" class="hidden">'.$url.'</span>';
2466
+        $post = '</div>'."\n";
2467
+        $cache_key = 'ee_rss_'.md5($rss_id);
2468 2468
         $output = get_transient($cache_key);
2469 2469
         if ($output !== false) {
2470
-            echo $pre . $output . $post;
2470
+            echo $pre.$output.$post;
2471 2471
             return true;
2472 2472
         }
2473
-        if (! (defined('DOING_AJAX') && DOING_AJAX)) {
2474
-            echo $pre . $loading . $post;
2473
+        if ( ! (defined('DOING_AJAX') && DOING_AJAX)) {
2474
+            echo $pre.$loading.$post;
2475 2475
             return false;
2476 2476
         }
2477 2477
         ob_start();
@@ -2538,19 +2538,19 @@  discard block
 block discarded – undo
2538 2538
     public function espresso_sponsors_post_box()
2539 2539
     {
2540 2540
         EEH_Template::display_template(
2541
-            EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php'
2541
+            EE_ADMIN_TEMPLATE.'admin_general_metabox_contents_espresso_sponsors.template.php'
2542 2542
         );
2543 2543
     }
2544 2544
 
2545 2545
 
2546 2546
     private function _publish_post_box()
2547 2547
     {
2548
-        $meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview';
2548
+        $meta_box_ref = 'espresso_'.$this->page_slug.'_editor_overview';
2549 2549
         // if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array
2550 2550
         // then we'll use that for the metabox label.
2551 2551
         // Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes)
2552
-        if (! empty($this->_labels['publishbox'])) {
2553
-            $box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][ $this->_req_action ]
2552
+        if ( ! empty($this->_labels['publishbox'])) {
2553
+            $box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][$this->_req_action]
2554 2554
                 : $this->_labels['publishbox'];
2555 2555
         } else {
2556 2556
             $box_label = esc_html__('Publish', 'event_espresso');
@@ -2579,7 +2579,7 @@  discard block
 block discarded – undo
2579 2579
             ? $this->_template_args['publish_box_extra_content']
2580 2580
             : '';
2581 2581
         echo EEH_Template::display_template(
2582
-            EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php',
2582
+            EE_ADMIN_TEMPLATE.'admin_details_publish_metabox.template.php',
2583 2583
             $this->_template_args,
2584 2584
             true
2585 2585
         );
@@ -2669,8 +2669,8 @@  discard block
 block discarded – undo
2669 2669
             );
2670 2670
         }
2671 2671
         $this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : '';
2672
-        if (! empty($name) && ! empty($id)) {
2673
-            $hidden_field_arr[ $name ] = array(
2672
+        if ( ! empty($name) && ! empty($id)) {
2673
+            $hidden_field_arr[$name] = array(
2674 2674
                 'type'  => 'hidden',
2675 2675
                 'value' => $id,
2676 2676
             );
@@ -2680,7 +2680,7 @@  discard block
 block discarded – undo
2680 2680
         }
2681 2681
         // add hidden field
2682 2682
         $this->_template_args['publish_hidden_fields'] = is_array($hf) && ! empty($name)
2683
-            ? $hf[ $name ]['field']
2683
+            ? $hf[$name]['field']
2684 2684
             : $hf;
2685 2685
     }
2686 2686
 
@@ -2782,7 +2782,7 @@  discard block
 block discarded – undo
2782 2782
         }
2783 2783
         // if $create_func is true (default) then we automatically create the function for displaying the actual meta box.  If false then we take the $callback reference passed through and use it instead (so callers can define their own callback function/method if they wish)
2784 2784
         $call_back_func = $create_func
2785
-            ? static function ($post, $metabox) {
2785
+            ? static function($post, $metabox) {
2786 2786
                 do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2787 2787
                 echo EEH_Template::display_template(
2788 2788
                     $metabox['args']['template_path'],
@@ -2792,7 +2792,7 @@  discard block
 block discarded – undo
2792 2792
             }
2793 2793
             : $callback;
2794 2794
         add_meta_box(
2795
-            str_replace('_', '-', $action) . '-mbox',
2795
+            str_replace('_', '-', $action).'-mbox',
2796 2796
             $title,
2797 2797
             $call_back_func,
2798 2798
             $this->_wp_page_slug,
@@ -2899,9 +2899,9 @@  discard block
 block discarded – undo
2899 2899
             : 'espresso-default-admin';
2900 2900
         $template_path = $sidebar
2901 2901
             ? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php'
2902
-            : EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php';
2902
+            : EE_ADMIN_TEMPLATE.'admin_details_wrapper_no_sidebar.template.php';
2903 2903
         if (defined('DOING_AJAX') && DOING_AJAX) {
2904
-            $template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php';
2904
+            $template_path = EE_ADMIN_TEMPLATE.'admin_details_wrapper_no_sidebar_ajax.template.php';
2905 2905
         }
2906 2906
         $template_path = ! empty($this->_column_template_path)
2907 2907
             ? $this->_column_template_path : $template_path;
@@ -2966,7 +2966,7 @@  discard block
 block discarded – undo
2966 2966
             )
2967 2967
             : $this->_template_args['preview_action_button'];
2968 2968
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2969
-            EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php',
2969
+            EE_ADMIN_TEMPLATE.'admin_caf_full_page_preview.template.php',
2970 2970
             $this->_template_args,
2971 2971
             true
2972 2972
         );
@@ -3024,7 +3024,7 @@  discard block
 block discarded – undo
3024 3024
         // setup search attributes
3025 3025
         $this->_set_search_attributes();
3026 3026
         $this->_template_args['current_page'] = $this->_wp_page_slug;
3027
-        $template_path = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php';
3027
+        $template_path = EE_ADMIN_TEMPLATE.'admin_list_wrapper.template.php';
3028 3028
         $this->_template_args['table_url'] = defined('DOING_AJAX')
3029 3029
             ? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url)
3030 3030
             : add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url);
@@ -3032,10 +3032,10 @@  discard block
 block discarded – undo
3032 3032
         $this->_template_args['current_route'] = $this->_req_action;
3033 3033
         $this->_template_args['list_table_class'] = get_class($this->_list_table_object);
3034 3034
         $ajax_sorting_callback = $this->_list_table_object->get_ajax_sorting_callback();
3035
-        if (! empty($ajax_sorting_callback)) {
3035
+        if ( ! empty($ajax_sorting_callback)) {
3036 3036
             $sortable_list_table_form_fields = wp_nonce_field(
3037
-                $ajax_sorting_callback . '_nonce',
3038
-                $ajax_sorting_callback . '_nonce',
3037
+                $ajax_sorting_callback.'_nonce',
3038
+                $ajax_sorting_callback.'_nonce',
3039 3039
                 false,
3040 3040
                 false
3041 3041
             );
@@ -3052,7 +3052,7 @@  discard block
 block discarded – undo
3052 3052
         $hidden_form_fields = isset($this->_template_args['list_table_hidden_fields'])
3053 3053
             ? $this->_template_args['list_table_hidden_fields']
3054 3054
             : '';
3055
-        $nonce_ref = $this->_req_action . '_nonce';
3055
+        $nonce_ref = $this->_req_action.'_nonce';
3056 3056
         $hidden_form_fields .= '<input type="hidden" name="'
3057 3057
                                . $nonce_ref
3058 3058
                                . '" value="'
@@ -3061,10 +3061,10 @@  discard block
 block discarded – undo
3061 3061
         $this->_template_args['list_table_hidden_fields'] = $hidden_form_fields;
3062 3062
         // display message about search results?
3063 3063
         $this->_template_args['before_list_table'] .= ! empty($this->_req_data['s'])
3064
-            ? '<p class="ee-search-results">' . sprintf(
3064
+            ? '<p class="ee-search-results">'.sprintf(
3065 3065
                 esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'),
3066 3066
                 trim($this->_req_data['s'], '%')
3067
-            ) . '</p>'
3067
+            ).'</p>'
3068 3068
             : '';
3069 3069
         // filter before_list_table template arg
3070 3070
         $this->_template_args['before_list_table'] = apply_filters(
@@ -3145,12 +3145,12 @@  discard block
 block discarded – undo
3145 3145
             $this
3146 3146
         );
3147 3147
         $this->_template_args['status_change_notice'] = EEH_Template::display_template(
3148
-            EE_ADMIN_TEMPLATE . 'status_change_notice.template.php',
3149
-            [ 'context' => '__admin-legend' ],
3148
+            EE_ADMIN_TEMPLATE.'status_change_notice.template.php',
3149
+            ['context' => '__admin-legend'],
3150 3150
             true
3151 3151
         );
3152 3152
         return EEH_Template::display_template(
3153
-            EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php',
3153
+            EE_ADMIN_TEMPLATE.'admin_details_legend.template.php',
3154 3154
             $this->_template_args,
3155 3155
             true
3156 3156
         );
@@ -3381,17 +3381,17 @@  discard block
 block discarded – undo
3381 3381
         // add in a hidden index for the current page (so save and close redirects properly)
3382 3382
         $this->_template_args['save_buttons'] = $referrer_url;
3383 3383
         foreach ($button_text as $key => $button) {
3384
-            $ref = $default_names[ $key ];
3384
+            $ref = $default_names[$key];
3385 3385
             $this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary '
3386 3386
                                                      . $ref
3387 3387
                                                      . '" value="'
3388 3388
                                                      . $button
3389 3389
                                                      . '" name="'
3390
-                                                     . (! empty($actions) ? $actions[ $key ] : $ref)
3390
+                                                     . ( ! empty($actions) ? $actions[$key] : $ref)
3391 3391
                                                      . '" id="'
3392
-                                                     . $this->_current_view . '_' . $ref
3392
+                                                     . $this->_current_view.'_'.$ref
3393 3393
                                                      . '" />';
3394
-            if (! $both) {
3394
+            if ( ! $both) {
3395 3395
                 break;
3396 3396
             }
3397 3397
         }
@@ -3426,13 +3426,13 @@  discard block
 block discarded – undo
3426 3426
                 'An error occurred. No action was set for this page\'s form.',
3427 3427
                 'event_espresso'
3428 3428
             );
3429
-            $dev_msg = $user_msg . "\n"
3429
+            $dev_msg = $user_msg."\n"
3430 3430
                        . sprintf(
3431 3431
                            esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'),
3432 3432
                            __FUNCTION__,
3433 3433
                            EE_Admin_Page::class
3434 3434
                        );
3435
-            EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
3435
+            EE_Error::add_error($user_msg.'||'.$dev_msg, __FILE__, __FUNCTION__, __LINE__);
3436 3436
         }
3437 3437
         // open form
3438 3438
         $this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="'
@@ -3441,8 +3441,8 @@  discard block
 block discarded – undo
3441 3441
                                                              . $route
3442 3442
                                                              . '_event_form" >';
3443 3443
         // add nonce
3444
-        $nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false);
3445
-        $this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce;
3444
+        $nonce = wp_nonce_field($route.'_nonce', $route.'_nonce', false, false);
3445
+        $this->_template_args['before_admin_page_content'] .= "\n\t".$nonce;
3446 3446
         // add REQUIRED form action
3447 3447
         $hidden_fields = array(
3448 3448
             'action' => array('type' => 'hidden', 'value' => $route),
@@ -3455,7 +3455,7 @@  discard block
 block discarded – undo
3455 3455
         $form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array');
3456 3456
         // add fields to form
3457 3457
         foreach ((array) $form_fields as $field_name => $form_field) {
3458
-            $this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field'];
3458
+            $this->_template_args['before_admin_page_content'] .= "\n\t".$form_field['field'];
3459 3459
         }
3460 3460
         // close form
3461 3461
         $this->_template_args['after_admin_page_content'] = '</form>';
@@ -3509,12 +3509,12 @@  discard block
 block discarded – undo
3509 3509
         foreach ($this->_req_data as $ref => $value) {
3510 3510
             // unset nonces
3511 3511
             if (strpos($ref, 'nonce') !== false) {
3512
-                unset($this->_req_data[ $ref ]);
3512
+                unset($this->_req_data[$ref]);
3513 3513
                 continue;
3514 3514
             }
3515 3515
             // urlencode values.
3516 3516
             $value = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
3517
-            $this->_req_data[ $ref ] = $value;
3517
+            $this->_req_data[$ref] = $value;
3518 3518
         }
3519 3519
         return array_merge($this->_req_data, $new_route_data);
3520 3520
     }
@@ -3552,10 +3552,10 @@  discard block
 block discarded – undo
3552 3552
         $redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url;
3553 3553
         $notices = EE_Error::get_notices(false);
3554 3554
         // overwrite default success messages //BUT ONLY if overwrite not overridden
3555
-        if (! $override_overwrite || ! empty($notices['errors'])) {
3555
+        if ( ! $override_overwrite || ! empty($notices['errors'])) {
3556 3556
             EE_Error::overwrite_success();
3557 3557
         }
3558
-        if (! empty($what) && ! empty($action_desc) && empty($notices['errors'])) {
3558
+        if ( ! empty($what) && ! empty($action_desc) && empty($notices['errors'])) {
3559 3559
             // how many records affected ? more than one record ? or just one ?
3560 3560
             if ($success > 1) {
3561 3561
                 // set plural msg
@@ -3584,7 +3584,7 @@  discard block
 block discarded – undo
3584 3584
             }
3585 3585
         }
3586 3586
         // check that $query_args isn't something crazy
3587
-        if (! is_array($query_args)) {
3587
+        if ( ! is_array($query_args)) {
3588 3588
             $query_args = array();
3589 3589
         }
3590 3590
         /**
@@ -3609,7 +3609,7 @@  discard block
 block discarded – undo
3609 3609
             $redirect_url = admin_url('admin.php');
3610 3610
         }
3611 3611
         // merge any default query_args set in _default_route_query_args property
3612
-        if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3612
+        if ( ! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3613 3613
             $args_to_merge = array();
3614 3614
             foreach ($this->_default_route_query_args as $query_param => $query_value) {
3615 3615
                 // is there a wp_referer array in our _default_route_query_args property?
@@ -3621,15 +3621,15 @@  discard block
 block discarded – undo
3621 3621
                         }
3622 3622
                         // finally we will override any arguments in the referer with
3623 3623
                         // what might be set on the _default_route_query_args array.
3624
-                        if (isset($this->_default_route_query_args[ $reference ])) {
3625
-                            $args_to_merge[ $reference ] = urlencode($this->_default_route_query_args[ $reference ]);
3624
+                        if (isset($this->_default_route_query_args[$reference])) {
3625
+                            $args_to_merge[$reference] = urlencode($this->_default_route_query_args[$reference]);
3626 3626
                         } else {
3627
-                            $args_to_merge[ $reference ] = urlencode($value);
3627
+                            $args_to_merge[$reference] = urlencode($value);
3628 3628
                         }
3629 3629
                     }
3630 3630
                     continue;
3631 3631
                 }
3632
-                $args_to_merge[ $query_param ] = $query_value;
3632
+                $args_to_merge[$query_param] = $query_value;
3633 3633
             }
3634 3634
             // now let's merge these arguments but override with what was specifically sent in to the
3635 3635
             // redirect.
@@ -3641,13 +3641,13 @@  discard block
 block discarded – undo
3641 3641
         if (isset($query_args['action'])) {
3642 3642
             // manually generate wp_nonce and merge that with the query vars
3643 3643
             // becuz the wp_nonce_url function wrecks havoc on some vars
3644
-            $query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce');
3644
+            $query_args['_wpnonce'] = wp_create_nonce($query_args['action'].'_nonce');
3645 3645
         }
3646 3646
         // we're adding some hooks and filters in here for processing any things just before redirects
3647 3647
         // (example: an admin page has done an insert or update and we want to run something after that).
3648
-        do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args);
3648
+        do_action('AHEE_redirect_'.$classname.$this->_req_action, $query_args);
3649 3649
         $redirect_url = apply_filters(
3650
-            'FHEE_redirect_' . $classname . $this->_req_action,
3650
+            'FHEE_redirect_'.$classname.$this->_req_action,
3651 3651
             EE_Admin_Page::add_query_args_and_nonce($query_args, $redirect_url),
3652 3652
             $query_args
3653 3653
         );
@@ -3703,7 +3703,7 @@  discard block
 block discarded – undo
3703 3703
         }
3704 3704
         $this->_template_args['notices'] = EE_Error::get_notices();
3705 3705
         // IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true)
3706
-        if (! defined('DOING_AJAX') || $sticky_notices) {
3706
+        if ( ! defined('DOING_AJAX') || $sticky_notices) {
3707 3707
             $route = isset($query_args['action']) ? $query_args['action'] : 'default';
3708 3708
             $this->_add_transient(
3709 3709
                 $route,
@@ -3743,7 +3743,7 @@  discard block
 block discarded – undo
3743 3743
         $exclude_nonce = false
3744 3744
     ) {
3745 3745
         // first let's validate the action (if $base_url is FALSE otherwise validation will happen further along)
3746
-        if (empty($base_url) && ! isset($this->_page_routes[ $action ])) {
3746
+        if (empty($base_url) && ! isset($this->_page_routes[$action])) {
3747 3747
             throw new EE_Error(
3748 3748
                 sprintf(
3749 3749
                     esc_html__(
@@ -3754,7 +3754,7 @@  discard block
 block discarded – undo
3754 3754
                 )
3755 3755
             );
3756 3756
         }
3757
-        if (! isset($this->_labels['buttons'][ $type ])) {
3757
+        if ( ! isset($this->_labels['buttons'][$type])) {
3758 3758
             throw new EE_Error(
3759 3759
                 sprintf(
3760 3760
                     __(
@@ -3767,7 +3767,7 @@  discard block
 block discarded – undo
3767 3767
         }
3768 3768
         // finally check user access for this button.
3769 3769
         $has_access = $this->check_user_access($action, true);
3770
-        if (! $has_access) {
3770
+        if ( ! $has_access) {
3771 3771
             return '';
3772 3772
         }
3773 3773
         $_base_url = ! $base_url ? $this->_admin_base_url : $base_url;
@@ -3775,11 +3775,11 @@  discard block
 block discarded – undo
3775 3775
             'action' => $action,
3776 3776
         );
3777 3777
         // merge extra_request args but make sure our original action takes precedence and doesn't get overwritten.
3778
-        if (! empty($extra_request)) {
3778
+        if ( ! empty($extra_request)) {
3779 3779
             $query_args = array_merge($extra_request, $query_args);
3780 3780
         }
3781 3781
         $url = EE_Admin_Page::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce);
3782
-        return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][ $type ], $class);
3782
+        return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][$type], $class);
3783 3783
     }
3784 3784
 
3785 3785
 
@@ -3805,7 +3805,7 @@  discard block
 block discarded – undo
3805 3805
                 'FHEE__EE_Admin_Page___per_page_screen_options__default',
3806 3806
                 20
3807 3807
             ),
3808
-            'option'  => $this->_current_page . '_' . $this->_current_view . '_per_page',
3808
+            'option'  => $this->_current_page.'_'.$this->_current_view.'_per_page',
3809 3809
         );
3810 3810
         // ONLY add the screen option if the user has access to it.
3811 3811
         if ($this->check_user_access($this->_current_view, true)) {
@@ -3826,7 +3826,7 @@  discard block
 block discarded – undo
3826 3826
     {
3827 3827
         if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) {
3828 3828
             check_admin_referer('screen-options-nonce', 'screenoptionnonce');
3829
-            if (! $user = wp_get_current_user()) {
3829
+            if ( ! $user = wp_get_current_user()) {
3830 3830
                 return;
3831 3831
             }
3832 3832
             $option = $_POST['wp_screen_options']['option'];
@@ -3837,7 +3837,7 @@  discard block
 block discarded – undo
3837 3837
             $map_option = $option;
3838 3838
             $option = str_replace('-', '_', $option);
3839 3839
             switch ($map_option) {
3840
-                case $this->_current_page . '_' . $this->_current_view . '_per_page':
3840
+                case $this->_current_page.'_'.$this->_current_view.'_per_page':
3841 3841
                     $value = (int) $value;
3842 3842
                     $max_value = apply_filters(
3843 3843
                         'FHEE__EE_Admin_Page___set_per_page_screen_options__max_value',
@@ -3895,13 +3895,13 @@  discard block
 block discarded – undo
3895 3895
     protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false)
3896 3896
     {
3897 3897
         $user_id = get_current_user_id();
3898
-        if (! $skip_route_verify) {
3898
+        if ( ! $skip_route_verify) {
3899 3899
             $this->_verify_route($route);
3900 3900
         }
3901 3901
         // now let's set the string for what kind of transient we're setting
3902 3902
         $transient = $notices
3903
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3904
-            : 'rte_tx_' . $route . '_' . $user_id;
3903
+            ? 'ee_rte_n_tx_'.$route.'_'.$user_id
3904
+            : 'rte_tx_'.$route.'_'.$user_id;
3905 3905
         $data = $notices ? array('notices' => $data) : $data;
3906 3906
         // is there already a transient for this route?  If there is then let's ADD to that transient
3907 3907
         $existing = is_multisite() && is_network_admin()
@@ -3930,8 +3930,8 @@  discard block
 block discarded – undo
3930 3930
         $user_id = get_current_user_id();
3931 3931
         $route = ! $route ? $this->_req_action : $route;
3932 3932
         $transient = $notices
3933
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3934
-            : 'rte_tx_' . $route . '_' . $user_id;
3933
+            ? 'ee_rte_n_tx_'.$route.'_'.$user_id
3934
+            : 'rte_tx_'.$route.'_'.$user_id;
3935 3935
         $data = is_multisite() && is_network_admin()
3936 3936
             ? get_site_transient($transient)
3937 3937
             : get_transient($transient);
@@ -4155,7 +4155,7 @@  discard block
 block discarded – undo
4155 4155
      */
4156 4156
     protected function _next_link($url, $class = 'dashicons dashicons-arrow-right')
4157 4157
     {
4158
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4158
+        return '<a class="'.$class.'" href="'.$url.'"></a>';
4159 4159
     }
4160 4160
 
4161 4161
 
@@ -4168,7 +4168,7 @@  discard block
 block discarded – undo
4168 4168
      */
4169 4169
     protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left')
4170 4170
     {
4171
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4171
+        return '<a class="'.$class.'" href="'.$url.'"></a>';
4172 4172
     }
4173 4173
 
4174 4174
 
Please login to merge, or discard this patch.
core/admin/templates/admin_details_legend.template.php 2 patches
Indentation   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -9,7 +9,7 @@  discard block
 block discarded – undo
9 9
 
10 10
 <?php
11 11
 if (isset($status_change_notice)) {
12
-    echo $status_change_notice;
12
+	echo $status_change_notice;
13 13
 }
14 14
 ?>
15 15
 
@@ -17,18 +17,18 @@  discard block
 block discarded – undo
17 17
     <dl class="alignleft ee-list-table-legend">
18 18
         <?php foreach ($items as $item => $details) : ?>
19 19
         <?php
20
-        if ($per_col < $count) : ?>
20
+		if ($per_col < $count) : ?>
21 21
     </dl>
22 22
     <dl class="alignleft ee-list-table-legend">
23 23
         <?php $count = 1;
24
-        endif; ?>
24
+		endif; ?>
25 25
         <dt id="ee-legend-item-<?php echo $item; ?>">
26 26
             <?php $class = ! empty($details['class']) ? $details['class'] : 'ee-legend-img-container'; ?>
27 27
             <span class="ee-legend-item-wrap">
28 28
             <?php
29
-            if (strpos($details['class'], '<span') !== false) {
30
-                echo $class;
31
-            } else { ?>
29
+			if (strpos($details['class'], '<span') !== false) {
30
+				echo $class;
31
+			} else { ?>
32 32
                 <span class="<?php echo $class; ?>">
33 33
                     <?php if (! empty($details['icon'])) : ?>
34 34
                         <img src="<?php echo $details['icon']; ?>" class="ee-legend-icon"
@@ -40,7 +40,7 @@  discard block
 block discarded – undo
40 40
             <span class="ee-legend-description"><?php echo $details['desc']; ?></span>
41 41
         </dt>
42 42
         <?php $count++;
43
-        endforeach; ?>
43
+		endforeach; ?>
44 44
     </dl>
45 45
     <div style="clear:both"></div>
46 46
 </div>
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -30,7 +30,7 @@
 block discarded – undo
30 30
                 echo $class;
31 31
             } else { ?>
32 32
                 <span class="<?php echo $class; ?>">
33
-                    <?php if (! empty($details['icon'])) : ?>
33
+                    <?php if ( ! empty($details['icon'])) : ?>
34 34
                         <img src="<?php echo $details['icon']; ?>" class="ee-legend-icon"
35 35
                              alt="<?php echo esc_attr($details['desc']); ?>"/>
36 36
                     <?php endif; ?>
Please login to merge, or discard this patch.
core/domain/services/assets/EspressoLegacyAdminAssetManager.php 2 patches
Indentation   +117 added lines, -117 removed lines patch added patch discarded remove patch
@@ -15,121 +15,121 @@
 block discarded – undo
15 15
 class EspressoLegacyAdminAssetManager extends AssetManager
16 16
 {
17 17
 
18
-    const JS_HANDLE_INJECT_WP = 'ee-inject-wp';
19
-
20
-    const JS_HANDLE_JQUERY_COOKIE = 'jquery-cookie';
21
-
22
-    const JS_HANDLE_JOYRIDE_MODERNIZR = 'joyride-modernizr';
23
-
24
-    const JS_HANDLE_JQUERY_JOYRIDE = 'jquery-joyride';
25
-
26
-    const CSS_HANDLE_EE_JOYRIDE = 'ee-joyride-css';
27
-
28
-    const CSS_HANDLE_JOYRIDE = 'joyride-css';
29
-
30
-
31
-    /**
32
-     * @inheritDoc
33
-     */
34
-    public function addAssets()
35
-    {
36
-        $joyride = filter_var(apply_filters('FHEE_load_joyride', false), FILTER_VALIDATE_BOOLEAN);
37
-        $this->registerJavascript($joyride);
38
-        $this->registerStyleSheets($joyride);
39
-    }
40
-
41
-
42
-    /**
43
-     * Register javascript assets
44
-     *
45
-     * @param bool $joyride
46
-     */
47
-    private function registerJavascript($joyride = false)
48
-    {
49
-        // this javascript is loaded on every admin page to catch any injections ee needs to add to wp run js.
50
-        // Note: the intention of this script is to only do TARGETED injections.
51
-        //ie: only injecting on certain script calls.
52
-        $this->addJavascript(
53
-            EspressoLegacyAdminAssetManager::JS_HANDLE_INJECT_WP,
54
-            EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js',
55
-            ['jquery'],
56
-            true,
57
-            EVENT_ESPRESSO_VERSION
58
-        );
59
-        // register cookie script for future dependencies
60
-        $this->addJavascript(
61
-            EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_COOKIE,
62
-            EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js',
63
-            ['jquery'],
64
-            true,
65
-            '2.1'
66
-        );
67
-        $this->loadQtipJs();
68
-        // joyride is turned OFF by default, but prior to the admin_enqueue_scripts hook,
69
-        // can be turned back on again via: add_filter('FHEE_load_joyride', '__return_true' );
70
-        if (! $joyride) {
71
-            return;
72
-        }
73
-        $this->addJavascript(
74
-            EspressoLegacyAdminAssetManager::JS_HANDLE_JOYRIDE_MODERNIZR,
75
-            EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js',
76
-            [],
77
-            true,
78
-            '2.1'
79
-        );
80
-        // wanna go for a joyride?
81
-        $this->addJavascript(
82
-            EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_JOYRIDE,
83
-            EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js',
84
-            [
85
-                EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_COOKIE,
86
-                EspressoLegacyAdminAssetManager::JS_HANDLE_JOYRIDE_MODERNIZR
87
-            ],
88
-            '2.1',
89
-            true
90
-        )->enqueueAsset();
91
-    }
92
-
93
-
94
-    /**
95
-     * Register CSS assets.
96
-     *
97
-     * @param bool $joyride
98
-     */
99
-    private function registerStyleSheets($joyride = false)
100
-    {
101
-        if (! $joyride) {
102
-            return;
103
-        }       // joyride style
104
-        $this->addStylesheet(
105
-            EspressoLegacyAdminAssetManager::CSS_HANDLE_JOYRIDE,
106
-            EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css',
107
-            [],
108
-            'all',
109
-            '2.1'
110
-        );
111
-        $this->addStylesheet(
112
-            EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_JOYRIDE,
113
-            EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css',
114
-            ['joyride-css'],
115
-            'all',
116
-            EVENT_ESPRESSO_VERSION
117
-        )->enqueueAsset();
118
-    }
119
-
120
-
121
-    /**
122
-     * registers assets for cleaning your ears
123
-     */
124
-    public function loadQtipJs()
125
-    {
126
-        // qtip is turned OFF by default, but prior to the wp_enqueue_scripts hook,
127
-        // can be turned back on again via: add_filter('FHEE_load_qtip', '__return_true' );
128
-        if (apply_filters('FHEE_load_qtip', false)) {
129
-            $qtip_loader = EEH_Qtip_Loader::instance();
130
-            if ($qtip_loader instanceof EEH_Qtip_Loader) {
131
-                $qtip_loader->register_and_enqueue();
132
-            }
133
-        }
134
-    }
18
+	const JS_HANDLE_INJECT_WP = 'ee-inject-wp';
19
+
20
+	const JS_HANDLE_JQUERY_COOKIE = 'jquery-cookie';
21
+
22
+	const JS_HANDLE_JOYRIDE_MODERNIZR = 'joyride-modernizr';
23
+
24
+	const JS_HANDLE_JQUERY_JOYRIDE = 'jquery-joyride';
25
+
26
+	const CSS_HANDLE_EE_JOYRIDE = 'ee-joyride-css';
27
+
28
+	const CSS_HANDLE_JOYRIDE = 'joyride-css';
29
+
30
+
31
+	/**
32
+	 * @inheritDoc
33
+	 */
34
+	public function addAssets()
35
+	{
36
+		$joyride = filter_var(apply_filters('FHEE_load_joyride', false), FILTER_VALIDATE_BOOLEAN);
37
+		$this->registerJavascript($joyride);
38
+		$this->registerStyleSheets($joyride);
39
+	}
40
+
41
+
42
+	/**
43
+	 * Register javascript assets
44
+	 *
45
+	 * @param bool $joyride
46
+	 */
47
+	private function registerJavascript($joyride = false)
48
+	{
49
+		// this javascript is loaded on every admin page to catch any injections ee needs to add to wp run js.
50
+		// Note: the intention of this script is to only do TARGETED injections.
51
+		//ie: only injecting on certain script calls.
52
+		$this->addJavascript(
53
+			EspressoLegacyAdminAssetManager::JS_HANDLE_INJECT_WP,
54
+			EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js',
55
+			['jquery'],
56
+			true,
57
+			EVENT_ESPRESSO_VERSION
58
+		);
59
+		// register cookie script for future dependencies
60
+		$this->addJavascript(
61
+			EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_COOKIE,
62
+			EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js',
63
+			['jquery'],
64
+			true,
65
+			'2.1'
66
+		);
67
+		$this->loadQtipJs();
68
+		// joyride is turned OFF by default, but prior to the admin_enqueue_scripts hook,
69
+		// can be turned back on again via: add_filter('FHEE_load_joyride', '__return_true' );
70
+		if (! $joyride) {
71
+			return;
72
+		}
73
+		$this->addJavascript(
74
+			EspressoLegacyAdminAssetManager::JS_HANDLE_JOYRIDE_MODERNIZR,
75
+			EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js',
76
+			[],
77
+			true,
78
+			'2.1'
79
+		);
80
+		// wanna go for a joyride?
81
+		$this->addJavascript(
82
+			EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_JOYRIDE,
83
+			EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js',
84
+			[
85
+				EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_COOKIE,
86
+				EspressoLegacyAdminAssetManager::JS_HANDLE_JOYRIDE_MODERNIZR
87
+			],
88
+			'2.1',
89
+			true
90
+		)->enqueueAsset();
91
+	}
92
+
93
+
94
+	/**
95
+	 * Register CSS assets.
96
+	 *
97
+	 * @param bool $joyride
98
+	 */
99
+	private function registerStyleSheets($joyride = false)
100
+	{
101
+		if (! $joyride) {
102
+			return;
103
+		}       // joyride style
104
+		$this->addStylesheet(
105
+			EspressoLegacyAdminAssetManager::CSS_HANDLE_JOYRIDE,
106
+			EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css',
107
+			[],
108
+			'all',
109
+			'2.1'
110
+		);
111
+		$this->addStylesheet(
112
+			EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_JOYRIDE,
113
+			EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css',
114
+			['joyride-css'],
115
+			'all',
116
+			EVENT_ESPRESSO_VERSION
117
+		)->enqueueAsset();
118
+	}
119
+
120
+
121
+	/**
122
+	 * registers assets for cleaning your ears
123
+	 */
124
+	public function loadQtipJs()
125
+	{
126
+		// qtip is turned OFF by default, but prior to the wp_enqueue_scripts hook,
127
+		// can be turned back on again via: add_filter('FHEE_load_qtip', '__return_true' );
128
+		if (apply_filters('FHEE_load_qtip', false)) {
129
+			$qtip_loader = EEH_Qtip_Loader::instance();
130
+			if ($qtip_loader instanceof EEH_Qtip_Loader) {
131
+				$qtip_loader->register_and_enqueue();
132
+			}
133
+		}
134
+	}
135 135
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -51,7 +51,7 @@  discard block
 block discarded – undo
51 51
         //ie: only injecting on certain script calls.
52 52
         $this->addJavascript(
53 53
             EspressoLegacyAdminAssetManager::JS_HANDLE_INJECT_WP,
54
-            EE_ADMIN_URL . 'assets/ee-cpt-wp-injects.js',
54
+            EE_ADMIN_URL.'assets/ee-cpt-wp-injects.js',
55 55
             ['jquery'],
56 56
             true,
57 57
             EVENT_ESPRESSO_VERSION
@@ -59,7 +59,7 @@  discard block
 block discarded – undo
59 59
         // register cookie script for future dependencies
60 60
         $this->addJavascript(
61 61
             EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_COOKIE,
62
-            EE_THIRD_PARTY_URL . 'joyride/jquery.cookie.js',
62
+            EE_THIRD_PARTY_URL.'joyride/jquery.cookie.js',
63 63
             ['jquery'],
64 64
             true,
65 65
             '2.1'
@@ -67,12 +67,12 @@  discard block
 block discarded – undo
67 67
         $this->loadQtipJs();
68 68
         // joyride is turned OFF by default, but prior to the admin_enqueue_scripts hook,
69 69
         // can be turned back on again via: add_filter('FHEE_load_joyride', '__return_true' );
70
-        if (! $joyride) {
70
+        if ( ! $joyride) {
71 71
             return;
72 72
         }
73 73
         $this->addJavascript(
74 74
             EspressoLegacyAdminAssetManager::JS_HANDLE_JOYRIDE_MODERNIZR,
75
-            EE_THIRD_PARTY_URL . 'joyride/modernizr.mq.js',
75
+            EE_THIRD_PARTY_URL.'joyride/modernizr.mq.js',
76 76
             [],
77 77
             true,
78 78
             '2.1'
@@ -80,7 +80,7 @@  discard block
 block discarded – undo
80 80
         // wanna go for a joyride?
81 81
         $this->addJavascript(
82 82
             EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_JOYRIDE,
83
-            EE_THIRD_PARTY_URL . 'joyride/jquery.joyride-2.1.js',
83
+            EE_THIRD_PARTY_URL.'joyride/jquery.joyride-2.1.js',
84 84
             [
85 85
                 EspressoLegacyAdminAssetManager::JS_HANDLE_JQUERY_COOKIE,
86 86
                 EspressoLegacyAdminAssetManager::JS_HANDLE_JOYRIDE_MODERNIZR
@@ -98,19 +98,19 @@  discard block
 block discarded – undo
98 98
      */
99 99
     private function registerStyleSheets($joyride = false)
100 100
     {
101
-        if (! $joyride) {
101
+        if ( ! $joyride) {
102 102
             return;
103 103
         }       // joyride style
104 104
         $this->addStylesheet(
105 105
             EspressoLegacyAdminAssetManager::CSS_HANDLE_JOYRIDE,
106
-            EE_THIRD_PARTY_URL . 'joyride/joyride-2.1.css',
106
+            EE_THIRD_PARTY_URL.'joyride/joyride-2.1.css',
107 107
             [],
108 108
             'all',
109 109
             '2.1'
110 110
         );
111 111
         $this->addStylesheet(
112 112
             EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_JOYRIDE,
113
-            EE_GLOBAL_ASSETS_URL . 'css/ee-joyride-styles.css',
113
+            EE_GLOBAL_ASSETS_URL.'css/ee-joyride-styles.css',
114 114
             ['joyride-css'],
115 115
             'all',
116 116
             EVENT_ESPRESSO_VERSION
Please login to merge, or discard this patch.
core/domain/services/assets/CoreAssetManager.php 1 patch
Indentation   +254 added lines, -254 removed lines patch added patch discarded remove patch
@@ -30,258 +30,258 @@
 block discarded – undo
30 30
 class CoreAssetManager extends AssetManager
31 31
 {
32 32
 
33
-    // WordPress core / Third party JS asset handles
34
-    const JS_HANDLE_JQUERY = 'jquery';
35
-
36
-    const JS_HANDLE_JQUERY_VALIDATE = 'jquery-validate';
37
-
38
-    const JS_HANDLE_JQUERY_VALIDATE_EXTRA = 'jquery-validate-extra-methods';
39
-
40
-    const JS_HANDLE_JS_CORE = 'eejs-core';
41
-
42
-    const JS_HANDLE_CORE = 'espresso_core';
43
-
44
-    const JS_HANDLE_I18N = 'eei18n';
45
-
46
-    const JS_HANDLE_VENDOR = 'eventespresso-vendor';
47
-
48
-    // EE CSS assets handles
49
-    const CSS_HANDLE_DEFAULT = 'espresso_default';
50
-
51
-    const CSS_HANDLE_CUSTOM = 'espresso_custom_css';
52
-
53
-    /**
54
-     * @var EE_Currency_Config $currency_config
55
-     */
56
-    protected $currency_config;
57
-
58
-    /**
59
-     * @var EE_Template_Config $template_config
60
-     */
61
-    protected $template_config;
62
-
63
-
64
-    /**
65
-     * CoreAssetRegister constructor.
66
-     *
67
-     * @param AssetCollection    $assets
68
-     * @param EE_Currency_Config $currency_config
69
-     * @param EE_Template_Config $template_config
70
-     * @param DomainInterface    $domain
71
-     * @param Registry           $registry
72
-     */
73
-    public function __construct(
74
-        AssetCollection $assets,
75
-        EE_Currency_Config $currency_config,
76
-        EE_Template_Config $template_config,
77
-        DomainInterface $domain,
78
-        Registry $registry
79
-    ) {
80
-        $this->currency_config = $currency_config;
81
-        $this->template_config = $template_config;
82
-        parent::__construct($domain, $assets, $registry);
83
-    }
84
-
85
-
86
-    /**
87
-     * @since 4.9.62.p
88
-     * @throws DomainException
89
-     * @throws DuplicateCollectionIdentifierException
90
-     * @throws InvalidArgumentException
91
-     * @throws InvalidDataTypeException
92
-     * @throws InvalidEntityException
93
-     * @throws InvalidInterfaceException
94
-     */
95
-    public function addAssets()
96
-    {
97
-        $this->addJavascriptFiles();
98
-        $this->addStylesheetFiles();
99
-    }
100
-
101
-
102
-    /**
103
-     * @since 4.9.62.p
104
-     * @throws DomainException
105
-     * @throws DuplicateCollectionIdentifierException
106
-     * @throws InvalidArgumentException
107
-     * @throws InvalidDataTypeException
108
-     * @throws InvalidEntityException
109
-     * @throws InvalidInterfaceException
110
-     */
111
-    public function addJavascriptFiles()
112
-    {
113
-        $this->loadCoreJs();
114
-        $this->loadJqueryValidate();
115
-    }
116
-
117
-
118
-    /**
119
-     * @throws DuplicateCollectionIdentifierException
120
-     * @throws InvalidDataTypeException
121
-     * @throws InvalidEntityException
122
-     * @throws DomainException
123
-     * @since 4.9.62.p
124
-     */
125
-    public function addStylesheetFiles()
126
-    {
127
-        $this->loadCoreCss();
128
-    }
129
-
130
-
131
-    /**
132
-     * core default javascript
133
-     *
134
-     * @since 4.9.62.p
135
-     * @throws DomainException
136
-     * @throws DuplicateCollectionIdentifierException
137
-     * @throws InvalidArgumentException
138
-     * @throws InvalidDataTypeException
139
-     * @throws InvalidEntityException
140
-     * @throws InvalidInterfaceException
141
-     */
142
-    private function loadCoreJs()
143
-    {
144
-        $this->addJs(CoreAssetManager::JS_HANDLE_VENDOR);
145
-        $this->addJs(CoreAssetManager::JS_HANDLE_JS_CORE)->setHasInlineData();
146
-        // todo verify that the following data is no longer being used anywhere and remove
147
-        $this->registry->addData('eejs_api_nonce', wp_create_nonce('wp_rest'));
148
-        $this->registry->addData(
149
-            'paths',
150
-            array(
151
-                'base_rest_route' => rest_url(),
152
-                'rest_route' => rest_url('ee/v4.8.36/'),
153
-                'collection_endpoints' => EED_Core_Rest_Api::getCollectionRoutesIndexedByModelName(),
154
-                'primary_keys' => EED_Core_Rest_Api::getPrimaryKeyNamesIndexedByModelName(),
155
-                'site_url' => site_url('/'),
156
-                'admin_url' => admin_url('/'),
157
-            )
158
-        );
159
-        // Event Espresso brand name
160
-        $this->registry->addData('brandName', Domain::brandName());
161
-        /** site formatting values **/
162
-        $this->registry->addData(
163
-            'site_formats',
164
-            array(
165
-                'date_formats' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats()
166
-            )
167
-        );
168
-        /** currency data **/
169
-        $this->registry->addData(
170
-            'currency_config',
171
-            $this->getCurrencySettings()
172
-        );
173
-        /** site timezone */
174
-        $this->registry->addData(
175
-            'default_timezone',
176
-            array(
177
-                'pretty' => EEH_DTT_Helper::get_timezone_string_for_display(),
178
-                'string' => get_option('timezone_string'),
179
-                'offset' => EEH_DTT_Helper::get_site_timezone_gmt_offset(),
180
-            )
181
-        );
182
-        /** site locale (user locale if user logged in) */
183
-        $this->registry->addData(
184
-            'locale',
185
-            array(
186
-                'user' => get_user_locale(),
187
-                'site' => get_locale()
188
-            )
189
-        );
190
-
191
-        $this->addJavascript(
192
-            CoreAssetManager::JS_HANDLE_CORE,
193
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
194
-            array(CoreAssetManager::JS_HANDLE_JQUERY)
195
-        );
196
-    }
197
-
198
-
199
-
200
-    /**
201
-     * Returns configuration data for the js Currency VO.
202
-     * @since 4.9.71.p
203
-     * @return array
204
-     */
205
-    private function getCurrencySettings()
206
-    {
207
-        return array(
208
-            'code' => $this->currency_config->code,
209
-            'singularLabel' => $this->currency_config->name,
210
-            'pluralLabel' => $this->currency_config->plural,
211
-            'sign' => $this->currency_config->sign,
212
-            'signB4' => $this->currency_config->sign_b4,
213
-            'decimalPlaces' => $this->currency_config->dec_plc,
214
-            'decimalMark' => $this->currency_config->dec_mrk,
215
-            'thousandsSeparator' => $this->currency_config->thsnds,
216
-        );
217
-    }
218
-
219
-
220
-    /**
221
-     * @throws DuplicateCollectionIdentifierException
222
-     * @throws InvalidDataTypeException
223
-     * @throws InvalidEntityException
224
-     * @throws DomainException
225
-     * @since 4.9.62.p
226
-     */
227
-    private function loadCoreCss()
228
-    {
229
-        if ($this->template_config->enable_default_style && ! is_admin()) {
230
-            $this->addStylesheet(
231
-                CoreAssetManager::CSS_HANDLE_DEFAULT,
232
-                is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css')
233
-                    ? EVENT_ESPRESSO_UPLOAD_URL . 'css/espresso_default.css'
234
-                    : EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
235
-                array('dashicons')
236
-            );
237
-            //Load custom style sheet if available
238
-            if ($this->template_config->custom_style_sheet !== null) {
239
-                $this->addStylesheet(
240
-                    CoreAssetManager::CSS_HANDLE_CUSTOM,
241
-                    EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
242
-                    array(CoreAssetManager::CSS_HANDLE_DEFAULT)
243
-                );
244
-            }
245
-        }
246
-    }
247
-
248
-
249
-    /**
250
-     * jQuery Validate for form validation
251
-     *
252
-     * @since 4.9.62.p
253
-     * @throws DomainException
254
-     * @throws DuplicateCollectionIdentifierException
255
-     * @throws InvalidDataTypeException
256
-     * @throws InvalidEntityException
257
-     */
258
-    private function loadJqueryValidate()
259
-    {
260
-        $this->addJavascript(
261
-            CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE,
262
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
263
-            array(CoreAssetManager::JS_HANDLE_JQUERY),
264
-            true,
265
-            '1.15.0'
266
-        );
267
-
268
-        $this->addJavascript(
269
-            CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE_EXTRA,
270
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
271
-            array(CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE),
272
-            true,
273
-            '1.15.0'
274
-        );
275
-    }
276
-
277
-
278
-    /**
279
-     * @param JavascriptAsset $script
280
-     * @deprecated $VID:$
281
-     */
282
-    public function loadQtipJs(JavascriptAsset $script)
283
-    {
284
-        // replacement:
285
-        // EventEspresso\core\domain\services\assets\EspressoLegacyAdminAssetManager::loadQtipJs()
286
-    }
33
+	// WordPress core / Third party JS asset handles
34
+	const JS_HANDLE_JQUERY = 'jquery';
35
+
36
+	const JS_HANDLE_JQUERY_VALIDATE = 'jquery-validate';
37
+
38
+	const JS_HANDLE_JQUERY_VALIDATE_EXTRA = 'jquery-validate-extra-methods';
39
+
40
+	const JS_HANDLE_JS_CORE = 'eejs-core';
41
+
42
+	const JS_HANDLE_CORE = 'espresso_core';
43
+
44
+	const JS_HANDLE_I18N = 'eei18n';
45
+
46
+	const JS_HANDLE_VENDOR = 'eventespresso-vendor';
47
+
48
+	// EE CSS assets handles
49
+	const CSS_HANDLE_DEFAULT = 'espresso_default';
50
+
51
+	const CSS_HANDLE_CUSTOM = 'espresso_custom_css';
52
+
53
+	/**
54
+	 * @var EE_Currency_Config $currency_config
55
+	 */
56
+	protected $currency_config;
57
+
58
+	/**
59
+	 * @var EE_Template_Config $template_config
60
+	 */
61
+	protected $template_config;
62
+
63
+
64
+	/**
65
+	 * CoreAssetRegister constructor.
66
+	 *
67
+	 * @param AssetCollection    $assets
68
+	 * @param EE_Currency_Config $currency_config
69
+	 * @param EE_Template_Config $template_config
70
+	 * @param DomainInterface    $domain
71
+	 * @param Registry           $registry
72
+	 */
73
+	public function __construct(
74
+		AssetCollection $assets,
75
+		EE_Currency_Config $currency_config,
76
+		EE_Template_Config $template_config,
77
+		DomainInterface $domain,
78
+		Registry $registry
79
+	) {
80
+		$this->currency_config = $currency_config;
81
+		$this->template_config = $template_config;
82
+		parent::__construct($domain, $assets, $registry);
83
+	}
84
+
85
+
86
+	/**
87
+	 * @since 4.9.62.p
88
+	 * @throws DomainException
89
+	 * @throws DuplicateCollectionIdentifierException
90
+	 * @throws InvalidArgumentException
91
+	 * @throws InvalidDataTypeException
92
+	 * @throws InvalidEntityException
93
+	 * @throws InvalidInterfaceException
94
+	 */
95
+	public function addAssets()
96
+	{
97
+		$this->addJavascriptFiles();
98
+		$this->addStylesheetFiles();
99
+	}
100
+
101
+
102
+	/**
103
+	 * @since 4.9.62.p
104
+	 * @throws DomainException
105
+	 * @throws DuplicateCollectionIdentifierException
106
+	 * @throws InvalidArgumentException
107
+	 * @throws InvalidDataTypeException
108
+	 * @throws InvalidEntityException
109
+	 * @throws InvalidInterfaceException
110
+	 */
111
+	public function addJavascriptFiles()
112
+	{
113
+		$this->loadCoreJs();
114
+		$this->loadJqueryValidate();
115
+	}
116
+
117
+
118
+	/**
119
+	 * @throws DuplicateCollectionIdentifierException
120
+	 * @throws InvalidDataTypeException
121
+	 * @throws InvalidEntityException
122
+	 * @throws DomainException
123
+	 * @since 4.9.62.p
124
+	 */
125
+	public function addStylesheetFiles()
126
+	{
127
+		$this->loadCoreCss();
128
+	}
129
+
130
+
131
+	/**
132
+	 * core default javascript
133
+	 *
134
+	 * @since 4.9.62.p
135
+	 * @throws DomainException
136
+	 * @throws DuplicateCollectionIdentifierException
137
+	 * @throws InvalidArgumentException
138
+	 * @throws InvalidDataTypeException
139
+	 * @throws InvalidEntityException
140
+	 * @throws InvalidInterfaceException
141
+	 */
142
+	private function loadCoreJs()
143
+	{
144
+		$this->addJs(CoreAssetManager::JS_HANDLE_VENDOR);
145
+		$this->addJs(CoreAssetManager::JS_HANDLE_JS_CORE)->setHasInlineData();
146
+		// todo verify that the following data is no longer being used anywhere and remove
147
+		$this->registry->addData('eejs_api_nonce', wp_create_nonce('wp_rest'));
148
+		$this->registry->addData(
149
+			'paths',
150
+			array(
151
+				'base_rest_route' => rest_url(),
152
+				'rest_route' => rest_url('ee/v4.8.36/'),
153
+				'collection_endpoints' => EED_Core_Rest_Api::getCollectionRoutesIndexedByModelName(),
154
+				'primary_keys' => EED_Core_Rest_Api::getPrimaryKeyNamesIndexedByModelName(),
155
+				'site_url' => site_url('/'),
156
+				'admin_url' => admin_url('/'),
157
+			)
158
+		);
159
+		// Event Espresso brand name
160
+		$this->registry->addData('brandName', Domain::brandName());
161
+		/** site formatting values **/
162
+		$this->registry->addData(
163
+			'site_formats',
164
+			array(
165
+				'date_formats' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats()
166
+			)
167
+		);
168
+		/** currency data **/
169
+		$this->registry->addData(
170
+			'currency_config',
171
+			$this->getCurrencySettings()
172
+		);
173
+		/** site timezone */
174
+		$this->registry->addData(
175
+			'default_timezone',
176
+			array(
177
+				'pretty' => EEH_DTT_Helper::get_timezone_string_for_display(),
178
+				'string' => get_option('timezone_string'),
179
+				'offset' => EEH_DTT_Helper::get_site_timezone_gmt_offset(),
180
+			)
181
+		);
182
+		/** site locale (user locale if user logged in) */
183
+		$this->registry->addData(
184
+			'locale',
185
+			array(
186
+				'user' => get_user_locale(),
187
+				'site' => get_locale()
188
+			)
189
+		);
190
+
191
+		$this->addJavascript(
192
+			CoreAssetManager::JS_HANDLE_CORE,
193
+			EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
194
+			array(CoreAssetManager::JS_HANDLE_JQUERY)
195
+		);
196
+	}
197
+
198
+
199
+
200
+	/**
201
+	 * Returns configuration data for the js Currency VO.
202
+	 * @since 4.9.71.p
203
+	 * @return array
204
+	 */
205
+	private function getCurrencySettings()
206
+	{
207
+		return array(
208
+			'code' => $this->currency_config->code,
209
+			'singularLabel' => $this->currency_config->name,
210
+			'pluralLabel' => $this->currency_config->plural,
211
+			'sign' => $this->currency_config->sign,
212
+			'signB4' => $this->currency_config->sign_b4,
213
+			'decimalPlaces' => $this->currency_config->dec_plc,
214
+			'decimalMark' => $this->currency_config->dec_mrk,
215
+			'thousandsSeparator' => $this->currency_config->thsnds,
216
+		);
217
+	}
218
+
219
+
220
+	/**
221
+	 * @throws DuplicateCollectionIdentifierException
222
+	 * @throws InvalidDataTypeException
223
+	 * @throws InvalidEntityException
224
+	 * @throws DomainException
225
+	 * @since 4.9.62.p
226
+	 */
227
+	private function loadCoreCss()
228
+	{
229
+		if ($this->template_config->enable_default_style && ! is_admin()) {
230
+			$this->addStylesheet(
231
+				CoreAssetManager::CSS_HANDLE_DEFAULT,
232
+				is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css')
233
+					? EVENT_ESPRESSO_UPLOAD_URL . 'css/espresso_default.css'
234
+					: EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
235
+				array('dashicons')
236
+			);
237
+			//Load custom style sheet if available
238
+			if ($this->template_config->custom_style_sheet !== null) {
239
+				$this->addStylesheet(
240
+					CoreAssetManager::CSS_HANDLE_CUSTOM,
241
+					EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
242
+					array(CoreAssetManager::CSS_HANDLE_DEFAULT)
243
+				);
244
+			}
245
+		}
246
+	}
247
+
248
+
249
+	/**
250
+	 * jQuery Validate for form validation
251
+	 *
252
+	 * @since 4.9.62.p
253
+	 * @throws DomainException
254
+	 * @throws DuplicateCollectionIdentifierException
255
+	 * @throws InvalidDataTypeException
256
+	 * @throws InvalidEntityException
257
+	 */
258
+	private function loadJqueryValidate()
259
+	{
260
+		$this->addJavascript(
261
+			CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE,
262
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
263
+			array(CoreAssetManager::JS_HANDLE_JQUERY),
264
+			true,
265
+			'1.15.0'
266
+		);
267
+
268
+		$this->addJavascript(
269
+			CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE_EXTRA,
270
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
271
+			array(CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE),
272
+			true,
273
+			'1.15.0'
274
+		);
275
+	}
276
+
277
+
278
+	/**
279
+	 * @param JavascriptAsset $script
280
+	 * @deprecated $VID:$
281
+	 */
282
+	public function loadQtipJs(JavascriptAsset $script)
283
+	{
284
+		// replacement:
285
+		// EventEspresso\core\domain\services\assets\EspressoLegacyAdminAssetManager::loadQtipJs()
286
+	}
287 287
 }
Please login to merge, or discard this patch.
admin_pages/messages/Messages_Admin_Page.core.php 2 patches
Indentation   +4537 added lines, -4537 removed lines patch added patch discarded remove patch
@@ -19,2638 +19,2638 @@  discard block
 block discarded – undo
19 19
 class Messages_Admin_Page extends EE_Admin_Page
20 20
 {
21 21
 
22
-    /**
23
-     * @type EE_Message_Resource_Manager $_message_resource_manager
24
-     */
25
-    protected $_message_resource_manager;
26
-
27
-    /**
28
-     * @type string $_active_message_type_name
29
-     */
30
-    protected $_active_message_type_name = '';
31
-
32
-    /**
33
-     * @type EE_messenger $_active_messenger
34
-     */
35
-    protected $_active_messenger;
36
-    protected $_activate_state;
37
-    protected $_activate_meta_box_type;
38
-    protected $_current_message_meta_box;
39
-    protected $_current_message_meta_box_object;
40
-    protected $_context_switcher;
41
-    protected $_shortcodes = array();
42
-    protected $_active_messengers = array();
43
-    protected $_active_message_types = array();
44
-
45
-    /**
46
-     * @var EE_Message_Template_Group $_message_template_group
47
-     */
48
-    protected $_message_template_group;
49
-    protected $_m_mt_settings = array();
50
-
51
-
52
-    /**
53
-     * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
54
-     * IF there is no group then it gets automatically set to the Default template pack.
55
-     *
56
-     * @since 4.5.0
57
-     *
58
-     * @var EE_Messages_Template_Pack
59
-     */
60
-    protected $_template_pack;
61
-
62
-
63
-    /**
64
-     * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
65
-     * group is.  If there is no group then it automatically gets set to default.
66
-     *
67
-     * @since 4.5.0
68
-     *
69
-     * @var string
70
-     */
71
-    protected $_variation;
72
-
73
-
74
-    /**
75
-     * @param bool $routing
76
-     * @throws EE_Error
77
-     */
78
-    public function __construct($routing = true)
79
-    {
80
-        // make sure messages autoloader is running
81
-        EED_Messages::set_autoloaders();
82
-        parent::__construct($routing);
83
-    }
84
-
85
-
86
-    protected function _init_page_props()
87
-    {
88
-        $this->page_slug = EE_MSG_PG_SLUG;
89
-        $this->page_label = esc_html__('Messages Settings', 'event_espresso');
90
-        $this->_admin_base_url = EE_MSG_ADMIN_URL;
91
-        $this->_admin_base_path = EE_MSG_ADMIN;
92
-
93
-        $this->_activate_state = isset($this->_req_data['activate_state']) ? (array) $this->_req_data['activate_state']
94
-            : array();
95
-
96
-        $this->_active_messenger = isset($this->_req_data['messenger']) ? $this->_req_data['messenger'] : null;
97
-        $this->_load_message_resource_manager();
98
-    }
99
-
100
-
101
-    /**
102
-     * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
103
-     *
104
-     * @throws EE_Error
105
-     * @throws InvalidDataTypeException
106
-     * @throws InvalidInterfaceException
107
-     * @throws InvalidArgumentException
108
-     * @throws ReflectionException
109
-     */
110
-    protected function _load_message_resource_manager()
111
-    {
112
-        $this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
113
-    }
114
-
115
-
116
-    /**
117
-     * @deprecated 4.9.9.rc.014
118
-     * @return array
119
-     * @throws EE_Error
120
-     * @throws InvalidArgumentException
121
-     * @throws InvalidDataTypeException
122
-     * @throws InvalidInterfaceException
123
-     */
124
-    public function get_messengers_for_list_table()
125
-    {
126
-        EE_Error::doing_it_wrong(
127
-            __METHOD__,
128
-            sprintf(
129
-                esc_html__(
130
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a messenger filter dropdown which is now generated differently via %s',
131
-                    'event_espresso'
132
-                ),
133
-                'Messages_Admin_Page::get_messengers_select_input()'
134
-            ),
135
-            '4.9.9.rc.014'
136
-        );
137
-
138
-        $m_values = array();
139
-        $active_messengers = EEM_Message::instance()->get_all(array('group_by' => 'MSG_messenger'));
140
-        // setup messengers for selects
141
-        $i = 1;
142
-        foreach ($active_messengers as $active_messenger) {
143
-            if ($active_messenger instanceof EE_Message) {
144
-                $m_values[ $i ]['id'] = $active_messenger->messenger();
145
-                $m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
146
-                $i++;
147
-            }
148
-        }
149
-
150
-        return $m_values;
151
-    }
152
-
153
-
154
-    /**
155
-     * @deprecated 4.9.9.rc.014
156
-     * @return array
157
-     * @throws EE_Error
158
-     * @throws InvalidArgumentException
159
-     * @throws InvalidDataTypeException
160
-     * @throws InvalidInterfaceException
161
-     */
162
-    public function get_message_types_for_list_table()
163
-    {
164
-        EE_Error::doing_it_wrong(
165
-            __METHOD__,
166
-            sprintf(
167
-                esc_html__(
168
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type filter dropdown which is now generated differently via %s',
169
-                    'event_espresso'
170
-                ),
171
-                'Messages_Admin_Page::get_message_types_select_input()'
172
-            ),
173
-            '4.9.9.rc.014'
174
-        );
175
-
176
-        $mt_values = array();
177
-        $active_messages = EEM_Message::instance()->get_all(array('group_by' => 'MSG_message_type'));
178
-        $i = 1;
179
-        foreach ($active_messages as $active_message) {
180
-            if ($active_message instanceof EE_Message) {
181
-                $mt_values[ $i ]['id'] = $active_message->message_type();
182
-                $mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
183
-                $i++;
184
-            }
185
-        }
186
-
187
-        return $mt_values;
188
-    }
189
-
190
-
191
-    /**
192
-     * @deprecated 4.9.9.rc.014
193
-     * @return array
194
-     * @throws EE_Error
195
-     * @throws InvalidArgumentException
196
-     * @throws InvalidDataTypeException
197
-     * @throws InvalidInterfaceException
198
-     */
199
-    public function get_contexts_for_message_types_for_list_table()
200
-    {
201
-        EE_Error::doing_it_wrong(
202
-            __METHOD__,
203
-            sprintf(
204
-                esc_html__(
205
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type context filter dropdown which is now generated differently via %s',
206
-                    'event_espresso'
207
-                ),
208
-                'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
209
-            ),
210
-            '4.9.9.rc.014'
211
-        );
212
-
213
-        $contexts = array();
214
-        $active_message_contexts = EEM_Message::instance()->get_all(array('group_by' => 'MSG_context'));
215
-        foreach ($active_message_contexts as $active_message) {
216
-            if ($active_message instanceof EE_Message) {
217
-                $message_type = $active_message->message_type_object();
218
-                if ($message_type instanceof EE_message_type) {
219
-                    $message_type_contexts = $message_type->get_contexts();
220
-                    foreach ($message_type_contexts as $context => $context_details) {
221
-                        $contexts[ $context ] = $context_details['label'];
222
-                    }
223
-                }
224
-            }
225
-        }
226
-
227
-        return $contexts;
228
-    }
229
-
230
-
231
-    /**
232
-     * Generate select input with provided messenger options array.
233
-     *
234
-     * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
235
-     *                                 labels.
236
-     * @return string
237
-     * @throws EE_Error
238
-     */
239
-    public function get_messengers_select_input($messenger_options)
240
-    {
241
-        // if empty or just one value then just return an empty string
242
-        if (empty($messenger_options)
243
-            || ! is_array($messenger_options)
244
-            || count($messenger_options) === 1
245
-        ) {
246
-            return '';
247
-        }
248
-        // merge in default
249
-        $messenger_options = array_merge(
250
-            array('none_selected' => esc_html__('Show All Messengers', 'event_espresso')),
251
-            $messenger_options
252
-        );
253
-        $input = new EE_Select_Input(
254
-            $messenger_options,
255
-            array(
256
-                'html_name'  => 'ee_messenger_filter_by',
257
-                'html_id'    => 'ee_messenger_filter_by',
258
-                'html_class' => 'wide',
259
-                'default'    => isset($this->_req_data['ee_messenger_filter_by'])
260
-                    ? sanitize_title($this->_req_data['ee_messenger_filter_by'])
261
-                    : 'none_selected',
262
-            )
263
-        );
264
-
265
-        return $input->get_html_for_input();
266
-    }
267
-
268
-
269
-    /**
270
-     * Generate select input with provided message type options array.
271
-     *
272
-     * @param array $message_type_options Array of message types indexed by message type slug, and values are the
273
-     *                                    message type labels
274
-     * @return string
275
-     * @throws EE_Error
276
-     */
277
-    public function get_message_types_select_input($message_type_options)
278
-    {
279
-        // if empty or count of options is 1 then just return an empty string
280
-        if (empty($message_type_options)
281
-            || ! is_array($message_type_options)
282
-            || count($message_type_options) === 1
283
-        ) {
284
-            return '';
285
-        }
286
-        // merge in default
287
-        $message_type_options = array_merge(
288
-            array('none_selected' => esc_html__('Show All Message Types', 'event_espresso')),
289
-            $message_type_options
290
-        );
291
-        $input = new EE_Select_Input(
292
-            $message_type_options,
293
-            array(
294
-                'html_name'  => 'ee_message_type_filter_by',
295
-                'html_id'    => 'ee_message_type_filter_by',
296
-                'html_class' => 'wide',
297
-                'default'    => isset($this->_req_data['ee_message_type_filter_by'])
298
-                    ? sanitize_title($this->_req_data['ee_message_type_filter_by'])
299
-                    : 'none_selected',
300
-            )
301
-        );
302
-
303
-        return $input->get_html_for_input();
304
-    }
305
-
306
-
307
-    /**
308
-     * Generate select input with provide message type contexts array.
309
-     *
310
-     * @param array $context_options Array of message type contexts indexed by context slug, and values are the
311
-     *                               context label.
312
-     * @return string
313
-     * @throws EE_Error
314
-     */
315
-    public function get_contexts_for_message_types_select_input($context_options)
316
-    {
317
-        // if empty or count of options is one then just return empty string
318
-        if (empty($context_options)
319
-            || ! is_array($context_options)
320
-            || count($context_options) === 1
321
-        ) {
322
-            return '';
323
-        }
324
-        // merge in default
325
-        $context_options = array_merge(
326
-            array('none_selected' => esc_html__('Show all Contexts', 'event_espresso')),
327
-            $context_options
328
-        );
329
-        $input = new EE_Select_Input(
330
-            $context_options,
331
-            array(
332
-                'html_name'  => 'ee_context_filter_by',
333
-                'html_id'    => 'ee_context_filter_by',
334
-                'html_class' => 'wide',
335
-                'default'    => isset($this->_req_data['ee_context_filter_by'])
336
-                    ? sanitize_title($this->_req_data['ee_context_filter_by'])
337
-                    : 'none_selected',
338
-            )
339
-        );
340
-
341
-        return $input->get_html_for_input();
342
-    }
343
-
344
-
345
-    protected function _ajax_hooks()
346
-    {
347
-        add_action('wp_ajax_activate_messenger', array($this, 'activate_messenger_toggle'));
348
-        add_action('wp_ajax_activate_mt', array($this, 'activate_mt_toggle'));
349
-        add_action('wp_ajax_ee_msgs_save_settings', array($this, 'save_settings'));
350
-        add_action('wp_ajax_ee_msgs_update_mt_form', array($this, 'update_mt_form'));
351
-        add_action('wp_ajax_switch_template_pack', array($this, 'switch_template_pack'));
352
-        add_action('wp_ajax_toggle_context_template', array($this, 'toggle_context_template'));
353
-    }
354
-
355
-
356
-    protected function _define_page_props()
357
-    {
358
-        $this->_admin_page_title = $this->page_label;
359
-        $this->_labels = array(
360
-            'buttons'    => array(
361
-                'add'    => esc_html__('Add New Message Template', 'event_espresso'),
362
-                'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
363
-                'delete' => esc_html__('Delete Message Template', 'event_espresso'),
364
-            ),
365
-            'publishbox' => esc_html__('Update Actions', 'event_espresso'),
366
-        );
367
-    }
368
-
369
-
370
-    /**
371
-     *        an array for storing key => value pairs of request actions and their corresponding methods
372
-     *
373
-     * @access protected
374
-     * @return void
375
-     */
376
-    protected function _set_page_routes()
377
-    {
378
-        $grp_id = ! empty($this->_req_data['GRP_ID']) && ! is_array($this->_req_data['GRP_ID'])
379
-            ? $this->_req_data['GRP_ID']
380
-            : 0;
381
-        $grp_id = empty($grp_id) && ! empty($this->_req_data['id'])
382
-            ? $this->_req_data['id']
383
-            : $grp_id;
384
-        $msg_id = ! empty($this->_req_data['MSG_ID']) && ! is_array($this->_req_data['MSG_ID'])
385
-            ? $this->_req_data['MSG_ID']
386
-            : 0;
387
-
388
-        $this->_page_routes = array(
389
-            'default'                          => array(
390
-                'func'       => '_message_queue_list_table',
391
-                'capability' => 'ee_read_global_messages',
392
-            ),
393
-            'global_mtps'                      => array(
394
-                'func'       => '_ee_default_messages_overview_list_table',
395
-                'capability' => 'ee_read_global_messages',
396
-            ),
397
-            'custom_mtps'                      => array(
398
-                'func'       => '_custom_mtps_preview',
399
-                'capability' => 'ee_read_messages',
400
-            ),
401
-            'add_new_message_template'         => array(
402
-                'func'       => '_add_message_template',
403
-                'capability' => 'ee_edit_messages',
404
-                'noheader'   => true,
405
-            ),
406
-            'edit_message_template'            => array(
407
-                'func'       => '_edit_message_template',
408
-                'capability' => 'ee_edit_message',
409
-                'obj_id'     => $grp_id,
410
-            ),
411
-            'preview_message'                  => array(
412
-                'func'               => '_preview_message',
413
-                'capability'         => 'ee_read_message',
414
-                'obj_id'             => $grp_id,
415
-                'noheader'           => true,
416
-                'headers_sent_route' => 'display_preview_message',
417
-            ),
418
-            'display_preview_message'          => array(
419
-                'func'       => '_display_preview_message',
420
-                'capability' => 'ee_read_message',
421
-                'obj_id'     => $grp_id,
422
-            ),
423
-            'insert_message_template'          => array(
424
-                'func'       => '_insert_or_update_message_template',
425
-                'capability' => 'ee_edit_messages',
426
-                'args'       => array('new_template' => true),
427
-                'noheader'   => true,
428
-            ),
429
-            'update_message_template'          => array(
430
-                'func'       => '_insert_or_update_message_template',
431
-                'capability' => 'ee_edit_message',
432
-                'obj_id'     => $grp_id,
433
-                'args'       => array('new_template' => false),
434
-                'noheader'   => true,
435
-            ),
436
-            'trash_message_template'           => array(
437
-                'func'       => '_trash_or_restore_message_template',
438
-                'capability' => 'ee_delete_message',
439
-                'obj_id'     => $grp_id,
440
-                'args'       => array('trash' => true, 'all' => true),
441
-                'noheader'   => true,
442
-            ),
443
-            'trash_message_template_context'   => array(
444
-                'func'       => '_trash_or_restore_message_template',
445
-                'capability' => 'ee_delete_message',
446
-                'obj_id'     => $grp_id,
447
-                'args'       => array('trash' => true),
448
-                'noheader'   => true,
449
-            ),
450
-            'restore_message_template'         => array(
451
-                'func'       => '_trash_or_restore_message_template',
452
-                'capability' => 'ee_delete_message',
453
-                'obj_id'     => $grp_id,
454
-                'args'       => array('trash' => false, 'all' => true),
455
-                'noheader'   => true,
456
-            ),
457
-            'restore_message_template_context' => array(
458
-                'func'       => '_trash_or_restore_message_template',
459
-                'capability' => 'ee_delete_message',
460
-                'obj_id'     => $grp_id,
461
-                'args'       => array('trash' => false),
462
-                'noheader'   => true,
463
-            ),
464
-            'delete_message_template'          => array(
465
-                'func'       => '_delete_message_template',
466
-                'capability' => 'ee_delete_message',
467
-                'obj_id'     => $grp_id,
468
-                'noheader'   => true,
469
-            ),
470
-            'reset_to_default'                 => array(
471
-                'func'       => '_reset_to_default_template',
472
-                'capability' => 'ee_edit_message',
473
-                'obj_id'     => $grp_id,
474
-                'noheader'   => true,
475
-            ),
476
-            'settings'                         => array(
477
-                'func'       => '_settings',
478
-                'capability' => 'manage_options',
479
-            ),
480
-            'update_global_settings'           => array(
481
-                'func'       => '_update_global_settings',
482
-                'capability' => 'manage_options',
483
-                'noheader'   => true,
484
-            ),
485
-            'generate_now'                     => array(
486
-                'func'       => '_generate_now',
487
-                'capability' => 'ee_send_message',
488
-                'noheader'   => true,
489
-            ),
490
-            'generate_and_send_now'            => array(
491
-                'func'       => '_generate_and_send_now',
492
-                'capability' => 'ee_send_message',
493
-                'noheader'   => true,
494
-            ),
495
-            'queue_for_resending'              => array(
496
-                'func'       => '_queue_for_resending',
497
-                'capability' => 'ee_send_message',
498
-                'noheader'   => true,
499
-            ),
500
-            'send_now'                         => array(
501
-                'func'       => '_send_now',
502
-                'capability' => 'ee_send_message',
503
-                'noheader'   => true,
504
-            ),
505
-            'delete_ee_message'                => array(
506
-                'func'       => '_delete_ee_messages',
507
-                'capability' => 'ee_delete_messages',
508
-                'noheader'   => true,
509
-            ),
510
-            'delete_ee_messages'               => array(
511
-                'func'       => '_delete_ee_messages',
512
-                'capability' => 'ee_delete_messages',
513
-                'noheader'   => true,
514
-                'obj_id'     => $msg_id,
515
-            ),
516
-        );
517
-    }
518
-
519
-
520
-    protected function _set_page_config()
521
-    {
522
-        $this->_page_config = array(
523
-            'default'                  => array(
524
-                'nav'           => array(
525
-                    'label' => esc_html__('Message Activity', 'event_espresso'),
526
-                    'order' => 10,
527
-                ),
528
-                'list_table'    => 'EE_Message_List_Table',
529
-                // 'qtips' => array( 'EE_Message_List_Table_Tips' ),
530
-                'require_nonce' => false,
531
-            ),
532
-            'global_mtps'              => array(
533
-                'nav'           => array(
534
-                    'label' => esc_html__('Default Message Templates', 'event_espresso'),
535
-                    'order' => 20,
536
-                ),
537
-                'list_table'    => 'Messages_Template_List_Table',
538
-                'help_tabs'     => array(
539
-                    'messages_overview_help_tab'                                => array(
540
-                        'title'    => esc_html__('Messages Overview', 'event_espresso'),
541
-                        'filename' => 'messages_overview',
542
-                    ),
543
-                    'messages_overview_messages_table_column_headings_help_tab' => array(
544
-                        'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
545
-                        'filename' => 'messages_overview_table_column_headings',
546
-                    ),
547
-                    'messages_overview_messages_filters_help_tab'               => array(
548
-                        'title'    => esc_html__('Message Filters', 'event_espresso'),
549
-                        'filename' => 'messages_overview_filters',
550
-                    ),
551
-                    'messages_overview_messages_views_help_tab'                 => array(
552
-                        'title'    => esc_html__('Message Views', 'event_espresso'),
553
-                        'filename' => 'messages_overview_views',
554
-                    ),
555
-                    'message_overview_message_types_help_tab'                   => array(
556
-                        'title'    => esc_html__('Message Types', 'event_espresso'),
557
-                        'filename' => 'messages_overview_types',
558
-                    ),
559
-                    'messages_overview_messengers_help_tab'                     => array(
560
-                        'title'    => esc_html__('Messengers', 'event_espresso'),
561
-                        'filename' => 'messages_overview_messengers',
562
-                    ),
563
-                ),
564
-                'help_tour'     => array('Messages_Overview_Help_Tour'),
565
-                'require_nonce' => false,
566
-            ),
567
-            'custom_mtps'              => array(
568
-                'nav'           => array(
569
-                    'label' => esc_html__('Custom Message Templates', 'event_espresso'),
570
-                    'order' => 30,
571
-                ),
572
-                'help_tabs'     => array(),
573
-                'help_tour'     => array(),
574
-                'require_nonce' => false,
575
-            ),
576
-            'add_new_message_template' => array(
577
-                'nav'           => array(
578
-                    'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
579
-                    'order'      => 5,
580
-                    'persistent' => false,
581
-                ),
582
-                'require_nonce' => false,
583
-            ),
584
-            'edit_message_template'    => array(
585
-                'labels'        => array(
586
-                    'buttons'    => array(
587
-                        'reset' => esc_html__('Reset Templates', 'event_espresso'),
588
-                    ),
589
-                    'publishbox' => esc_html__('Update Actions', 'event_espresso'),
590
-                ),
591
-                'nav'           => array(
592
-                    'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
593
-                    'order'      => 5,
594
-                    'persistent' => false,
595
-                    'url'        => '',
596
-                ),
597
-                'metaboxes'     => array('_publish_post_box', '_register_edit_meta_boxes'),
598
-                'has_metaboxes' => true,
599
-                'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
600
-                'help_tabs'     => array(
601
-                    'edit_message_template'            => array(
602
-                        'title'    => esc_html__('Message Template Editor', 'event_espresso'),
603
-                        'callback' => 'edit_message_template_help_tab',
604
-                    ),
605
-                    'message_templates_help_tab'       => array(
606
-                        'title'    => esc_html__('Message Templates', 'event_espresso'),
607
-                        'filename' => 'messages_templates',
608
-                    ),
609
-                    'message_template_shortcodes'      => array(
610
-                        'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
611
-                        'callback' => 'message_template_shortcodes_help_tab',
612
-                    ),
613
-                    'message_preview_help_tab'         => array(
614
-                        'title'    => esc_html__('Message Preview', 'event_espresso'),
615
-                        'filename' => 'messages_preview',
616
-                    ),
617
-                    'messages_overview_other_help_tab' => array(
618
-                        'title'    => esc_html__('Messages Other', 'event_espresso'),
619
-                        'filename' => 'messages_overview_other',
620
-                    ),
621
-                ),
622
-                'require_nonce' => false,
623
-            ),
624
-            'display_preview_message'  => array(
625
-                'nav'           => array(
626
-                    'label'      => esc_html__('Message Preview', 'event_espresso'),
627
-                    'order'      => 5,
628
-                    'url'        => '',
629
-                    'persistent' => false,
630
-                ),
631
-                'help_tabs'     => array(
632
-                    'preview_message' => array(
633
-                        'title'    => esc_html__('About Previews', 'event_espresso'),
634
-                        'callback' => 'preview_message_help_tab',
635
-                    ),
636
-                ),
637
-                'require_nonce' => false,
638
-            ),
639
-            'settings'                 => array(
640
-                'nav'           => array(
641
-                    'label' => esc_html__('Settings', 'event_espresso'),
642
-                    'order' => 40,
643
-                ),
644
-                'metaboxes'     => array('_messages_settings_metaboxes'),
645
-                'help_tabs'     => array(
646
-                    'messages_settings_help_tab'               => array(
647
-                        'title'    => esc_html__('Messages Settings', 'event_espresso'),
648
-                        'filename' => 'messages_settings',
649
-                    ),
650
-                    'messages_settings_message_types_help_tab' => array(
651
-                        'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
652
-                        'filename' => 'messages_settings_message_types',
653
-                    ),
654
-                    'messages_settings_messengers_help_tab'    => array(
655
-                        'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
656
-                        'filename' => 'messages_settings_messengers',
657
-                    ),
658
-                ),
659
-                'help_tour'     => array('Messages_Settings_Help_Tour'),
660
-                'require_nonce' => false,
661
-            ),
662
-        );
663
-    }
664
-
665
-
666
-    protected function _add_screen_options()
667
-    {
668
-        // todo
669
-    }
670
-
671
-
672
-    protected function _add_screen_options_global_mtps()
673
-    {
674
-        /**
675
-         * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
676
-         * uses the $_admin_page_title property and we want different outputs in the different spots.
677
-         */
678
-        $page_title = $this->_admin_page_title;
679
-        $this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
680
-        $this->_per_page_screen_option();
681
-        $this->_admin_page_title = $page_title;
682
-    }
683
-
684
-
685
-    protected function _add_screen_options_default()
686
-    {
687
-        $this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
688
-        $this->_per_page_screen_option();
689
-    }
690
-
691
-
692
-    // none of the below group are currently used for Messages
693
-    protected function _add_feature_pointers()
694
-    {
695
-    }
696
-
697
-    public function admin_init()
698
-    {
699
-    }
700
-
701
-    public function admin_notices()
702
-    {
703
-    }
704
-
705
-    public function admin_footer_scripts()
706
-    {
707
-    }
708
-
709
-
710
-    public function messages_help_tab()
711
-    {
712
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
713
-    }
714
-
715
-
716
-    public function messengers_help_tab()
717
-    {
718
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
719
-    }
720
-
721
-
722
-    public function message_types_help_tab()
723
-    {
724
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
725
-    }
726
-
727
-
728
-    public function messages_overview_help_tab()
729
-    {
730
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
731
-    }
732
-
733
-
734
-    public function message_templates_help_tab()
735
-    {
736
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
737
-    }
738
-
739
-
740
-    public function edit_message_template_help_tab()
741
-    {
742
-        $args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
743
-                        . esc_attr__('Editor Title', 'event_espresso')
744
-                        . '" />';
745
-        $args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
746
-                        . esc_attr__('Context Switcher and Preview', 'event_espresso')
747
-                        . '" />';
748
-        $args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
749
-                        . esc_attr__('Message Template Form Fields', 'event_espresso')
750
-                        . '" />';
751
-        $args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
752
-                        . esc_attr__('Shortcodes Metabox', 'event_espresso')
753
-                        . '" />';
754
-        $args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
755
-                        . esc_attr__('Publish Metabox', 'event_espresso')
756
-                        . '" />';
757
-        EEH_Template::display_template(
758
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
759
-            $args
760
-        );
761
-    }
762
-
763
-
764
-    public function message_template_shortcodes_help_tab()
765
-    {
766
-        $this->_set_shortcodes();
767
-        $args['shortcodes'] = $this->_shortcodes;
768
-        EEH_Template::display_template(
769
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
770
-            $args
771
-        );
772
-    }
773
-
774
-
775
-    public function preview_message_help_tab()
776
-    {
777
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
778
-    }
779
-
780
-
781
-    public function settings_help_tab()
782
-    {
783
-        $args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
784
-                        . '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
785
-        $args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
786
-                        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
787
-        $args['img3'] = '<div class="switch">'
788
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
789
-                        . ' type="checkbox" checked="checked">'
790
-                        . '<label for="ee-on-off-toggle-on"></label>'
791
-                        . '</div>';
792
-        $args['img4'] = '<div class="switch">'
793
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
794
-                        . ' type="checkbox">'
795
-                        . '<label for="ee-on-off-toggle-on"></label>'
796
-                        . '</div>';
797
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
798
-    }
799
-
800
-
801
-    public function load_scripts_styles()
802
-    {
803
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
804
-        wp_enqueue_style('espresso_ee_msg');
805
-
806
-        wp_register_script(
807
-            'ee-messages-settings',
808
-            EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
809
-            array('jquery-ui-droppable', 'ee-serialize-full-array'),
810
-            EVENT_ESPRESSO_VERSION,
811
-            true
812
-        );
813
-        wp_register_script(
814
-            'ee-msg-list-table-js',
815
-            EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
816
-            array('ee-dialog'),
817
-            EVENT_ESPRESSO_VERSION
818
-        );
819
-    }
820
-
821
-
822
-    public function load_scripts_styles_default()
823
-    {
824
-        wp_enqueue_script('ee-msg-list-table-js');
825
-    }
826
-
827
-
828
-    public function wp_editor_css($mce_css)
829
-    {
830
-        // if we're on the edit_message_template route
831
-        if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
832
-            $message_type_name = $this->_active_message_type_name;
833
-
834
-            // we're going to REPLACE the existing mce css
835
-            // we need to get the css file location from the active messenger
836
-            $mce_css = $this->_active_messenger->get_variation(
837
-                $this->_template_pack,
838
-                $message_type_name,
839
-                true,
840
-                'wpeditor',
841
-                $this->_variation
842
-            );
843
-        }
844
-
845
-        return $mce_css;
846
-    }
847
-
848
-
849
-    public function load_scripts_styles_edit_message_template()
850
-    {
851
-
852
-        $this->_set_shortcodes();
853
-
854
-        EE_Registry::$i18n_js_strings['confirm_default_reset'] = sprintf(
855
-            esc_html__(
856
-                '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.',
857
-                'event_espresso'
858
-            ),
859
-            $this->_message_template_group->messenger_obj()->label['singular'],
860
-            $this->_message_template_group->message_type_obj()->label['singular']
861
-        );
862
-        EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
863
-            '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?',
864
-            'event_espresso'
865
-        );
866
-        EE_Registry::$i18n_js_strings['server_error'] = esc_html__(
867
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
868
-            'event_espresso'
869
-        );
870
-
871
-        wp_register_script(
872
-            'ee_msgs_edit_js',
873
-            EE_MSG_ASSETS_URL . 'ee_message_editor.js',
874
-            array('jquery'),
875
-            EVENT_ESPRESSO_VERSION
876
-        );
877
-
878
-        wp_enqueue_script('ee_admin_js');
879
-        wp_enqueue_script('ee_msgs_edit_js');
880
-
881
-        // add in special css for tiny_mce
882
-        add_filter('mce_css', array($this, 'wp_editor_css'));
883
-    }
884
-
885
-
886
-    public function load_scripts_styles_display_preview_message()
887
-    {
888
-
889
-        $this->_set_message_template_group();
890
-
891
-        if (isset($this->_req_data['messenger'])) {
892
-            $this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
893
-                $this->_req_data['messenger']
894
-            );
895
-        }
896
-
897
-        $message_type_name = isset($this->_req_data['message_type']) ? $this->_req_data['message_type'] : '';
898
-
899
-
900
-        wp_enqueue_style(
901
-            'espresso_preview_css',
902
-            $this->_active_messenger->get_variation(
903
-                $this->_template_pack,
904
-                $message_type_name,
905
-                true,
906
-                'preview',
907
-                $this->_variation
908
-            )
909
-        );
910
-    }
911
-
912
-
913
-    public function load_scripts_styles_settings()
914
-    {
915
-        wp_register_style(
916
-            'ee-message-settings',
917
-            EE_MSG_ASSETS_URL . 'ee_message_settings.css',
918
-            array(),
919
-            EVENT_ESPRESSO_VERSION
920
-        );
921
-        wp_enqueue_style('ee-text-links');
922
-        wp_enqueue_style('ee-message-settings');
923
-        wp_enqueue_script('ee-messages-settings');
924
-    }
925
-
926
-
927
-    /**
928
-     * set views array for List Table
929
-     */
930
-    public function _set_list_table_views_global_mtps()
931
-    {
932
-        $this->_views = array(
933
-            'in_use' => array(
934
-                'slug'  => 'in_use',
935
-                'label' => esc_html__('In Use', 'event_espresso'),
936
-                'count' => 0,
937
-            ),
938
-        );
939
-    }
940
-
941
-
942
-    /**
943
-     * Set views array for the Custom Template List Table
944
-     */
945
-    public function _set_list_table_views_custom_mtps()
946
-    {
947
-        $this->_set_list_table_views_global_mtps();
948
-        $this->_views['in_use']['bulk_action'] = array(
949
-            'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
950
-        );
951
-    }
952
-
953
-
954
-    /**
955
-     * set views array for message queue list table
956
-     *
957
-     * @throws InvalidDataTypeException
958
-     * @throws InvalidInterfaceException
959
-     * @throws InvalidArgumentException
960
-     * @throws EE_Error
961
-     * @throws ReflectionException
962
-     */
963
-    public function _set_list_table_views_default()
964
-    {
965
-        EE_Registry::instance()->load_helper('Template');
966
-
967
-        $common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
968
-            'ee_send_message',
969
-            'message_list_table_bulk_actions'
970
-        )
971
-            ? array(
972
-                'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
973
-                'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
974
-                'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
975
-                'send_now'              => esc_html__('Send Now', 'event_espresso'),
976
-            )
977
-            : array();
978
-
979
-        $delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
980
-            'ee_delete_messages',
981
-            'message_list_table_bulk_actions'
982
-        )
983
-            ? array('delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso'))
984
-            : array();
985
-
986
-
987
-        $this->_views = array(
988
-            'all' => array(
989
-                'slug'        => 'all',
990
-                'label'       => esc_html__('All', 'event_espresso'),
991
-                'count'       => 0,
992
-                'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
993
-            ),
994
-        );
995
-
996
-
997
-        foreach (EEM_Message::instance()->all_statuses() as $status) {
998
-            if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
999
-                continue;
1000
-            }
1001
-            $status_bulk_actions = $common_bulk_actions;
1002
-            // unset bulk actions not applying to status
1003
-            if (! empty($status_bulk_actions)) {
1004
-                switch ($status) {
1005
-                    case EEM_Message::status_idle:
1006
-                    case EEM_Message::status_resend:
1007
-                        $status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1008
-                        break;
1009
-
1010
-                    case EEM_Message::status_failed:
1011
-                    case EEM_Message::status_debug_only:
1012
-                    case EEM_Message::status_messenger_executing:
1013
-                        $status_bulk_actions = array();
1014
-                        break;
1015
-
1016
-                    case EEM_Message::status_incomplete:
1017
-                        unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1018
-                        break;
1019
-
1020
-                    case EEM_Message::status_retry:
1021
-                    case EEM_Message::status_sent:
1022
-                        unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1023
-                        break;
1024
-                }
1025
-            }
1026
-
1027
-            // skip adding messenger executing status to views because it will be included with the Failed view.
1028
-            if ($status === EEM_Message::status_messenger_executing) {
1029
-                continue;
1030
-            }
1031
-
1032
-            $this->_views[ strtolower($status) ] = array(
1033
-                'slug'        => strtolower($status),
1034
-                'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1035
-                'count'       => 0,
1036
-                'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1037
-            );
1038
-        }
1039
-    }
1040
-
1041
-
1042
-    protected function _ee_default_messages_overview_list_table()
1043
-    {
1044
-        $this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1045
-        $this->display_admin_list_table_page_with_no_sidebar();
1046
-    }
1047
-
1048
-
1049
-    protected function _message_queue_list_table()
1050
-    {
1051
-        $this->_search_btn_label = esc_html__('Message Activity', 'event_espresso');
1052
-        $this->_template_args['per_column'] = 6;
1053
-        $this->_template_args['after_list_table'] = $this->_display_legend($this->_message_legend_items());
1054
-        $this->_template_args['before_list_table'] = '<h3>'
1055
-                                                     . EEM_Message::instance()->get_pretty_label_for_results()
1056
-                                                     . '</h3>';
1057
-        $this->display_admin_list_table_page_with_no_sidebar();
1058
-    }
1059
-
1060
-
1061
-    protected function _message_legend_items()
1062
-    {
1063
-
1064
-        $action_css_classes = EEH_MSG_Template::get_message_action_icons();
1065
-        $action_items = array();
1066
-
1067
-        foreach ($action_css_classes as $action_item => $action_details) {
1068
-            if ($action_item === 'see_notifications_for') {
1069
-                continue;
1070
-            }
1071
-            $action_items[ $action_item ] = array(
1072
-                'class' => $action_details['css_class'],
1073
-                'desc'  => $action_details['label'],
1074
-            );
1075
-        }
1076
-
1077
-        /** @type array $status_items status legend setup */
1078
-        $status_items = array(
1079
-            'incomplete_status'          => array(
1080
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1081
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1082
-            ),
1083
-            'idle_status'                => array(
1084
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1085
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1086
-            ),
1087
-            'resend_status'              => array(
1088
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1089
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1090
-            ),
1091
-            'messenger_executing_status' => array(
1092
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1093
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1094
-            ),
1095
-            'sent_status'                => array(
1096
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1097
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1098
-            ),
1099
-            'retry_status'               => array(
1100
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1101
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1102
-            ),
1103
-            'failed_status'              => array(
1104
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1105
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1106
-            ),
1107
-        );
1108
-        if (EEM_Message::debug()) {
1109
-            $status_items['debug_only_status'] = array(
1110
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1111
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1112
-            );
1113
-        }
1114
-
1115
-        return array_merge($action_items, $status_items);
1116
-    }
1117
-
1118
-
1119
-    protected function _custom_mtps_preview()
1120
-    {
1121
-        $this->_admin_page_title = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1122
-        $this->_template_args['preview_img'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1123
-                                               . ' alt="' . esc_attr__(
1124
-                                                   'Preview Custom Message Templates screenshot',
1125
-                                                   'event_espresso'
1126
-                                               ) . '" />';
1127
-        $this->_template_args['preview_text'] = '<strong>'
1128
-                                                . esc_html__(
1129
-                                                    '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.',
1130
-                                                    'event_espresso'
1131
-                                                )
1132
-                                                . '</strong>';
1133
-
1134
-        $this->display_admin_caf_preview_page('custom_message_types', false);
1135
-    }
1136
-
1137
-
1138
-    /**
1139
-     * get_message_templates
1140
-     * This gets all the message templates for listing on the overview list.
1141
-     *
1142
-     * @access public
1143
-     * @param int    $perpage the amount of templates groups to show per page
1144
-     * @param string $type    the current _view we're getting templates for
1145
-     * @param bool   $count   return count?
1146
-     * @param bool   $all     disregard any paging info (get all data);
1147
-     * @param bool   $global  whether to return just global (true) or custom templates (false)
1148
-     * @return array
1149
-     * @throws EE_Error
1150
-     * @throws InvalidArgumentException
1151
-     * @throws InvalidDataTypeException
1152
-     * @throws InvalidInterfaceException
1153
-     */
1154
-    public function get_message_templates(
1155
-        $perpage = 10,
1156
-        $type = 'in_use',
1157
-        $count = false,
1158
-        $all = false,
1159
-        $global = true
1160
-    ) {
1161
-
1162
-        $MTP = EEM_Message_Template_Group::instance();
1163
-
1164
-        $this->_req_data['orderby'] = empty($this->_req_data['orderby']) ? 'GRP_ID' : $this->_req_data['orderby'];
1165
-        $orderby = $this->_req_data['orderby'];
1166
-
1167
-        $order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1168
-            ? $this->_req_data['order']
1169
-            : 'ASC';
1170
-
1171
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1172
-            ? $this->_req_data['paged']
1173
-            : 1;
1174
-        $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1175
-            ? $this->_req_data['perpage']
1176
-            : $perpage;
1177
-
1178
-        $offset = ($current_page - 1) * $per_page;
1179
-        $limit = $all ? null : array($offset, $per_page);
1180
-
1181
-
1182
-        // options will match what is in the _views array property
1183
-        switch ($type) {
1184
-            case 'in_use':
1185
-                $templates = $MTP->get_all_active_message_templates($orderby, $order, $limit, $count, $global, true);
1186
-                break;
1187
-            default:
1188
-                $templates = $MTP->get_all_trashed_grouped_message_templates($orderby, $order, $limit, $count, $global);
1189
-        }
1190
-
1191
-        return $templates;
1192
-    }
1193
-
1194
-
1195
-    /**
1196
-     * filters etc might need a list of installed message_types
1197
-     *
1198
-     * @return array an array of message type objects
1199
-     */
1200
-    public function get_installed_message_types()
1201
-    {
1202
-        $installed_message_types = $this->_message_resource_manager->installed_message_types();
1203
-        $installed = array();
1204
-
1205
-        foreach ($installed_message_types as $message_type) {
1206
-            $installed[ $message_type->name ] = $message_type;
1207
-        }
1208
-
1209
-        return $installed;
1210
-    }
1211
-
1212
-
1213
-    /**
1214
-     * _add_message_template
1215
-     *
1216
-     * This is used when creating a custom template. All Custom Templates start based off another template.
1217
-     *
1218
-     * @param string $message_type
1219
-     * @param string $messenger
1220
-     * @param string $GRP_ID
1221
-     *
1222
-     * @throws EE_error
1223
-     */
1224
-    protected function _add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1225
-    {
1226
-        // set values override any request data
1227
-        $message_type = ! empty($message_type) ? $message_type : '';
1228
-        $message_type = empty($message_type) && ! empty($this->_req_data['message_type'])
1229
-            ? $this->_req_data['message_type']
1230
-            : $message_type;
1231
-
1232
-        $messenger = ! empty($messenger) ? $messenger : '';
1233
-        $messenger = empty($messenger) && ! empty($this->_req_data['messenger'])
1234
-            ? $this->_req_data['messenger']
1235
-            : $messenger;
1236
-
1237
-        $GRP_ID = ! empty($GRP_ID) ? $GRP_ID : '';
1238
-        $GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : $GRP_ID;
1239
-
1240
-        // we need messenger and message type.  They should be coming from the event editor. If not here then return error
1241
-        if (empty($message_type) || empty($messenger)) {
1242
-            throw new EE_Error(
1243
-                esc_html__(
1244
-                    'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1245
-                    'event_espresso'
1246
-                )
1247
-            );
1248
-        }
1249
-
1250
-        // we need the GRP_ID for the template being used as the base for the new template
1251
-        if (empty($GRP_ID)) {
1252
-            throw new EE_Error(
1253
-                esc_html__(
1254
-                    'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1255
-                    'event_espresso'
1256
-                )
1257
-            );
1258
-        }
1259
-
1260
-        // let's just make sure the template gets generated!
1261
-
1262
-        // we need to reassign some variables for what the insert is expecting
1263
-        $this->_req_data['MTP_messenger'] = $messenger;
1264
-        $this->_req_data['MTP_message_type'] = $message_type;
1265
-        $this->_req_data['GRP_ID'] = $GRP_ID;
1266
-        $this->_insert_or_update_message_template(true);
1267
-    }
1268
-
1269
-
1270
-    /**
1271
-     * public wrapper for the _add_message_template method
1272
-     *
1273
-     * @param string $message_type     message type slug
1274
-     * @param string $messenger        messenger slug
1275
-     * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1276
-     *                                 off of.
1277
-     * @throws EE_error
1278
-     */
1279
-    public function add_message_template($message_type, $messenger, $GRP_ID)
1280
-    {
1281
-        $this->_add_message_template($message_type, $messenger, $GRP_ID);
1282
-    }
1283
-
1284
-
1285
-    /**
1286
-     * _edit_message_template
1287
-     *
1288
-     * @access protected
1289
-     * @return void
1290
-     * @throws InvalidIdentifierException
1291
-     * @throws DomainException
1292
-     * @throws EE_Error
1293
-     * @throws InvalidArgumentException
1294
-     * @throws ReflectionException
1295
-     * @throws InvalidDataTypeException
1296
-     * @throws InvalidInterfaceException
1297
-     */
1298
-    protected function _edit_message_template()
1299
-    {
1300
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1301
-        $template_fields = '';
1302
-        $sidebar_fields = '';
1303
-        // we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1304
-        // valid html in the templates.
1305
-        add_filter('tiny_mce_before_init', array($this, 'filter_tinymce_init'), 10, 2);
1306
-
1307
-        $GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
1308
-            ? absint($this->_req_data['id'])
1309
-            : false;
1310
-
1311
-        $EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
1312
-        ? absint($this->_req_data['evt_id'])
1313
-        : false;
1314
-
1315
-        $this->_set_shortcodes(); // this also sets the _message_template property.
1316
-        $message_template_group = $this->_message_template_group;
1317
-        $c_label = $message_template_group->context_label();
1318
-        $c_config = $message_template_group->contexts_config();
1319
-
1320
-        reset($c_config);
1321
-        $context = isset($this->_req_data['context']) && ! empty($this->_req_data['context'])
1322
-            ? strtolower($this->_req_data['context'])
1323
-            : key($c_config);
1324
-
1325
-
1326
-        if (empty($GRP_ID)) {
1327
-            $action = 'insert_message_template';
1328
-            $edit_message_template_form_url = add_query_arg(
1329
-                array('action' => $action, 'noheader' => true),
1330
-                EE_MSG_ADMIN_URL
1331
-            );
1332
-        } else {
1333
-            $action = 'update_message_template';
1334
-            $edit_message_template_form_url = add_query_arg(
1335
-                array('action' => $action, 'noheader' => true),
1336
-                EE_MSG_ADMIN_URL
1337
-            );
1338
-        }
1339
-
1340
-        // set active messenger for this view
1341
-        $this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
1342
-            $message_template_group->messenger()
1343
-        );
1344
-        $this->_active_message_type_name = $message_template_group->message_type();
1345
-
1346
-
1347
-        // Do we have any validation errors?
1348
-        $validators = $this->_get_transient();
1349
-        $v_fields = ! empty($validators) ? array_keys($validators) : array();
1350
-
1351
-
1352
-        // we need to assemble the title from Various details
1353
-        $context_label = sprintf(
1354
-            esc_html__('(%s %s)', 'event_espresso'),
1355
-            $c_config[ $context ]['label'],
1356
-            ucwords($c_label['label'])
1357
-        );
1358
-
1359
-        $title = sprintf(
1360
-            esc_html__(' %s %s Template %s', 'event_espresso'),
1361
-            ucwords($message_template_group->messenger_obj()->label['singular']),
1362
-            ucwords($message_template_group->message_type_obj()->label['singular']),
1363
-            $context_label
1364
-        );
1365
-
1366
-        $this->_template_args['GRP_ID'] = $GRP_ID;
1367
-        $this->_template_args['message_template'] = $message_template_group;
1368
-        $this->_template_args['is_extra_fields'] = false;
1369
-
1370
-
1371
-        // let's get EEH_MSG_Template so we can get template form fields
1372
-        $template_field_structure = EEH_MSG_Template::get_fields(
1373
-            $message_template_group->messenger(),
1374
-            $message_template_group->message_type()
1375
-        );
1376
-
1377
-        if (! $template_field_structure) {
1378
-            $template_field_structure = false;
1379
-            $template_fields = esc_html__(
1380
-                'There was an error in assembling the fields for this display (you should see an error message)',
1381
-                'event_espresso'
1382
-            );
1383
-        }
1384
-
1385
-
1386
-        $message_templates = $message_template_group->context_templates();
1387
-
1388
-
1389
-        // if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1390
-        // will get handled in the "extra" array.
1391
-        if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1392
-            foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1393
-                unset($template_field_structure[ $context ][ $reference_field ]);
1394
-            }
1395
-        }
1396
-
1397
-        // let's loop through the template_field_structure and actually assemble the input fields!
1398
-        if (! empty($template_field_structure)) {
1399
-            foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1400
-                // if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1401
-                // the extra array and reset them.
1402
-                if ($template_field === 'extra') {
1403
-                    $this->_template_args['is_extra_fields'] = true;
1404
-                    foreach ($field_setup_array as $reference_field => $new_fields_array) {
1405
-                        $message_template = $message_templates[ $context ][ $reference_field ];
1406
-                        $content = $message_template instanceof EE_Message_Template
1407
-                            ? $message_template->get('MTP_content')
1408
-                            : '';
1409
-                        foreach ($new_fields_array as $extra_field => $extra_array) {
1410
-                            // let's verify if we need this extra field via the shortcodes parameter.
1411
-                            $continue = false;
1412
-                            if (isset($extra_array['shortcodes_required'])) {
1413
-                                foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1414
-                                    if (! array_key_exists($shortcode, $this->_shortcodes)) {
1415
-                                        $continue = true;
1416
-                                    }
1417
-                                }
1418
-                                if ($continue) {
1419
-                                    continue;
1420
-                                }
1421
-                            }
1422
-
1423
-                            $field_id = $reference_field
1424
-                                        . '-'
1425
-                                        . $extra_field
1426
-                                        . '-content';
1427
-                            $template_form_fields[ $field_id ] = $extra_array;
1428
-                            $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1429
-                                                                         . $reference_field
1430
-                                                                         . '][content]['
1431
-                                                                         . $extra_field . ']';
1432
-                            $css_class = isset($extra_array['css_class'])
1433
-                                ? $extra_array['css_class']
1434
-                                : '';
1435
-
1436
-                            $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1437
-                                                                              && in_array($extra_field, $v_fields, true)
1438
-                                                                              &&
1439
-                                                                              (
1440
-                                                                                  is_array($validators[ $extra_field ])
1441
-                                                                                  && isset($validators[ $extra_field ]['msg'])
1442
-                                                                              )
1443
-                                ? 'validate-error ' . $css_class
1444
-                                : $css_class;
1445
-
1446
-                            $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1447
-                                                                          && isset($content[ $extra_field ])
1448
-                                ? $content[ $extra_field ]
1449
-                                : '';
1450
-
1451
-                            // do we have a validation error?  if we do then let's use that value instead
1452
-                            $template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1453
-                                ? $validators[ $extra_field ]['value']
1454
-                                : $template_form_fields[ $field_id ]['value'];
1455
-
1456
-
1457
-                            $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1458
-
1459
-                            // shortcode selector
1460
-                            $field_name_to_use = $extra_field === 'main'
1461
-                                ? 'content'
1462
-                                : $extra_field;
1463
-                            $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1464
-                                $field_name_to_use,
1465
-                                $field_id
1466
-                            );
1467
-
1468
-                            if (isset($extra_array['input']) && $extra_array['input'] === 'wp_editor') {
1469
-                                // we want to decode the entities
1470
-                                $template_form_fields[ $field_id ]['value'] = $template_form_fields[ $field_id ]['value'];
1471
-                            }/**/
1472
-                        }
1473
-                        $templatefield_MTP_id = $reference_field . '-MTP_ID';
1474
-                        $templatefield_templatename_id = $reference_field . '-name';
1475
-
1476
-                        $template_form_fields[ $templatefield_MTP_id ] = array(
1477
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1478
-                            'label'      => null,
1479
-                            'input'      => 'hidden',
1480
-                            'type'       => 'int',
1481
-                            'required'   => false,
1482
-                            'validation' => false,
1483
-                            'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1484
-                            'css_class'  => '',
1485
-                            'format'     => '%d',
1486
-                            'db-col'     => 'MTP_ID',
1487
-                        );
1488
-
1489
-                        $template_form_fields[ $templatefield_templatename_id ] = array(
1490
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1491
-                            'label'      => null,
1492
-                            'input'      => 'hidden',
1493
-                            'type'       => 'string',
1494
-                            'required'   => false,
1495
-                            'validation' => true,
1496
-                            'value'      => $reference_field,
1497
-                            'css_class'  => '',
1498
-                            'format'     => '%s',
1499
-                            'db-col'     => 'MTP_template_field',
1500
-                        );
1501
-                    }
1502
-                    continue; // skip the next stuff, we got the necessary fields here for this dataset.
1503
-                } else {
1504
-                    $field_id = $template_field . '-content';
1505
-                    $template_form_fields[ $field_id ] = $field_setup_array;
1506
-                    $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields[' . $template_field . '][content]';
1507
-                    $message_template = isset($message_templates[ $context ][ $template_field ])
1508
-                        ? $message_templates[ $context ][ $template_field ]
1509
-                        : null;
1510
-                    $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1511
-                                                                  && is_array($message_templates[ $context ])
1512
-                                                                  && $message_template instanceof EE_Message_Template
1513
-                        ? $message_template->get('MTP_content')
1514
-                        : '';
1515
-
1516
-                    // do we have a validator error for this field?  if we do then we'll use that value instead
1517
-                    $template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1518
-                        ? $validators[ $template_field ]['value']
1519
-                        : $template_form_fields[ $field_id ]['value'];
1520
-
1521
-
1522
-                    $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1523
-                    $css_class = isset($field_setup_array['css_class'])
1524
-                        ? $field_setup_array['css_class']
1525
-                        : '';
1526
-                    $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1527
-                                                                      && in_array($template_field, $v_fields, true)
1528
-                                                                      && isset($validators[ $template_field ]['msg'])
1529
-                        ? 'validate-error ' . $css_class
1530
-                        : $css_class;
1531
-
1532
-                    // shortcode selector
1533
-                    $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1534
-                        $template_field,
1535
-                        $field_id
1536
-                    );
1537
-                }
1538
-
1539
-                // k took care of content field(s) now let's take care of others.
1540
-
1541
-                $templatefield_MTP_id = $template_field . '-MTP_ID';
1542
-                $templatefield_field_templatename_id = $template_field . '-name';
1543
-
1544
-                // foreach template field there are actually two form fields created
1545
-                $template_form_fields[ $templatefield_MTP_id ] = array(
1546
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1547
-                    'label'      => null,
1548
-                    'input'      => 'hidden',
1549
-                    'type'       => 'int',
1550
-                    'required'   => false,
1551
-                    'validation' => true,
1552
-                    'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1553
-                    'css_class'  => '',
1554
-                    'format'     => '%d',
1555
-                    'db-col'     => 'MTP_ID',
1556
-                );
1557
-
1558
-                $template_form_fields[ $templatefield_field_templatename_id ] = array(
1559
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1560
-                    'label'      => null,
1561
-                    'input'      => 'hidden',
1562
-                    'type'       => 'string',
1563
-                    'required'   => false,
1564
-                    'validation' => true,
1565
-                    'value'      => $template_field,
1566
-                    'css_class'  => '',
1567
-                    'format'     => '%s',
1568
-                    'db-col'     => 'MTP_template_field',
1569
-                );
1570
-            }
1571
-
1572
-            // add other fields
1573
-            $template_form_fields['ee-msg-current-context'] = array(
1574
-                'name'       => 'MTP_context',
1575
-                'label'      => null,
1576
-                'input'      => 'hidden',
1577
-                'type'       => 'string',
1578
-                'required'   => false,
1579
-                'validation' => true,
1580
-                'value'      => $context,
1581
-                'css_class'  => '',
1582
-                'format'     => '%s',
1583
-                'db-col'     => 'MTP_context',
1584
-            );
1585
-
1586
-            $template_form_fields['ee-msg-grp-id'] = array(
1587
-                'name'       => 'GRP_ID',
1588
-                'label'      => null,
1589
-                'input'      => 'hidden',
1590
-                'type'       => 'int',
1591
-                'required'   => false,
1592
-                'validation' => true,
1593
-                'value'      => $GRP_ID,
1594
-                'css_class'  => '',
1595
-                'format'     => '%d',
1596
-                'db-col'     => 'GRP_ID',
1597
-            );
1598
-
1599
-            $template_form_fields['ee-msg-messenger'] = array(
1600
-                'name'       => 'MTP_messenger',
1601
-                'label'      => null,
1602
-                'input'      => 'hidden',
1603
-                'type'       => 'string',
1604
-                'required'   => false,
1605
-                'validation' => true,
1606
-                'value'      => $message_template_group->messenger(),
1607
-                'css_class'  => '',
1608
-                'format'     => '%s',
1609
-                'db-col'     => 'MTP_messenger',
1610
-            );
1611
-
1612
-            $template_form_fields['ee-msg-message-type'] = array(
1613
-                'name'       => 'MTP_message_type',
1614
-                'label'      => null,
1615
-                'input'      => 'hidden',
1616
-                'type'       => 'string',
1617
-                'required'   => false,
1618
-                'validation' => true,
1619
-                'value'      => $message_template_group->message_type(),
1620
-                'css_class'  => '',
1621
-                'format'     => '%s',
1622
-                'db-col'     => 'MTP_message_type',
1623
-            );
1624
-
1625
-            $sidebar_form_fields['ee-msg-is-global'] = array(
1626
-                'name'       => 'MTP_is_global',
1627
-                'label'      => esc_html__('Global Template', 'event_espresso'),
1628
-                'input'      => 'hidden',
1629
-                'type'       => 'int',
1630
-                'required'   => false,
1631
-                'validation' => true,
1632
-                'value'      => $message_template_group->get('MTP_is_global'),
1633
-                'css_class'  => '',
1634
-                'format'     => '%d',
1635
-                'db-col'     => 'MTP_is_global',
1636
-            );
1637
-
1638
-            $sidebar_form_fields['ee-msg-is-override'] = array(
1639
-                'name'       => 'MTP_is_override',
1640
-                'label'      => esc_html__('Override all custom', 'event_espresso'),
1641
-                'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1642
-                'type'       => 'int',
1643
-                'required'   => false,
1644
-                'validation' => true,
1645
-                'value'      => $message_template_group->get('MTP_is_override'),
1646
-                'css_class'  => '',
1647
-                'format'     => '%d',
1648
-                'db-col'     => 'MTP_is_override',
1649
-            );
1650
-
1651
-            $sidebar_form_fields['ee-msg-is-active'] = array(
1652
-                'name'       => 'MTP_is_active',
1653
-                'label'      => esc_html__('Active Template', 'event_espresso'),
1654
-                'input'      => 'hidden',
1655
-                'type'       => 'int',
1656
-                'required'   => false,
1657
-                'validation' => true,
1658
-                'value'      => $message_template_group->is_active(),
1659
-                'css_class'  => '',
1660
-                'format'     => '%d',
1661
-                'db-col'     => 'MTP_is_active',
1662
-            );
1663
-
1664
-            $sidebar_form_fields['ee-msg-deleted'] = array(
1665
-                'name'       => 'MTP_deleted',
1666
-                'label'      => null,
1667
-                'input'      => 'hidden',
1668
-                'type'       => 'int',
1669
-                'required'   => false,
1670
-                'validation' => true,
1671
-                'value'      => $message_template_group->get('MTP_deleted'),
1672
-                'css_class'  => '',
1673
-                'format'     => '%d',
1674
-                'db-col'     => 'MTP_deleted',
1675
-            );
1676
-            $sidebar_form_fields['ee-msg-author'] = array(
1677
-                'name'       => 'MTP_user_id',
1678
-                'label'      => esc_html__('Author', 'event_espresso'),
1679
-                'input'      => 'hidden',
1680
-                'type'       => 'int',
1681
-                'required'   => false,
1682
-                'validation' => false,
1683
-                'value'      => $message_template_group->user(),
1684
-                'format'     => '%d',
1685
-                'db-col'     => 'MTP_user_id',
1686
-            );
1687
-
1688
-            $sidebar_form_fields['ee-msg-route'] = array(
1689
-                'name'  => 'action',
1690
-                'input' => 'hidden',
1691
-                'type'  => 'string',
1692
-                'value' => $action,
1693
-            );
1694
-
1695
-            $sidebar_form_fields['ee-msg-id'] = array(
1696
-                'name'  => 'id',
1697
-                'input' => 'hidden',
1698
-                'type'  => 'int',
1699
-                'value' => $GRP_ID,
1700
-            );
1701
-            $sidebar_form_fields['ee-msg-evt-nonce'] = array(
1702
-                'name'  => $action . '_nonce',
1703
-                'input' => 'hidden',
1704
-                'type'  => 'string',
1705
-                'value' => wp_create_nonce($action . '_nonce'),
1706
-            );
1707
-
1708
-            if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
1709
-                $sidebar_form_fields['ee-msg-template-switch'] = array(
1710
-                    'name'  => 'template_switch',
1711
-                    'input' => 'hidden',
1712
-                    'type'  => 'int',
1713
-                    'value' => 1,
1714
-                );
1715
-            }
1716
-
1717
-
1718
-            $template_fields = $this->_generate_admin_form_fields($template_form_fields);
1719
-            $sidebar_fields = $this->_generate_admin_form_fields($sidebar_form_fields);
1720
-        } //end if ( !empty($template_field_structure) )
1721
-
1722
-        // set extra content for publish box
1723
-        $this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1724
-        $this->_set_publish_post_box_vars(
1725
-            'id',
1726
-            $GRP_ID,
1727
-            false,
1728
-            add_query_arg(
1729
-                array('action' => 'global_mtps'),
1730
-                $this->_admin_base_url
1731
-            )
1732
-        );
1733
-
1734
-        // add preview button
1735
-        $preview_url = parent::add_query_args_and_nonce(
1736
-            array(
1737
-                'message_type' => $message_template_group->message_type(),
1738
-                'messenger'    => $message_template_group->messenger(),
1739
-                'context'      => $context,
1740
-                'GRP_ID'       => $GRP_ID,
1741
-                'evt_id'       => $EVT_ID,
1742
-                'action'       => 'preview_message',
1743
-            ),
1744
-            $this->_admin_base_url
1745
-        );
1746
-        $preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1747
-                          . esc_html__('Preview', 'event_espresso')
1748
-                          . '</a>';
1749
-
1750
-
1751
-        // setup context switcher
1752
-        $context_switcher_args = array(
1753
-            'page'    => 'espresso_messages',
1754
-            'action'  => 'edit_message_template',
1755
-            'id'      => $GRP_ID,
1756
-            'evt_id'  => $EVT_ID,
1757
-            'context' => $context,
1758
-            'extra'   => $preview_button,
1759
-        );
1760
-        $this->_set_context_switcher($message_template_group, $context_switcher_args);
1761
-
1762
-
1763
-        // main box
1764
-        $this->_template_args['template_fields'] = $template_fields;
1765
-        $this->_template_args['sidebar_box_id'] = 'details';
1766
-        $this->_template_args['action'] = $action;
1767
-        $this->_template_args['context'] = $context;
1768
-        $this->_template_args['edit_message_template_form_url'] = $edit_message_template_form_url;
1769
-        $this->_template_args['learn_more_about_message_templates_link'] =
1770
-            $this->_learn_more_about_message_templates_link();
1771
-
1772
-
1773
-        $this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1774
-        $this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1775
-            $message_template_group,
1776
-            $context,
1777
-            $context_label
1778
-        );
1779
-        $this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1780
-        $this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1781
-
1782
-        $this->_template_path = $this->_template_args['GRP_ID']
1783
-            ? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1784
-            : EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1785
-
1786
-        // send along EE_Message_Template_Group object for further template use.
1787
-        $this->_template_args['MTP'] = $message_template_group;
1788
-
1789
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1790
-            $this->_template_path,
1791
-            $this->_template_args,
1792
-            true
1793
-        );
1794
-
1795
-
1796
-        // finally, let's set the admin_page title
1797
-        $this->_admin_page_title = sprintf(__('Editing %s', 'event_espresso'), $title);
1798
-
1799
-
1800
-        // we need to take care of setting the shortcodes property for use elsewhere.
1801
-        $this->_set_shortcodes();
1802
-
1803
-
1804
-        // final template wrapper
1805
-        $this->display_admin_page_with_sidebar();
1806
-    }
1807
-
1808
-
1809
-    public function filter_tinymce_init($mceInit, $editor_id)
1810
-    {
1811
-        return $mceInit;
1812
-    }
1813
-
1814
-
1815
-    public function add_context_switcher()
1816
-    {
1817
-        return $this->_context_switcher;
1818
-    }
1819
-
1820
-
1821
-    /**
1822
-     * Adds the activation/deactivation toggle for the message template context.
1823
-     *
1824
-     * @param EE_Message_Template_Group $message_template_group
1825
-     * @param string                    $context
1826
-     * @param string                    $context_label
1827
-     * @return string
1828
-     * @throws DomainException
1829
-     * @throws EE_Error
1830
-     * @throws InvalidIdentifierException
1831
-     */
1832
-    protected function add_active_context_element(
1833
-        EE_Message_Template_Group $message_template_group,
1834
-        $context,
1835
-        $context_label
1836
-    ) {
1837
-        $template_args = array(
1838
-            'context'                   => $context,
1839
-            'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1840
-            'is_active'                 => $message_template_group->is_context_active($context),
1841
-            'on_off_action'             => $message_template_group->is_context_active($context)
1842
-                ? 'context-off'
1843
-                : 'context-on',
1844
-            'context_label'             => str_replace(array('(', ')'), '', $context_label),
1845
-            'message_template_group_id' => $message_template_group->ID(),
1846
-        );
1847
-        return EEH_Template::display_template(
1848
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1849
-            $template_args,
1850
-            true
1851
-        );
1852
-    }
1853
-
1854
-
1855
-    /**
1856
-     * Ajax callback for `toggle_context_template` ajax action.
1857
-     * Handles toggling the message context on or off.
1858
-     *
1859
-     * @throws EE_Error
1860
-     * @throws InvalidArgumentException
1861
-     * @throws InvalidDataTypeException
1862
-     * @throws InvalidIdentifierException
1863
-     * @throws InvalidInterfaceException
1864
-     */
1865
-    public function toggle_context_template()
1866
-    {
1867
-        $success = true;
1868
-        // check for required data
1869
-        if (! isset(
1870
-            $this->_req_data['message_template_group_id'],
1871
-            $this->_req_data['context'],
1872
-            $this->_req_data['status']
1873
-        )) {
1874
-            EE_Error::add_error(
1875
-                esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1876
-                __FILE__,
1877
-                __FUNCTION__,
1878
-                __LINE__
1879
-            );
1880
-            $success = false;
1881
-        }
1882
-
1883
-        $nonce = isset($this->_req_data['toggle_context_nonce'])
1884
-            ? sanitize_text_field($this->_req_data['toggle_context_nonce'])
1885
-            : '';
1886
-        $nonce_ref = 'activate_' . $this->_req_data['context'] . '_toggle_nonce';
1887
-        $this->_verify_nonce($nonce, $nonce_ref);
1888
-        $status = $this->_req_data['status'];
1889
-        if ($status !== 'off' && $status !== 'on') {
1890
-            EE_Error::add_error(
1891
-                sprintf(
1892
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1893
-                    $this->_req_data['status']
1894
-                ),
1895
-                __FILE__,
1896
-                __FUNCTION__,
1897
-                __LINE__
1898
-            );
1899
-            $success = false;
1900
-        }
1901
-        $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID(
1902
-            $this->_req_data['message_template_group_id']
1903
-        );
1904
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
1905
-            EE_Error::add_error(
1906
-                sprintf(
1907
-                    esc_html__(
1908
-                        'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1909
-                        'event_espresso'
1910
-                    ),
1911
-                    $this->_req_data['message_template_group_id'],
1912
-                    'EE_Message_Template_Group'
1913
-                ),
1914
-                __FILE__,
1915
-                __FUNCTION__,
1916
-                __LINE__
1917
-            );
1918
-            $success = false;
1919
-        }
1920
-        if ($success) {
1921
-            $success = $status === 'off'
1922
-                ? $message_template_group->deactivate_context($this->_req_data['context'])
1923
-                : $message_template_group->activate_context($this->_req_data['context']);
1924
-        }
1925
-        $this->_template_args['success'] = $success;
1926
-        $this->_return_json();
1927
-    }
1928
-
1929
-
1930
-    public function _add_form_element_before()
1931
-    {
1932
-        return '<form method="post" action="'
1933
-               . $this->_template_args["edit_message_template_form_url"]
1934
-               . '" id="ee-msg-edit-frm">';
1935
-    }
1936
-
1937
-    public function _add_form_element_after()
1938
-    {
1939
-        return '</form>';
1940
-    }
1941
-
1942
-
1943
-    /**
1944
-     * This executes switching the template pack for a message template.
1945
-     *
1946
-     * @since 4.5.0
1947
-     * @throws EE_Error
1948
-     * @throws InvalidDataTypeException
1949
-     * @throws InvalidInterfaceException
1950
-     * @throws InvalidArgumentException
1951
-     * @throws ReflectionException
1952
-     */
1953
-    public function switch_template_pack()
1954
-    {
1955
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1956
-        $template_pack = ! empty($this->_req_data['template_pack']) ? $this->_req_data['template_pack'] : '';
1957
-
1958
-        // verify we have needed values.
1959
-        if (empty($GRP_ID) || empty($template_pack)) {
1960
-            $this->_template_args['error'] = true;
1961
-            EE_Error::add_error(
1962
-                esc_html__('The required date for switching templates is not available.', 'event_espresso'),
1963
-                __FILE__,
1964
-                __FUNCTION__,
1965
-                __LINE__
1966
-            );
1967
-        } else {
1968
-            // get template, set the new template_pack and then reset to default
1969
-            /** @type EE_Message_Template_Group $message_template_group */
1970
-            $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1971
-
1972
-            $message_template_group->set_template_pack_name($template_pack);
1973
-            $this->_req_data['msgr'] = $message_template_group->messenger();
1974
-            $this->_req_data['mt'] = $message_template_group->message_type();
1975
-
1976
-            $query_args = $this->_reset_to_default_template();
1977
-
1978
-            if (empty($query_args['id'])) {
1979
-                EE_Error::add_error(
1980
-                    esc_html__(
1981
-                        'Something went wrong with switching the template pack. Please try again or contact EE support',
1982
-                        'event_espresso'
1983
-                    ),
1984
-                    __FILE__,
1985
-                    __FUNCTION__,
1986
-                    __LINE__
1987
-                );
1988
-                $this->_template_args['error'] = true;
1989
-            } else {
1990
-                $template_label = $message_template_group->get_template_pack()->label;
1991
-                $template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
1992
-                EE_Error::add_success(
1993
-                    sprintf(
1994
-                        esc_html__(
1995
-                            'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
1996
-                            'event_espresso'
1997
-                        ),
1998
-                        $template_label,
1999
-                        $template_pack_labels->template_pack
2000
-                    )
2001
-                );
2002
-                // generate the redirect url for js.
2003
-                $url = self::add_query_args_and_nonce(
2004
-                    $query_args,
2005
-                    $this->_admin_base_url
2006
-                );
2007
-                $this->_template_args['data']['redirect_url'] = $url;
2008
-                $this->_template_args['success'] = true;
2009
-            }
2010
-
2011
-            $this->_return_json();
2012
-        }
2013
-    }
2014
-
2015
-
2016
-    /**
2017
-     * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2018
-     * they want.
2019
-     *
2020
-     * @access protected
2021
-     * @return array|null
2022
-     * @throws EE_Error
2023
-     * @throws InvalidArgumentException
2024
-     * @throws InvalidDataTypeException
2025
-     * @throws InvalidInterfaceException
2026
-     */
2027
-    protected function _reset_to_default_template()
2028
-    {
2029
-
2030
-        $templates = array();
2031
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2032
-        // we need to make sure we've got the info we need.
2033
-        if (! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2034
-            EE_Error::add_error(
2035
-                esc_html__(
2036
-                    '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.',
2037
-                    'event_espresso'
2038
-                ),
2039
-                __FILE__,
2040
-                __FUNCTION__,
2041
-                __LINE__
2042
-            );
2043
-        }
2044
-
2045
-        // all templates will be reset to whatever the defaults are
2046
-        // for the global template matching the messenger and message type.
2047
-        $success = ! empty($GRP_ID) ? true : false;
2048
-
2049
-        if ($success) {
2050
-            // let's first determine if the incoming template is a global template,
2051
-            // if it isn't then we need to get the global template matching messenger and message type.
2052
-            // $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $GRP_ID );
2053
-
2054
-
2055
-            // note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2056
-            $success = $this->_delete_mtp_permanently($GRP_ID, false);
2057
-
2058
-            if ($success) {
2059
-                // if successfully deleted, lets generate the new ones.
2060
-                // Note. We set GLOBAL to true, because resets on ANY template
2061
-                // will use the related global template defaults for regeneration.
2062
-                // This means that if a custom template is reset it resets to whatever the related global template is.
2063
-                // HOWEVER, we DO keep the template pack and template variation set
2064
-                // for the current custom template when resetting.
2065
-                $templates = $this->_generate_new_templates(
2066
-                    $this->_req_data['msgr'],
2067
-                    $this->_req_data['mt'],
2068
-                    $GRP_ID,
2069
-                    true
2070
-                );
2071
-            }
2072
-        }
2073
-
2074
-        // any error messages?
2075
-        if (! $success) {
2076
-            EE_Error::add_error(
2077
-                esc_html__(
2078
-                    'Something went wrong with deleting existing templates. Unable to reset to default',
2079
-                    'event_espresso'
2080
-                ),
2081
-                __FILE__,
2082
-                __FUNCTION__,
2083
-                __LINE__
2084
-            );
2085
-        }
2086
-
2087
-        // all good, let's add a success message!
2088
-        if ($success && ! empty($templates)) {
2089
-            // the info for the template we generated is the first element in the returned array
2090
-            // $templates = $templates[0];
2091
-            EE_Error::overwrite_success();
2092
-            EE_Error::add_success(__('Templates have been reset to defaults.', 'event_espresso'));
2093
-        }
2094
-
2095
-
2096
-        $query_args = array(
2097
-            'id'      => isset($templates[0]['GRP_ID']) ? $templates[0]['GRP_ID'] : null,
2098
-            'context' => isset($templates[0]['MTP_context']) ? $templates[0]['MTP_context'] : null,
2099
-            'action'  => isset($templates[0]['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2100
-        );
2101
-
2102
-        // if called via ajax then we return query args otherwise redirect
2103
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2104
-            return $query_args;
2105
-        } else {
2106
-            $this->_redirect_after_action(false, '', '', $query_args, true);
2107
-
2108
-            return null;
2109
-        }
2110
-    }
2111
-
2112
-
2113
-    /**
2114
-     * Retrieve and set the message preview for display.
2115
-     *
2116
-     * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2117
-     * @return string
2118
-     * @throws ReflectionException
2119
-     * @throws EE_Error
2120
-     * @throws InvalidArgumentException
2121
-     * @throws InvalidDataTypeException
2122
-     * @throws InvalidInterfaceException
2123
-     */
2124
-    public function _preview_message($send = false)
2125
-    {
2126
-        // first make sure we've got the necessary parameters
2127
-        if (! isset(
2128
-            $this->_req_data['message_type'],
2129
-            $this->_req_data['messenger'],
2130
-            $this->_req_data['messenger'],
2131
-            $this->_req_data['GRP_ID']
2132
-        )) {
2133
-            EE_Error::add_error(
2134
-                esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2135
-                __FILE__,
2136
-                __FUNCTION__,
2137
-                __LINE__
2138
-            );
2139
-        }
2140
-
2141
-        EE_Registry::instance()->REQ->set('GRP_ID', $this->_req_data['GRP_ID']);
22
+	/**
23
+	 * @type EE_Message_Resource_Manager $_message_resource_manager
24
+	 */
25
+	protected $_message_resource_manager;
26
+
27
+	/**
28
+	 * @type string $_active_message_type_name
29
+	 */
30
+	protected $_active_message_type_name = '';
31
+
32
+	/**
33
+	 * @type EE_messenger $_active_messenger
34
+	 */
35
+	protected $_active_messenger;
36
+	protected $_activate_state;
37
+	protected $_activate_meta_box_type;
38
+	protected $_current_message_meta_box;
39
+	protected $_current_message_meta_box_object;
40
+	protected $_context_switcher;
41
+	protected $_shortcodes = array();
42
+	protected $_active_messengers = array();
43
+	protected $_active_message_types = array();
44
+
45
+	/**
46
+	 * @var EE_Message_Template_Group $_message_template_group
47
+	 */
48
+	protected $_message_template_group;
49
+	protected $_m_mt_settings = array();
50
+
51
+
52
+	/**
53
+	 * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
54
+	 * IF there is no group then it gets automatically set to the Default template pack.
55
+	 *
56
+	 * @since 4.5.0
57
+	 *
58
+	 * @var EE_Messages_Template_Pack
59
+	 */
60
+	protected $_template_pack;
61
+
62
+
63
+	/**
64
+	 * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
65
+	 * group is.  If there is no group then it automatically gets set to default.
66
+	 *
67
+	 * @since 4.5.0
68
+	 *
69
+	 * @var string
70
+	 */
71
+	protected $_variation;
72
+
73
+
74
+	/**
75
+	 * @param bool $routing
76
+	 * @throws EE_Error
77
+	 */
78
+	public function __construct($routing = true)
79
+	{
80
+		// make sure messages autoloader is running
81
+		EED_Messages::set_autoloaders();
82
+		parent::__construct($routing);
83
+	}
84
+
85
+
86
+	protected function _init_page_props()
87
+	{
88
+		$this->page_slug = EE_MSG_PG_SLUG;
89
+		$this->page_label = esc_html__('Messages Settings', 'event_espresso');
90
+		$this->_admin_base_url = EE_MSG_ADMIN_URL;
91
+		$this->_admin_base_path = EE_MSG_ADMIN;
92
+
93
+		$this->_activate_state = isset($this->_req_data['activate_state']) ? (array) $this->_req_data['activate_state']
94
+			: array();
95
+
96
+		$this->_active_messenger = isset($this->_req_data['messenger']) ? $this->_req_data['messenger'] : null;
97
+		$this->_load_message_resource_manager();
98
+	}
99
+
100
+
101
+	/**
102
+	 * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
103
+	 *
104
+	 * @throws EE_Error
105
+	 * @throws InvalidDataTypeException
106
+	 * @throws InvalidInterfaceException
107
+	 * @throws InvalidArgumentException
108
+	 * @throws ReflectionException
109
+	 */
110
+	protected function _load_message_resource_manager()
111
+	{
112
+		$this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
113
+	}
114
+
115
+
116
+	/**
117
+	 * @deprecated 4.9.9.rc.014
118
+	 * @return array
119
+	 * @throws EE_Error
120
+	 * @throws InvalidArgumentException
121
+	 * @throws InvalidDataTypeException
122
+	 * @throws InvalidInterfaceException
123
+	 */
124
+	public function get_messengers_for_list_table()
125
+	{
126
+		EE_Error::doing_it_wrong(
127
+			__METHOD__,
128
+			sprintf(
129
+				esc_html__(
130
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a messenger filter dropdown which is now generated differently via %s',
131
+					'event_espresso'
132
+				),
133
+				'Messages_Admin_Page::get_messengers_select_input()'
134
+			),
135
+			'4.9.9.rc.014'
136
+		);
137
+
138
+		$m_values = array();
139
+		$active_messengers = EEM_Message::instance()->get_all(array('group_by' => 'MSG_messenger'));
140
+		// setup messengers for selects
141
+		$i = 1;
142
+		foreach ($active_messengers as $active_messenger) {
143
+			if ($active_messenger instanceof EE_Message) {
144
+				$m_values[ $i ]['id'] = $active_messenger->messenger();
145
+				$m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
146
+				$i++;
147
+			}
148
+		}
149
+
150
+		return $m_values;
151
+	}
152
+
153
+
154
+	/**
155
+	 * @deprecated 4.9.9.rc.014
156
+	 * @return array
157
+	 * @throws EE_Error
158
+	 * @throws InvalidArgumentException
159
+	 * @throws InvalidDataTypeException
160
+	 * @throws InvalidInterfaceException
161
+	 */
162
+	public function get_message_types_for_list_table()
163
+	{
164
+		EE_Error::doing_it_wrong(
165
+			__METHOD__,
166
+			sprintf(
167
+				esc_html__(
168
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type filter dropdown which is now generated differently via %s',
169
+					'event_espresso'
170
+				),
171
+				'Messages_Admin_Page::get_message_types_select_input()'
172
+			),
173
+			'4.9.9.rc.014'
174
+		);
175
+
176
+		$mt_values = array();
177
+		$active_messages = EEM_Message::instance()->get_all(array('group_by' => 'MSG_message_type'));
178
+		$i = 1;
179
+		foreach ($active_messages as $active_message) {
180
+			if ($active_message instanceof EE_Message) {
181
+				$mt_values[ $i ]['id'] = $active_message->message_type();
182
+				$mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
183
+				$i++;
184
+			}
185
+		}
186
+
187
+		return $mt_values;
188
+	}
189
+
190
+
191
+	/**
192
+	 * @deprecated 4.9.9.rc.014
193
+	 * @return array
194
+	 * @throws EE_Error
195
+	 * @throws InvalidArgumentException
196
+	 * @throws InvalidDataTypeException
197
+	 * @throws InvalidInterfaceException
198
+	 */
199
+	public function get_contexts_for_message_types_for_list_table()
200
+	{
201
+		EE_Error::doing_it_wrong(
202
+			__METHOD__,
203
+			sprintf(
204
+				esc_html__(
205
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type context filter dropdown which is now generated differently via %s',
206
+					'event_espresso'
207
+				),
208
+				'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
209
+			),
210
+			'4.9.9.rc.014'
211
+		);
212
+
213
+		$contexts = array();
214
+		$active_message_contexts = EEM_Message::instance()->get_all(array('group_by' => 'MSG_context'));
215
+		foreach ($active_message_contexts as $active_message) {
216
+			if ($active_message instanceof EE_Message) {
217
+				$message_type = $active_message->message_type_object();
218
+				if ($message_type instanceof EE_message_type) {
219
+					$message_type_contexts = $message_type->get_contexts();
220
+					foreach ($message_type_contexts as $context => $context_details) {
221
+						$contexts[ $context ] = $context_details['label'];
222
+					}
223
+				}
224
+			}
225
+		}
226
+
227
+		return $contexts;
228
+	}
229
+
230
+
231
+	/**
232
+	 * Generate select input with provided messenger options array.
233
+	 *
234
+	 * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
235
+	 *                                 labels.
236
+	 * @return string
237
+	 * @throws EE_Error
238
+	 */
239
+	public function get_messengers_select_input($messenger_options)
240
+	{
241
+		// if empty or just one value then just return an empty string
242
+		if (empty($messenger_options)
243
+			|| ! is_array($messenger_options)
244
+			|| count($messenger_options) === 1
245
+		) {
246
+			return '';
247
+		}
248
+		// merge in default
249
+		$messenger_options = array_merge(
250
+			array('none_selected' => esc_html__('Show All Messengers', 'event_espresso')),
251
+			$messenger_options
252
+		);
253
+		$input = new EE_Select_Input(
254
+			$messenger_options,
255
+			array(
256
+				'html_name'  => 'ee_messenger_filter_by',
257
+				'html_id'    => 'ee_messenger_filter_by',
258
+				'html_class' => 'wide',
259
+				'default'    => isset($this->_req_data['ee_messenger_filter_by'])
260
+					? sanitize_title($this->_req_data['ee_messenger_filter_by'])
261
+					: 'none_selected',
262
+			)
263
+		);
264
+
265
+		return $input->get_html_for_input();
266
+	}
267
+
268
+
269
+	/**
270
+	 * Generate select input with provided message type options array.
271
+	 *
272
+	 * @param array $message_type_options Array of message types indexed by message type slug, and values are the
273
+	 *                                    message type labels
274
+	 * @return string
275
+	 * @throws EE_Error
276
+	 */
277
+	public function get_message_types_select_input($message_type_options)
278
+	{
279
+		// if empty or count of options is 1 then just return an empty string
280
+		if (empty($message_type_options)
281
+			|| ! is_array($message_type_options)
282
+			|| count($message_type_options) === 1
283
+		) {
284
+			return '';
285
+		}
286
+		// merge in default
287
+		$message_type_options = array_merge(
288
+			array('none_selected' => esc_html__('Show All Message Types', 'event_espresso')),
289
+			$message_type_options
290
+		);
291
+		$input = new EE_Select_Input(
292
+			$message_type_options,
293
+			array(
294
+				'html_name'  => 'ee_message_type_filter_by',
295
+				'html_id'    => 'ee_message_type_filter_by',
296
+				'html_class' => 'wide',
297
+				'default'    => isset($this->_req_data['ee_message_type_filter_by'])
298
+					? sanitize_title($this->_req_data['ee_message_type_filter_by'])
299
+					: 'none_selected',
300
+			)
301
+		);
302
+
303
+		return $input->get_html_for_input();
304
+	}
305
+
306
+
307
+	/**
308
+	 * Generate select input with provide message type contexts array.
309
+	 *
310
+	 * @param array $context_options Array of message type contexts indexed by context slug, and values are the
311
+	 *                               context label.
312
+	 * @return string
313
+	 * @throws EE_Error
314
+	 */
315
+	public function get_contexts_for_message_types_select_input($context_options)
316
+	{
317
+		// if empty or count of options is one then just return empty string
318
+		if (empty($context_options)
319
+			|| ! is_array($context_options)
320
+			|| count($context_options) === 1
321
+		) {
322
+			return '';
323
+		}
324
+		// merge in default
325
+		$context_options = array_merge(
326
+			array('none_selected' => esc_html__('Show all Contexts', 'event_espresso')),
327
+			$context_options
328
+		);
329
+		$input = new EE_Select_Input(
330
+			$context_options,
331
+			array(
332
+				'html_name'  => 'ee_context_filter_by',
333
+				'html_id'    => 'ee_context_filter_by',
334
+				'html_class' => 'wide',
335
+				'default'    => isset($this->_req_data['ee_context_filter_by'])
336
+					? sanitize_title($this->_req_data['ee_context_filter_by'])
337
+					: 'none_selected',
338
+			)
339
+		);
340
+
341
+		return $input->get_html_for_input();
342
+	}
343
+
344
+
345
+	protected function _ajax_hooks()
346
+	{
347
+		add_action('wp_ajax_activate_messenger', array($this, 'activate_messenger_toggle'));
348
+		add_action('wp_ajax_activate_mt', array($this, 'activate_mt_toggle'));
349
+		add_action('wp_ajax_ee_msgs_save_settings', array($this, 'save_settings'));
350
+		add_action('wp_ajax_ee_msgs_update_mt_form', array($this, 'update_mt_form'));
351
+		add_action('wp_ajax_switch_template_pack', array($this, 'switch_template_pack'));
352
+		add_action('wp_ajax_toggle_context_template', array($this, 'toggle_context_template'));
353
+	}
354
+
355
+
356
+	protected function _define_page_props()
357
+	{
358
+		$this->_admin_page_title = $this->page_label;
359
+		$this->_labels = array(
360
+			'buttons'    => array(
361
+				'add'    => esc_html__('Add New Message Template', 'event_espresso'),
362
+				'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
363
+				'delete' => esc_html__('Delete Message Template', 'event_espresso'),
364
+			),
365
+			'publishbox' => esc_html__('Update Actions', 'event_espresso'),
366
+		);
367
+	}
368
+
369
+
370
+	/**
371
+	 *        an array for storing key => value pairs of request actions and their corresponding methods
372
+	 *
373
+	 * @access protected
374
+	 * @return void
375
+	 */
376
+	protected function _set_page_routes()
377
+	{
378
+		$grp_id = ! empty($this->_req_data['GRP_ID']) && ! is_array($this->_req_data['GRP_ID'])
379
+			? $this->_req_data['GRP_ID']
380
+			: 0;
381
+		$grp_id = empty($grp_id) && ! empty($this->_req_data['id'])
382
+			? $this->_req_data['id']
383
+			: $grp_id;
384
+		$msg_id = ! empty($this->_req_data['MSG_ID']) && ! is_array($this->_req_data['MSG_ID'])
385
+			? $this->_req_data['MSG_ID']
386
+			: 0;
387
+
388
+		$this->_page_routes = array(
389
+			'default'                          => array(
390
+				'func'       => '_message_queue_list_table',
391
+				'capability' => 'ee_read_global_messages',
392
+			),
393
+			'global_mtps'                      => array(
394
+				'func'       => '_ee_default_messages_overview_list_table',
395
+				'capability' => 'ee_read_global_messages',
396
+			),
397
+			'custom_mtps'                      => array(
398
+				'func'       => '_custom_mtps_preview',
399
+				'capability' => 'ee_read_messages',
400
+			),
401
+			'add_new_message_template'         => array(
402
+				'func'       => '_add_message_template',
403
+				'capability' => 'ee_edit_messages',
404
+				'noheader'   => true,
405
+			),
406
+			'edit_message_template'            => array(
407
+				'func'       => '_edit_message_template',
408
+				'capability' => 'ee_edit_message',
409
+				'obj_id'     => $grp_id,
410
+			),
411
+			'preview_message'                  => array(
412
+				'func'               => '_preview_message',
413
+				'capability'         => 'ee_read_message',
414
+				'obj_id'             => $grp_id,
415
+				'noheader'           => true,
416
+				'headers_sent_route' => 'display_preview_message',
417
+			),
418
+			'display_preview_message'          => array(
419
+				'func'       => '_display_preview_message',
420
+				'capability' => 'ee_read_message',
421
+				'obj_id'     => $grp_id,
422
+			),
423
+			'insert_message_template'          => array(
424
+				'func'       => '_insert_or_update_message_template',
425
+				'capability' => 'ee_edit_messages',
426
+				'args'       => array('new_template' => true),
427
+				'noheader'   => true,
428
+			),
429
+			'update_message_template'          => array(
430
+				'func'       => '_insert_or_update_message_template',
431
+				'capability' => 'ee_edit_message',
432
+				'obj_id'     => $grp_id,
433
+				'args'       => array('new_template' => false),
434
+				'noheader'   => true,
435
+			),
436
+			'trash_message_template'           => array(
437
+				'func'       => '_trash_or_restore_message_template',
438
+				'capability' => 'ee_delete_message',
439
+				'obj_id'     => $grp_id,
440
+				'args'       => array('trash' => true, 'all' => true),
441
+				'noheader'   => true,
442
+			),
443
+			'trash_message_template_context'   => array(
444
+				'func'       => '_trash_or_restore_message_template',
445
+				'capability' => 'ee_delete_message',
446
+				'obj_id'     => $grp_id,
447
+				'args'       => array('trash' => true),
448
+				'noheader'   => true,
449
+			),
450
+			'restore_message_template'         => array(
451
+				'func'       => '_trash_or_restore_message_template',
452
+				'capability' => 'ee_delete_message',
453
+				'obj_id'     => $grp_id,
454
+				'args'       => array('trash' => false, 'all' => true),
455
+				'noheader'   => true,
456
+			),
457
+			'restore_message_template_context' => array(
458
+				'func'       => '_trash_or_restore_message_template',
459
+				'capability' => 'ee_delete_message',
460
+				'obj_id'     => $grp_id,
461
+				'args'       => array('trash' => false),
462
+				'noheader'   => true,
463
+			),
464
+			'delete_message_template'          => array(
465
+				'func'       => '_delete_message_template',
466
+				'capability' => 'ee_delete_message',
467
+				'obj_id'     => $grp_id,
468
+				'noheader'   => true,
469
+			),
470
+			'reset_to_default'                 => array(
471
+				'func'       => '_reset_to_default_template',
472
+				'capability' => 'ee_edit_message',
473
+				'obj_id'     => $grp_id,
474
+				'noheader'   => true,
475
+			),
476
+			'settings'                         => array(
477
+				'func'       => '_settings',
478
+				'capability' => 'manage_options',
479
+			),
480
+			'update_global_settings'           => array(
481
+				'func'       => '_update_global_settings',
482
+				'capability' => 'manage_options',
483
+				'noheader'   => true,
484
+			),
485
+			'generate_now'                     => array(
486
+				'func'       => '_generate_now',
487
+				'capability' => 'ee_send_message',
488
+				'noheader'   => true,
489
+			),
490
+			'generate_and_send_now'            => array(
491
+				'func'       => '_generate_and_send_now',
492
+				'capability' => 'ee_send_message',
493
+				'noheader'   => true,
494
+			),
495
+			'queue_for_resending'              => array(
496
+				'func'       => '_queue_for_resending',
497
+				'capability' => 'ee_send_message',
498
+				'noheader'   => true,
499
+			),
500
+			'send_now'                         => array(
501
+				'func'       => '_send_now',
502
+				'capability' => 'ee_send_message',
503
+				'noheader'   => true,
504
+			),
505
+			'delete_ee_message'                => array(
506
+				'func'       => '_delete_ee_messages',
507
+				'capability' => 'ee_delete_messages',
508
+				'noheader'   => true,
509
+			),
510
+			'delete_ee_messages'               => array(
511
+				'func'       => '_delete_ee_messages',
512
+				'capability' => 'ee_delete_messages',
513
+				'noheader'   => true,
514
+				'obj_id'     => $msg_id,
515
+			),
516
+		);
517
+	}
518
+
519
+
520
+	protected function _set_page_config()
521
+	{
522
+		$this->_page_config = array(
523
+			'default'                  => array(
524
+				'nav'           => array(
525
+					'label' => esc_html__('Message Activity', 'event_espresso'),
526
+					'order' => 10,
527
+				),
528
+				'list_table'    => 'EE_Message_List_Table',
529
+				// 'qtips' => array( 'EE_Message_List_Table_Tips' ),
530
+				'require_nonce' => false,
531
+			),
532
+			'global_mtps'              => array(
533
+				'nav'           => array(
534
+					'label' => esc_html__('Default Message Templates', 'event_espresso'),
535
+					'order' => 20,
536
+				),
537
+				'list_table'    => 'Messages_Template_List_Table',
538
+				'help_tabs'     => array(
539
+					'messages_overview_help_tab'                                => array(
540
+						'title'    => esc_html__('Messages Overview', 'event_espresso'),
541
+						'filename' => 'messages_overview',
542
+					),
543
+					'messages_overview_messages_table_column_headings_help_tab' => array(
544
+						'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
545
+						'filename' => 'messages_overview_table_column_headings',
546
+					),
547
+					'messages_overview_messages_filters_help_tab'               => array(
548
+						'title'    => esc_html__('Message Filters', 'event_espresso'),
549
+						'filename' => 'messages_overview_filters',
550
+					),
551
+					'messages_overview_messages_views_help_tab'                 => array(
552
+						'title'    => esc_html__('Message Views', 'event_espresso'),
553
+						'filename' => 'messages_overview_views',
554
+					),
555
+					'message_overview_message_types_help_tab'                   => array(
556
+						'title'    => esc_html__('Message Types', 'event_espresso'),
557
+						'filename' => 'messages_overview_types',
558
+					),
559
+					'messages_overview_messengers_help_tab'                     => array(
560
+						'title'    => esc_html__('Messengers', 'event_espresso'),
561
+						'filename' => 'messages_overview_messengers',
562
+					),
563
+				),
564
+				'help_tour'     => array('Messages_Overview_Help_Tour'),
565
+				'require_nonce' => false,
566
+			),
567
+			'custom_mtps'              => array(
568
+				'nav'           => array(
569
+					'label' => esc_html__('Custom Message Templates', 'event_espresso'),
570
+					'order' => 30,
571
+				),
572
+				'help_tabs'     => array(),
573
+				'help_tour'     => array(),
574
+				'require_nonce' => false,
575
+			),
576
+			'add_new_message_template' => array(
577
+				'nav'           => array(
578
+					'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
579
+					'order'      => 5,
580
+					'persistent' => false,
581
+				),
582
+				'require_nonce' => false,
583
+			),
584
+			'edit_message_template'    => array(
585
+				'labels'        => array(
586
+					'buttons'    => array(
587
+						'reset' => esc_html__('Reset Templates', 'event_espresso'),
588
+					),
589
+					'publishbox' => esc_html__('Update Actions', 'event_espresso'),
590
+				),
591
+				'nav'           => array(
592
+					'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
593
+					'order'      => 5,
594
+					'persistent' => false,
595
+					'url'        => '',
596
+				),
597
+				'metaboxes'     => array('_publish_post_box', '_register_edit_meta_boxes'),
598
+				'has_metaboxes' => true,
599
+				'help_tour'     => array('Message_Templates_Edit_Help_Tour'),
600
+				'help_tabs'     => array(
601
+					'edit_message_template'            => array(
602
+						'title'    => esc_html__('Message Template Editor', 'event_espresso'),
603
+						'callback' => 'edit_message_template_help_tab',
604
+					),
605
+					'message_templates_help_tab'       => array(
606
+						'title'    => esc_html__('Message Templates', 'event_espresso'),
607
+						'filename' => 'messages_templates',
608
+					),
609
+					'message_template_shortcodes'      => array(
610
+						'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
611
+						'callback' => 'message_template_shortcodes_help_tab',
612
+					),
613
+					'message_preview_help_tab'         => array(
614
+						'title'    => esc_html__('Message Preview', 'event_espresso'),
615
+						'filename' => 'messages_preview',
616
+					),
617
+					'messages_overview_other_help_tab' => array(
618
+						'title'    => esc_html__('Messages Other', 'event_espresso'),
619
+						'filename' => 'messages_overview_other',
620
+					),
621
+				),
622
+				'require_nonce' => false,
623
+			),
624
+			'display_preview_message'  => array(
625
+				'nav'           => array(
626
+					'label'      => esc_html__('Message Preview', 'event_espresso'),
627
+					'order'      => 5,
628
+					'url'        => '',
629
+					'persistent' => false,
630
+				),
631
+				'help_tabs'     => array(
632
+					'preview_message' => array(
633
+						'title'    => esc_html__('About Previews', 'event_espresso'),
634
+						'callback' => 'preview_message_help_tab',
635
+					),
636
+				),
637
+				'require_nonce' => false,
638
+			),
639
+			'settings'                 => array(
640
+				'nav'           => array(
641
+					'label' => esc_html__('Settings', 'event_espresso'),
642
+					'order' => 40,
643
+				),
644
+				'metaboxes'     => array('_messages_settings_metaboxes'),
645
+				'help_tabs'     => array(
646
+					'messages_settings_help_tab'               => array(
647
+						'title'    => esc_html__('Messages Settings', 'event_espresso'),
648
+						'filename' => 'messages_settings',
649
+					),
650
+					'messages_settings_message_types_help_tab' => array(
651
+						'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
652
+						'filename' => 'messages_settings_message_types',
653
+					),
654
+					'messages_settings_messengers_help_tab'    => array(
655
+						'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
656
+						'filename' => 'messages_settings_messengers',
657
+					),
658
+				),
659
+				'help_tour'     => array('Messages_Settings_Help_Tour'),
660
+				'require_nonce' => false,
661
+			),
662
+		);
663
+	}
664
+
665
+
666
+	protected function _add_screen_options()
667
+	{
668
+		// todo
669
+	}
670
+
671
+
672
+	protected function _add_screen_options_global_mtps()
673
+	{
674
+		/**
675
+		 * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
676
+		 * uses the $_admin_page_title property and we want different outputs in the different spots.
677
+		 */
678
+		$page_title = $this->_admin_page_title;
679
+		$this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
680
+		$this->_per_page_screen_option();
681
+		$this->_admin_page_title = $page_title;
682
+	}
683
+
684
+
685
+	protected function _add_screen_options_default()
686
+	{
687
+		$this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
688
+		$this->_per_page_screen_option();
689
+	}
690
+
691
+
692
+	// none of the below group are currently used for Messages
693
+	protected function _add_feature_pointers()
694
+	{
695
+	}
696
+
697
+	public function admin_init()
698
+	{
699
+	}
700
+
701
+	public function admin_notices()
702
+	{
703
+	}
704
+
705
+	public function admin_footer_scripts()
706
+	{
707
+	}
708
+
709
+
710
+	public function messages_help_tab()
711
+	{
712
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
713
+	}
714
+
715
+
716
+	public function messengers_help_tab()
717
+	{
718
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
719
+	}
720
+
721
+
722
+	public function message_types_help_tab()
723
+	{
724
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
725
+	}
726
+
727
+
728
+	public function messages_overview_help_tab()
729
+	{
730
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
731
+	}
732
+
733
+
734
+	public function message_templates_help_tab()
735
+	{
736
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
737
+	}
738
+
739
+
740
+	public function edit_message_template_help_tab()
741
+	{
742
+		$args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
743
+						. esc_attr__('Editor Title', 'event_espresso')
744
+						. '" />';
745
+		$args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
746
+						. esc_attr__('Context Switcher and Preview', 'event_espresso')
747
+						. '" />';
748
+		$args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
749
+						. esc_attr__('Message Template Form Fields', 'event_espresso')
750
+						. '" />';
751
+		$args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
752
+						. esc_attr__('Shortcodes Metabox', 'event_espresso')
753
+						. '" />';
754
+		$args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
755
+						. esc_attr__('Publish Metabox', 'event_espresso')
756
+						. '" />';
757
+		EEH_Template::display_template(
758
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
759
+			$args
760
+		);
761
+	}
762
+
763
+
764
+	public function message_template_shortcodes_help_tab()
765
+	{
766
+		$this->_set_shortcodes();
767
+		$args['shortcodes'] = $this->_shortcodes;
768
+		EEH_Template::display_template(
769
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
770
+			$args
771
+		);
772
+	}
773
+
774
+
775
+	public function preview_message_help_tab()
776
+	{
777
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
778
+	}
779
+
780
+
781
+	public function settings_help_tab()
782
+	{
783
+		$args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
784
+						. '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
785
+		$args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
786
+						. '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
787
+		$args['img3'] = '<div class="switch">'
788
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
789
+						. ' type="checkbox" checked="checked">'
790
+						. '<label for="ee-on-off-toggle-on"></label>'
791
+						. '</div>';
792
+		$args['img4'] = '<div class="switch">'
793
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
794
+						. ' type="checkbox">'
795
+						. '<label for="ee-on-off-toggle-on"></label>'
796
+						. '</div>';
797
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
798
+	}
799
+
800
+
801
+	public function load_scripts_styles()
802
+	{
803
+		wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
804
+		wp_enqueue_style('espresso_ee_msg');
805
+
806
+		wp_register_script(
807
+			'ee-messages-settings',
808
+			EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
809
+			array('jquery-ui-droppable', 'ee-serialize-full-array'),
810
+			EVENT_ESPRESSO_VERSION,
811
+			true
812
+		);
813
+		wp_register_script(
814
+			'ee-msg-list-table-js',
815
+			EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
816
+			array('ee-dialog'),
817
+			EVENT_ESPRESSO_VERSION
818
+		);
819
+	}
820
+
821
+
822
+	public function load_scripts_styles_default()
823
+	{
824
+		wp_enqueue_script('ee-msg-list-table-js');
825
+	}
826
+
827
+
828
+	public function wp_editor_css($mce_css)
829
+	{
830
+		// if we're on the edit_message_template route
831
+		if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
832
+			$message_type_name = $this->_active_message_type_name;
833
+
834
+			// we're going to REPLACE the existing mce css
835
+			// we need to get the css file location from the active messenger
836
+			$mce_css = $this->_active_messenger->get_variation(
837
+				$this->_template_pack,
838
+				$message_type_name,
839
+				true,
840
+				'wpeditor',
841
+				$this->_variation
842
+			);
843
+		}
844
+
845
+		return $mce_css;
846
+	}
847
+
848
+
849
+	public function load_scripts_styles_edit_message_template()
850
+	{
851
+
852
+		$this->_set_shortcodes();
853
+
854
+		EE_Registry::$i18n_js_strings['confirm_default_reset'] = sprintf(
855
+			esc_html__(
856
+				'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.',
857
+				'event_espresso'
858
+			),
859
+			$this->_message_template_group->messenger_obj()->label['singular'],
860
+			$this->_message_template_group->message_type_obj()->label['singular']
861
+		);
862
+		EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
863
+			'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?',
864
+			'event_espresso'
865
+		);
866
+		EE_Registry::$i18n_js_strings['server_error'] = esc_html__(
867
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
868
+			'event_espresso'
869
+		);
870
+
871
+		wp_register_script(
872
+			'ee_msgs_edit_js',
873
+			EE_MSG_ASSETS_URL . 'ee_message_editor.js',
874
+			array('jquery'),
875
+			EVENT_ESPRESSO_VERSION
876
+		);
877
+
878
+		wp_enqueue_script('ee_admin_js');
879
+		wp_enqueue_script('ee_msgs_edit_js');
880
+
881
+		// add in special css for tiny_mce
882
+		add_filter('mce_css', array($this, 'wp_editor_css'));
883
+	}
884
+
885
+
886
+	public function load_scripts_styles_display_preview_message()
887
+	{
888
+
889
+		$this->_set_message_template_group();
890
+
891
+		if (isset($this->_req_data['messenger'])) {
892
+			$this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
893
+				$this->_req_data['messenger']
894
+			);
895
+		}
896
+
897
+		$message_type_name = isset($this->_req_data['message_type']) ? $this->_req_data['message_type'] : '';
898
+
899
+
900
+		wp_enqueue_style(
901
+			'espresso_preview_css',
902
+			$this->_active_messenger->get_variation(
903
+				$this->_template_pack,
904
+				$message_type_name,
905
+				true,
906
+				'preview',
907
+				$this->_variation
908
+			)
909
+		);
910
+	}
911
+
912
+
913
+	public function load_scripts_styles_settings()
914
+	{
915
+		wp_register_style(
916
+			'ee-message-settings',
917
+			EE_MSG_ASSETS_URL . 'ee_message_settings.css',
918
+			array(),
919
+			EVENT_ESPRESSO_VERSION
920
+		);
921
+		wp_enqueue_style('ee-text-links');
922
+		wp_enqueue_style('ee-message-settings');
923
+		wp_enqueue_script('ee-messages-settings');
924
+	}
925
+
926
+
927
+	/**
928
+	 * set views array for List Table
929
+	 */
930
+	public function _set_list_table_views_global_mtps()
931
+	{
932
+		$this->_views = array(
933
+			'in_use' => array(
934
+				'slug'  => 'in_use',
935
+				'label' => esc_html__('In Use', 'event_espresso'),
936
+				'count' => 0,
937
+			),
938
+		);
939
+	}
940
+
941
+
942
+	/**
943
+	 * Set views array for the Custom Template List Table
944
+	 */
945
+	public function _set_list_table_views_custom_mtps()
946
+	{
947
+		$this->_set_list_table_views_global_mtps();
948
+		$this->_views['in_use']['bulk_action'] = array(
949
+			'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
950
+		);
951
+	}
952
+
953
+
954
+	/**
955
+	 * set views array for message queue list table
956
+	 *
957
+	 * @throws InvalidDataTypeException
958
+	 * @throws InvalidInterfaceException
959
+	 * @throws InvalidArgumentException
960
+	 * @throws EE_Error
961
+	 * @throws ReflectionException
962
+	 */
963
+	public function _set_list_table_views_default()
964
+	{
965
+		EE_Registry::instance()->load_helper('Template');
966
+
967
+		$common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
968
+			'ee_send_message',
969
+			'message_list_table_bulk_actions'
970
+		)
971
+			? array(
972
+				'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
973
+				'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
974
+				'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
975
+				'send_now'              => esc_html__('Send Now', 'event_espresso'),
976
+			)
977
+			: array();
978
+
979
+		$delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
980
+			'ee_delete_messages',
981
+			'message_list_table_bulk_actions'
982
+		)
983
+			? array('delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso'))
984
+			: array();
985
+
986
+
987
+		$this->_views = array(
988
+			'all' => array(
989
+				'slug'        => 'all',
990
+				'label'       => esc_html__('All', 'event_espresso'),
991
+				'count'       => 0,
992
+				'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
993
+			),
994
+		);
995
+
996
+
997
+		foreach (EEM_Message::instance()->all_statuses() as $status) {
998
+			if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
999
+				continue;
1000
+			}
1001
+			$status_bulk_actions = $common_bulk_actions;
1002
+			// unset bulk actions not applying to status
1003
+			if (! empty($status_bulk_actions)) {
1004
+				switch ($status) {
1005
+					case EEM_Message::status_idle:
1006
+					case EEM_Message::status_resend:
1007
+						$status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1008
+						break;
1009
+
1010
+					case EEM_Message::status_failed:
1011
+					case EEM_Message::status_debug_only:
1012
+					case EEM_Message::status_messenger_executing:
1013
+						$status_bulk_actions = array();
1014
+						break;
1015
+
1016
+					case EEM_Message::status_incomplete:
1017
+						unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1018
+						break;
1019
+
1020
+					case EEM_Message::status_retry:
1021
+					case EEM_Message::status_sent:
1022
+						unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1023
+						break;
1024
+				}
1025
+			}
1026
+
1027
+			// skip adding messenger executing status to views because it will be included with the Failed view.
1028
+			if ($status === EEM_Message::status_messenger_executing) {
1029
+				continue;
1030
+			}
1031
+
1032
+			$this->_views[ strtolower($status) ] = array(
1033
+				'slug'        => strtolower($status),
1034
+				'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1035
+				'count'       => 0,
1036
+				'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1037
+			);
1038
+		}
1039
+	}
1040
+
1041
+
1042
+	protected function _ee_default_messages_overview_list_table()
1043
+	{
1044
+		$this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1045
+		$this->display_admin_list_table_page_with_no_sidebar();
1046
+	}
1047
+
1048
+
1049
+	protected function _message_queue_list_table()
1050
+	{
1051
+		$this->_search_btn_label = esc_html__('Message Activity', 'event_espresso');
1052
+		$this->_template_args['per_column'] = 6;
1053
+		$this->_template_args['after_list_table'] = $this->_display_legend($this->_message_legend_items());
1054
+		$this->_template_args['before_list_table'] = '<h3>'
1055
+													 . EEM_Message::instance()->get_pretty_label_for_results()
1056
+													 . '</h3>';
1057
+		$this->display_admin_list_table_page_with_no_sidebar();
1058
+	}
1059
+
1060
+
1061
+	protected function _message_legend_items()
1062
+	{
1063
+
1064
+		$action_css_classes = EEH_MSG_Template::get_message_action_icons();
1065
+		$action_items = array();
1066
+
1067
+		foreach ($action_css_classes as $action_item => $action_details) {
1068
+			if ($action_item === 'see_notifications_for') {
1069
+				continue;
1070
+			}
1071
+			$action_items[ $action_item ] = array(
1072
+				'class' => $action_details['css_class'],
1073
+				'desc'  => $action_details['label'],
1074
+			);
1075
+		}
1076
+
1077
+		/** @type array $status_items status legend setup */
1078
+		$status_items = array(
1079
+			'incomplete_status'          => array(
1080
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1081
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1082
+			),
1083
+			'idle_status'                => array(
1084
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1085
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1086
+			),
1087
+			'resend_status'              => array(
1088
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1089
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1090
+			),
1091
+			'messenger_executing_status' => array(
1092
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1093
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1094
+			),
1095
+			'sent_status'                => array(
1096
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1097
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1098
+			),
1099
+			'retry_status'               => array(
1100
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1101
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1102
+			),
1103
+			'failed_status'              => array(
1104
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1105
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1106
+			),
1107
+		);
1108
+		if (EEM_Message::debug()) {
1109
+			$status_items['debug_only_status'] = array(
1110
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1111
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1112
+			);
1113
+		}
1114
+
1115
+		return array_merge($action_items, $status_items);
1116
+	}
1117
+
1118
+
1119
+	protected function _custom_mtps_preview()
1120
+	{
1121
+		$this->_admin_page_title = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1122
+		$this->_template_args['preview_img'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1123
+											   . ' alt="' . esc_attr__(
1124
+												   'Preview Custom Message Templates screenshot',
1125
+												   'event_espresso'
1126
+											   ) . '" />';
1127
+		$this->_template_args['preview_text'] = '<strong>'
1128
+												. esc_html__(
1129
+													'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.',
1130
+													'event_espresso'
1131
+												)
1132
+												. '</strong>';
1133
+
1134
+		$this->display_admin_caf_preview_page('custom_message_types', false);
1135
+	}
1136
+
1137
+
1138
+	/**
1139
+	 * get_message_templates
1140
+	 * This gets all the message templates for listing on the overview list.
1141
+	 *
1142
+	 * @access public
1143
+	 * @param int    $perpage the amount of templates groups to show per page
1144
+	 * @param string $type    the current _view we're getting templates for
1145
+	 * @param bool   $count   return count?
1146
+	 * @param bool   $all     disregard any paging info (get all data);
1147
+	 * @param bool   $global  whether to return just global (true) or custom templates (false)
1148
+	 * @return array
1149
+	 * @throws EE_Error
1150
+	 * @throws InvalidArgumentException
1151
+	 * @throws InvalidDataTypeException
1152
+	 * @throws InvalidInterfaceException
1153
+	 */
1154
+	public function get_message_templates(
1155
+		$perpage = 10,
1156
+		$type = 'in_use',
1157
+		$count = false,
1158
+		$all = false,
1159
+		$global = true
1160
+	) {
1161
+
1162
+		$MTP = EEM_Message_Template_Group::instance();
1163
+
1164
+		$this->_req_data['orderby'] = empty($this->_req_data['orderby']) ? 'GRP_ID' : $this->_req_data['orderby'];
1165
+		$orderby = $this->_req_data['orderby'];
1166
+
1167
+		$order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1168
+			? $this->_req_data['order']
1169
+			: 'ASC';
1170
+
1171
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1172
+			? $this->_req_data['paged']
1173
+			: 1;
1174
+		$per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1175
+			? $this->_req_data['perpage']
1176
+			: $perpage;
1177
+
1178
+		$offset = ($current_page - 1) * $per_page;
1179
+		$limit = $all ? null : array($offset, $per_page);
1180
+
1181
+
1182
+		// options will match what is in the _views array property
1183
+		switch ($type) {
1184
+			case 'in_use':
1185
+				$templates = $MTP->get_all_active_message_templates($orderby, $order, $limit, $count, $global, true);
1186
+				break;
1187
+			default:
1188
+				$templates = $MTP->get_all_trashed_grouped_message_templates($orderby, $order, $limit, $count, $global);
1189
+		}
1190
+
1191
+		return $templates;
1192
+	}
1193
+
1194
+
1195
+	/**
1196
+	 * filters etc might need a list of installed message_types
1197
+	 *
1198
+	 * @return array an array of message type objects
1199
+	 */
1200
+	public function get_installed_message_types()
1201
+	{
1202
+		$installed_message_types = $this->_message_resource_manager->installed_message_types();
1203
+		$installed = array();
1204
+
1205
+		foreach ($installed_message_types as $message_type) {
1206
+			$installed[ $message_type->name ] = $message_type;
1207
+		}
1208
+
1209
+		return $installed;
1210
+	}
1211
+
1212
+
1213
+	/**
1214
+	 * _add_message_template
1215
+	 *
1216
+	 * This is used when creating a custom template. All Custom Templates start based off another template.
1217
+	 *
1218
+	 * @param string $message_type
1219
+	 * @param string $messenger
1220
+	 * @param string $GRP_ID
1221
+	 *
1222
+	 * @throws EE_error
1223
+	 */
1224
+	protected function _add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1225
+	{
1226
+		// set values override any request data
1227
+		$message_type = ! empty($message_type) ? $message_type : '';
1228
+		$message_type = empty($message_type) && ! empty($this->_req_data['message_type'])
1229
+			? $this->_req_data['message_type']
1230
+			: $message_type;
1231
+
1232
+		$messenger = ! empty($messenger) ? $messenger : '';
1233
+		$messenger = empty($messenger) && ! empty($this->_req_data['messenger'])
1234
+			? $this->_req_data['messenger']
1235
+			: $messenger;
1236
+
1237
+		$GRP_ID = ! empty($GRP_ID) ? $GRP_ID : '';
1238
+		$GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : $GRP_ID;
1239
+
1240
+		// we need messenger and message type.  They should be coming from the event editor. If not here then return error
1241
+		if (empty($message_type) || empty($messenger)) {
1242
+			throw new EE_Error(
1243
+				esc_html__(
1244
+					'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1245
+					'event_espresso'
1246
+				)
1247
+			);
1248
+		}
1249
+
1250
+		// we need the GRP_ID for the template being used as the base for the new template
1251
+		if (empty($GRP_ID)) {
1252
+			throw new EE_Error(
1253
+				esc_html__(
1254
+					'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1255
+					'event_espresso'
1256
+				)
1257
+			);
1258
+		}
1259
+
1260
+		// let's just make sure the template gets generated!
1261
+
1262
+		// we need to reassign some variables for what the insert is expecting
1263
+		$this->_req_data['MTP_messenger'] = $messenger;
1264
+		$this->_req_data['MTP_message_type'] = $message_type;
1265
+		$this->_req_data['GRP_ID'] = $GRP_ID;
1266
+		$this->_insert_or_update_message_template(true);
1267
+	}
1268
+
1269
+
1270
+	/**
1271
+	 * public wrapper for the _add_message_template method
1272
+	 *
1273
+	 * @param string $message_type     message type slug
1274
+	 * @param string $messenger        messenger slug
1275
+	 * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1276
+	 *                                 off of.
1277
+	 * @throws EE_error
1278
+	 */
1279
+	public function add_message_template($message_type, $messenger, $GRP_ID)
1280
+	{
1281
+		$this->_add_message_template($message_type, $messenger, $GRP_ID);
1282
+	}
1283
+
1284
+
1285
+	/**
1286
+	 * _edit_message_template
1287
+	 *
1288
+	 * @access protected
1289
+	 * @return void
1290
+	 * @throws InvalidIdentifierException
1291
+	 * @throws DomainException
1292
+	 * @throws EE_Error
1293
+	 * @throws InvalidArgumentException
1294
+	 * @throws ReflectionException
1295
+	 * @throws InvalidDataTypeException
1296
+	 * @throws InvalidInterfaceException
1297
+	 */
1298
+	protected function _edit_message_template()
1299
+	{
1300
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1301
+		$template_fields = '';
1302
+		$sidebar_fields = '';
1303
+		// we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1304
+		// valid html in the templates.
1305
+		add_filter('tiny_mce_before_init', array($this, 'filter_tinymce_init'), 10, 2);
1306
+
1307
+		$GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
1308
+			? absint($this->_req_data['id'])
1309
+			: false;
1310
+
1311
+		$EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
1312
+		? absint($this->_req_data['evt_id'])
1313
+		: false;
1314
+
1315
+		$this->_set_shortcodes(); // this also sets the _message_template property.
1316
+		$message_template_group = $this->_message_template_group;
1317
+		$c_label = $message_template_group->context_label();
1318
+		$c_config = $message_template_group->contexts_config();
1319
+
1320
+		reset($c_config);
1321
+		$context = isset($this->_req_data['context']) && ! empty($this->_req_data['context'])
1322
+			? strtolower($this->_req_data['context'])
1323
+			: key($c_config);
1324
+
1325
+
1326
+		if (empty($GRP_ID)) {
1327
+			$action = 'insert_message_template';
1328
+			$edit_message_template_form_url = add_query_arg(
1329
+				array('action' => $action, 'noheader' => true),
1330
+				EE_MSG_ADMIN_URL
1331
+			);
1332
+		} else {
1333
+			$action = 'update_message_template';
1334
+			$edit_message_template_form_url = add_query_arg(
1335
+				array('action' => $action, 'noheader' => true),
1336
+				EE_MSG_ADMIN_URL
1337
+			);
1338
+		}
1339
+
1340
+		// set active messenger for this view
1341
+		$this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
1342
+			$message_template_group->messenger()
1343
+		);
1344
+		$this->_active_message_type_name = $message_template_group->message_type();
1345
+
1346
+
1347
+		// Do we have any validation errors?
1348
+		$validators = $this->_get_transient();
1349
+		$v_fields = ! empty($validators) ? array_keys($validators) : array();
1350
+
1351
+
1352
+		// we need to assemble the title from Various details
1353
+		$context_label = sprintf(
1354
+			esc_html__('(%s %s)', 'event_espresso'),
1355
+			$c_config[ $context ]['label'],
1356
+			ucwords($c_label['label'])
1357
+		);
1358
+
1359
+		$title = sprintf(
1360
+			esc_html__(' %s %s Template %s', 'event_espresso'),
1361
+			ucwords($message_template_group->messenger_obj()->label['singular']),
1362
+			ucwords($message_template_group->message_type_obj()->label['singular']),
1363
+			$context_label
1364
+		);
1365
+
1366
+		$this->_template_args['GRP_ID'] = $GRP_ID;
1367
+		$this->_template_args['message_template'] = $message_template_group;
1368
+		$this->_template_args['is_extra_fields'] = false;
1369
+
1370
+
1371
+		// let's get EEH_MSG_Template so we can get template form fields
1372
+		$template_field_structure = EEH_MSG_Template::get_fields(
1373
+			$message_template_group->messenger(),
1374
+			$message_template_group->message_type()
1375
+		);
1376
+
1377
+		if (! $template_field_structure) {
1378
+			$template_field_structure = false;
1379
+			$template_fields = esc_html__(
1380
+				'There was an error in assembling the fields for this display (you should see an error message)',
1381
+				'event_espresso'
1382
+			);
1383
+		}
1384
+
1385
+
1386
+		$message_templates = $message_template_group->context_templates();
1387
+
1388
+
1389
+		// if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1390
+		// will get handled in the "extra" array.
1391
+		if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1392
+			foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1393
+				unset($template_field_structure[ $context ][ $reference_field ]);
1394
+			}
1395
+		}
1396
+
1397
+		// let's loop through the template_field_structure and actually assemble the input fields!
1398
+		if (! empty($template_field_structure)) {
1399
+			foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1400
+				// if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1401
+				// the extra array and reset them.
1402
+				if ($template_field === 'extra') {
1403
+					$this->_template_args['is_extra_fields'] = true;
1404
+					foreach ($field_setup_array as $reference_field => $new_fields_array) {
1405
+						$message_template = $message_templates[ $context ][ $reference_field ];
1406
+						$content = $message_template instanceof EE_Message_Template
1407
+							? $message_template->get('MTP_content')
1408
+							: '';
1409
+						foreach ($new_fields_array as $extra_field => $extra_array) {
1410
+							// let's verify if we need this extra field via the shortcodes parameter.
1411
+							$continue = false;
1412
+							if (isset($extra_array['shortcodes_required'])) {
1413
+								foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1414
+									if (! array_key_exists($shortcode, $this->_shortcodes)) {
1415
+										$continue = true;
1416
+									}
1417
+								}
1418
+								if ($continue) {
1419
+									continue;
1420
+								}
1421
+							}
1422
+
1423
+							$field_id = $reference_field
1424
+										. '-'
1425
+										. $extra_field
1426
+										. '-content';
1427
+							$template_form_fields[ $field_id ] = $extra_array;
1428
+							$template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1429
+																		 . $reference_field
1430
+																		 . '][content]['
1431
+																		 . $extra_field . ']';
1432
+							$css_class = isset($extra_array['css_class'])
1433
+								? $extra_array['css_class']
1434
+								: '';
1435
+
1436
+							$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1437
+																			  && in_array($extra_field, $v_fields, true)
1438
+																			  &&
1439
+																			  (
1440
+																				  is_array($validators[ $extra_field ])
1441
+																				  && isset($validators[ $extra_field ]['msg'])
1442
+																			  )
1443
+								? 'validate-error ' . $css_class
1444
+								: $css_class;
1445
+
1446
+							$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1447
+																		  && isset($content[ $extra_field ])
1448
+								? $content[ $extra_field ]
1449
+								: '';
1450
+
1451
+							// do we have a validation error?  if we do then let's use that value instead
1452
+							$template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1453
+								? $validators[ $extra_field ]['value']
1454
+								: $template_form_fields[ $field_id ]['value'];
1455
+
1456
+
1457
+							$template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1458
+
1459
+							// shortcode selector
1460
+							$field_name_to_use = $extra_field === 'main'
1461
+								? 'content'
1462
+								: $extra_field;
1463
+							$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1464
+								$field_name_to_use,
1465
+								$field_id
1466
+							);
1467
+
1468
+							if (isset($extra_array['input']) && $extra_array['input'] === 'wp_editor') {
1469
+								// we want to decode the entities
1470
+								$template_form_fields[ $field_id ]['value'] = $template_form_fields[ $field_id ]['value'];
1471
+							}/**/
1472
+						}
1473
+						$templatefield_MTP_id = $reference_field . '-MTP_ID';
1474
+						$templatefield_templatename_id = $reference_field . '-name';
1475
+
1476
+						$template_form_fields[ $templatefield_MTP_id ] = array(
1477
+							'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1478
+							'label'      => null,
1479
+							'input'      => 'hidden',
1480
+							'type'       => 'int',
1481
+							'required'   => false,
1482
+							'validation' => false,
1483
+							'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1484
+							'css_class'  => '',
1485
+							'format'     => '%d',
1486
+							'db-col'     => 'MTP_ID',
1487
+						);
1488
+
1489
+						$template_form_fields[ $templatefield_templatename_id ] = array(
1490
+							'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1491
+							'label'      => null,
1492
+							'input'      => 'hidden',
1493
+							'type'       => 'string',
1494
+							'required'   => false,
1495
+							'validation' => true,
1496
+							'value'      => $reference_field,
1497
+							'css_class'  => '',
1498
+							'format'     => '%s',
1499
+							'db-col'     => 'MTP_template_field',
1500
+						);
1501
+					}
1502
+					continue; // skip the next stuff, we got the necessary fields here for this dataset.
1503
+				} else {
1504
+					$field_id = $template_field . '-content';
1505
+					$template_form_fields[ $field_id ] = $field_setup_array;
1506
+					$template_form_fields[ $field_id ]['name'] = 'MTP_template_fields[' . $template_field . '][content]';
1507
+					$message_template = isset($message_templates[ $context ][ $template_field ])
1508
+						? $message_templates[ $context ][ $template_field ]
1509
+						: null;
1510
+					$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1511
+																  && is_array($message_templates[ $context ])
1512
+																  && $message_template instanceof EE_Message_Template
1513
+						? $message_template->get('MTP_content')
1514
+						: '';
1515
+
1516
+					// do we have a validator error for this field?  if we do then we'll use that value instead
1517
+					$template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1518
+						? $validators[ $template_field ]['value']
1519
+						: $template_form_fields[ $field_id ]['value'];
1520
+
1521
+
1522
+					$template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1523
+					$css_class = isset($field_setup_array['css_class'])
1524
+						? $field_setup_array['css_class']
1525
+						: '';
1526
+					$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1527
+																	  && in_array($template_field, $v_fields, true)
1528
+																	  && isset($validators[ $template_field ]['msg'])
1529
+						? 'validate-error ' . $css_class
1530
+						: $css_class;
1531
+
1532
+					// shortcode selector
1533
+					$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1534
+						$template_field,
1535
+						$field_id
1536
+					);
1537
+				}
1538
+
1539
+				// k took care of content field(s) now let's take care of others.
1540
+
1541
+				$templatefield_MTP_id = $template_field . '-MTP_ID';
1542
+				$templatefield_field_templatename_id = $template_field . '-name';
1543
+
1544
+				// foreach template field there are actually two form fields created
1545
+				$template_form_fields[ $templatefield_MTP_id ] = array(
1546
+					'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1547
+					'label'      => null,
1548
+					'input'      => 'hidden',
1549
+					'type'       => 'int',
1550
+					'required'   => false,
1551
+					'validation' => true,
1552
+					'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1553
+					'css_class'  => '',
1554
+					'format'     => '%d',
1555
+					'db-col'     => 'MTP_ID',
1556
+				);
1557
+
1558
+				$template_form_fields[ $templatefield_field_templatename_id ] = array(
1559
+					'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1560
+					'label'      => null,
1561
+					'input'      => 'hidden',
1562
+					'type'       => 'string',
1563
+					'required'   => false,
1564
+					'validation' => true,
1565
+					'value'      => $template_field,
1566
+					'css_class'  => '',
1567
+					'format'     => '%s',
1568
+					'db-col'     => 'MTP_template_field',
1569
+				);
1570
+			}
1571
+
1572
+			// add other fields
1573
+			$template_form_fields['ee-msg-current-context'] = array(
1574
+				'name'       => 'MTP_context',
1575
+				'label'      => null,
1576
+				'input'      => 'hidden',
1577
+				'type'       => 'string',
1578
+				'required'   => false,
1579
+				'validation' => true,
1580
+				'value'      => $context,
1581
+				'css_class'  => '',
1582
+				'format'     => '%s',
1583
+				'db-col'     => 'MTP_context',
1584
+			);
1585
+
1586
+			$template_form_fields['ee-msg-grp-id'] = array(
1587
+				'name'       => 'GRP_ID',
1588
+				'label'      => null,
1589
+				'input'      => 'hidden',
1590
+				'type'       => 'int',
1591
+				'required'   => false,
1592
+				'validation' => true,
1593
+				'value'      => $GRP_ID,
1594
+				'css_class'  => '',
1595
+				'format'     => '%d',
1596
+				'db-col'     => 'GRP_ID',
1597
+			);
1598
+
1599
+			$template_form_fields['ee-msg-messenger'] = array(
1600
+				'name'       => 'MTP_messenger',
1601
+				'label'      => null,
1602
+				'input'      => 'hidden',
1603
+				'type'       => 'string',
1604
+				'required'   => false,
1605
+				'validation' => true,
1606
+				'value'      => $message_template_group->messenger(),
1607
+				'css_class'  => '',
1608
+				'format'     => '%s',
1609
+				'db-col'     => 'MTP_messenger',
1610
+			);
1611
+
1612
+			$template_form_fields['ee-msg-message-type'] = array(
1613
+				'name'       => 'MTP_message_type',
1614
+				'label'      => null,
1615
+				'input'      => 'hidden',
1616
+				'type'       => 'string',
1617
+				'required'   => false,
1618
+				'validation' => true,
1619
+				'value'      => $message_template_group->message_type(),
1620
+				'css_class'  => '',
1621
+				'format'     => '%s',
1622
+				'db-col'     => 'MTP_message_type',
1623
+			);
1624
+
1625
+			$sidebar_form_fields['ee-msg-is-global'] = array(
1626
+				'name'       => 'MTP_is_global',
1627
+				'label'      => esc_html__('Global Template', 'event_espresso'),
1628
+				'input'      => 'hidden',
1629
+				'type'       => 'int',
1630
+				'required'   => false,
1631
+				'validation' => true,
1632
+				'value'      => $message_template_group->get('MTP_is_global'),
1633
+				'css_class'  => '',
1634
+				'format'     => '%d',
1635
+				'db-col'     => 'MTP_is_global',
1636
+			);
1637
+
1638
+			$sidebar_form_fields['ee-msg-is-override'] = array(
1639
+				'name'       => 'MTP_is_override',
1640
+				'label'      => esc_html__('Override all custom', 'event_espresso'),
1641
+				'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1642
+				'type'       => 'int',
1643
+				'required'   => false,
1644
+				'validation' => true,
1645
+				'value'      => $message_template_group->get('MTP_is_override'),
1646
+				'css_class'  => '',
1647
+				'format'     => '%d',
1648
+				'db-col'     => 'MTP_is_override',
1649
+			);
1650
+
1651
+			$sidebar_form_fields['ee-msg-is-active'] = array(
1652
+				'name'       => 'MTP_is_active',
1653
+				'label'      => esc_html__('Active Template', 'event_espresso'),
1654
+				'input'      => 'hidden',
1655
+				'type'       => 'int',
1656
+				'required'   => false,
1657
+				'validation' => true,
1658
+				'value'      => $message_template_group->is_active(),
1659
+				'css_class'  => '',
1660
+				'format'     => '%d',
1661
+				'db-col'     => 'MTP_is_active',
1662
+			);
1663
+
1664
+			$sidebar_form_fields['ee-msg-deleted'] = array(
1665
+				'name'       => 'MTP_deleted',
1666
+				'label'      => null,
1667
+				'input'      => 'hidden',
1668
+				'type'       => 'int',
1669
+				'required'   => false,
1670
+				'validation' => true,
1671
+				'value'      => $message_template_group->get('MTP_deleted'),
1672
+				'css_class'  => '',
1673
+				'format'     => '%d',
1674
+				'db-col'     => 'MTP_deleted',
1675
+			);
1676
+			$sidebar_form_fields['ee-msg-author'] = array(
1677
+				'name'       => 'MTP_user_id',
1678
+				'label'      => esc_html__('Author', 'event_espresso'),
1679
+				'input'      => 'hidden',
1680
+				'type'       => 'int',
1681
+				'required'   => false,
1682
+				'validation' => false,
1683
+				'value'      => $message_template_group->user(),
1684
+				'format'     => '%d',
1685
+				'db-col'     => 'MTP_user_id',
1686
+			);
1687
+
1688
+			$sidebar_form_fields['ee-msg-route'] = array(
1689
+				'name'  => 'action',
1690
+				'input' => 'hidden',
1691
+				'type'  => 'string',
1692
+				'value' => $action,
1693
+			);
1694
+
1695
+			$sidebar_form_fields['ee-msg-id'] = array(
1696
+				'name'  => 'id',
1697
+				'input' => 'hidden',
1698
+				'type'  => 'int',
1699
+				'value' => $GRP_ID,
1700
+			);
1701
+			$sidebar_form_fields['ee-msg-evt-nonce'] = array(
1702
+				'name'  => $action . '_nonce',
1703
+				'input' => 'hidden',
1704
+				'type'  => 'string',
1705
+				'value' => wp_create_nonce($action . '_nonce'),
1706
+			);
1707
+
1708
+			if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
1709
+				$sidebar_form_fields['ee-msg-template-switch'] = array(
1710
+					'name'  => 'template_switch',
1711
+					'input' => 'hidden',
1712
+					'type'  => 'int',
1713
+					'value' => 1,
1714
+				);
1715
+			}
1716
+
1717
+
1718
+			$template_fields = $this->_generate_admin_form_fields($template_form_fields);
1719
+			$sidebar_fields = $this->_generate_admin_form_fields($sidebar_form_fields);
1720
+		} //end if ( !empty($template_field_structure) )
1721
+
1722
+		// set extra content for publish box
1723
+		$this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1724
+		$this->_set_publish_post_box_vars(
1725
+			'id',
1726
+			$GRP_ID,
1727
+			false,
1728
+			add_query_arg(
1729
+				array('action' => 'global_mtps'),
1730
+				$this->_admin_base_url
1731
+			)
1732
+		);
1733
+
1734
+		// add preview button
1735
+		$preview_url = parent::add_query_args_and_nonce(
1736
+			array(
1737
+				'message_type' => $message_template_group->message_type(),
1738
+				'messenger'    => $message_template_group->messenger(),
1739
+				'context'      => $context,
1740
+				'GRP_ID'       => $GRP_ID,
1741
+				'evt_id'       => $EVT_ID,
1742
+				'action'       => 'preview_message',
1743
+			),
1744
+			$this->_admin_base_url
1745
+		);
1746
+		$preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1747
+						  . esc_html__('Preview', 'event_espresso')
1748
+						  . '</a>';
1749
+
1750
+
1751
+		// setup context switcher
1752
+		$context_switcher_args = array(
1753
+			'page'    => 'espresso_messages',
1754
+			'action'  => 'edit_message_template',
1755
+			'id'      => $GRP_ID,
1756
+			'evt_id'  => $EVT_ID,
1757
+			'context' => $context,
1758
+			'extra'   => $preview_button,
1759
+		);
1760
+		$this->_set_context_switcher($message_template_group, $context_switcher_args);
1761
+
1762
+
1763
+		// main box
1764
+		$this->_template_args['template_fields'] = $template_fields;
1765
+		$this->_template_args['sidebar_box_id'] = 'details';
1766
+		$this->_template_args['action'] = $action;
1767
+		$this->_template_args['context'] = $context;
1768
+		$this->_template_args['edit_message_template_form_url'] = $edit_message_template_form_url;
1769
+		$this->_template_args['learn_more_about_message_templates_link'] =
1770
+			$this->_learn_more_about_message_templates_link();
1771
+
1772
+
1773
+		$this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1774
+		$this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1775
+			$message_template_group,
1776
+			$context,
1777
+			$context_label
1778
+		);
1779
+		$this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1780
+		$this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1781
+
1782
+		$this->_template_path = $this->_template_args['GRP_ID']
1783
+			? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1784
+			: EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1785
+
1786
+		// send along EE_Message_Template_Group object for further template use.
1787
+		$this->_template_args['MTP'] = $message_template_group;
1788
+
1789
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1790
+			$this->_template_path,
1791
+			$this->_template_args,
1792
+			true
1793
+		);
1794
+
1795
+
1796
+		// finally, let's set the admin_page title
1797
+		$this->_admin_page_title = sprintf(__('Editing %s', 'event_espresso'), $title);
1798
+
1799
+
1800
+		// we need to take care of setting the shortcodes property for use elsewhere.
1801
+		$this->_set_shortcodes();
1802
+
1803
+
1804
+		// final template wrapper
1805
+		$this->display_admin_page_with_sidebar();
1806
+	}
1807
+
1808
+
1809
+	public function filter_tinymce_init($mceInit, $editor_id)
1810
+	{
1811
+		return $mceInit;
1812
+	}
1813
+
1814
+
1815
+	public function add_context_switcher()
1816
+	{
1817
+		return $this->_context_switcher;
1818
+	}
1819
+
1820
+
1821
+	/**
1822
+	 * Adds the activation/deactivation toggle for the message template context.
1823
+	 *
1824
+	 * @param EE_Message_Template_Group $message_template_group
1825
+	 * @param string                    $context
1826
+	 * @param string                    $context_label
1827
+	 * @return string
1828
+	 * @throws DomainException
1829
+	 * @throws EE_Error
1830
+	 * @throws InvalidIdentifierException
1831
+	 */
1832
+	protected function add_active_context_element(
1833
+		EE_Message_Template_Group $message_template_group,
1834
+		$context,
1835
+		$context_label
1836
+	) {
1837
+		$template_args = array(
1838
+			'context'                   => $context,
1839
+			'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1840
+			'is_active'                 => $message_template_group->is_context_active($context),
1841
+			'on_off_action'             => $message_template_group->is_context_active($context)
1842
+				? 'context-off'
1843
+				: 'context-on',
1844
+			'context_label'             => str_replace(array('(', ')'), '', $context_label),
1845
+			'message_template_group_id' => $message_template_group->ID(),
1846
+		);
1847
+		return EEH_Template::display_template(
1848
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1849
+			$template_args,
1850
+			true
1851
+		);
1852
+	}
1853
+
1854
+
1855
+	/**
1856
+	 * Ajax callback for `toggle_context_template` ajax action.
1857
+	 * Handles toggling the message context on or off.
1858
+	 *
1859
+	 * @throws EE_Error
1860
+	 * @throws InvalidArgumentException
1861
+	 * @throws InvalidDataTypeException
1862
+	 * @throws InvalidIdentifierException
1863
+	 * @throws InvalidInterfaceException
1864
+	 */
1865
+	public function toggle_context_template()
1866
+	{
1867
+		$success = true;
1868
+		// check for required data
1869
+		if (! isset(
1870
+			$this->_req_data['message_template_group_id'],
1871
+			$this->_req_data['context'],
1872
+			$this->_req_data['status']
1873
+		)) {
1874
+			EE_Error::add_error(
1875
+				esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1876
+				__FILE__,
1877
+				__FUNCTION__,
1878
+				__LINE__
1879
+			);
1880
+			$success = false;
1881
+		}
1882
+
1883
+		$nonce = isset($this->_req_data['toggle_context_nonce'])
1884
+			? sanitize_text_field($this->_req_data['toggle_context_nonce'])
1885
+			: '';
1886
+		$nonce_ref = 'activate_' . $this->_req_data['context'] . '_toggle_nonce';
1887
+		$this->_verify_nonce($nonce, $nonce_ref);
1888
+		$status = $this->_req_data['status'];
1889
+		if ($status !== 'off' && $status !== 'on') {
1890
+			EE_Error::add_error(
1891
+				sprintf(
1892
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1893
+					$this->_req_data['status']
1894
+				),
1895
+				__FILE__,
1896
+				__FUNCTION__,
1897
+				__LINE__
1898
+			);
1899
+			$success = false;
1900
+		}
1901
+		$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID(
1902
+			$this->_req_data['message_template_group_id']
1903
+		);
1904
+		if (! $message_template_group instanceof EE_Message_Template_Group) {
1905
+			EE_Error::add_error(
1906
+				sprintf(
1907
+					esc_html__(
1908
+						'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1909
+						'event_espresso'
1910
+					),
1911
+					$this->_req_data['message_template_group_id'],
1912
+					'EE_Message_Template_Group'
1913
+				),
1914
+				__FILE__,
1915
+				__FUNCTION__,
1916
+				__LINE__
1917
+			);
1918
+			$success = false;
1919
+		}
1920
+		if ($success) {
1921
+			$success = $status === 'off'
1922
+				? $message_template_group->deactivate_context($this->_req_data['context'])
1923
+				: $message_template_group->activate_context($this->_req_data['context']);
1924
+		}
1925
+		$this->_template_args['success'] = $success;
1926
+		$this->_return_json();
1927
+	}
1928
+
1929
+
1930
+	public function _add_form_element_before()
1931
+	{
1932
+		return '<form method="post" action="'
1933
+			   . $this->_template_args["edit_message_template_form_url"]
1934
+			   . '" id="ee-msg-edit-frm">';
1935
+	}
1936
+
1937
+	public function _add_form_element_after()
1938
+	{
1939
+		return '</form>';
1940
+	}
1941
+
1942
+
1943
+	/**
1944
+	 * This executes switching the template pack for a message template.
1945
+	 *
1946
+	 * @since 4.5.0
1947
+	 * @throws EE_Error
1948
+	 * @throws InvalidDataTypeException
1949
+	 * @throws InvalidInterfaceException
1950
+	 * @throws InvalidArgumentException
1951
+	 * @throws ReflectionException
1952
+	 */
1953
+	public function switch_template_pack()
1954
+	{
1955
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
1956
+		$template_pack = ! empty($this->_req_data['template_pack']) ? $this->_req_data['template_pack'] : '';
1957
+
1958
+		// verify we have needed values.
1959
+		if (empty($GRP_ID) || empty($template_pack)) {
1960
+			$this->_template_args['error'] = true;
1961
+			EE_Error::add_error(
1962
+				esc_html__('The required date for switching templates is not available.', 'event_espresso'),
1963
+				__FILE__,
1964
+				__FUNCTION__,
1965
+				__LINE__
1966
+			);
1967
+		} else {
1968
+			// get template, set the new template_pack and then reset to default
1969
+			/** @type EE_Message_Template_Group $message_template_group */
1970
+			$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
1971
+
1972
+			$message_template_group->set_template_pack_name($template_pack);
1973
+			$this->_req_data['msgr'] = $message_template_group->messenger();
1974
+			$this->_req_data['mt'] = $message_template_group->message_type();
1975
+
1976
+			$query_args = $this->_reset_to_default_template();
1977
+
1978
+			if (empty($query_args['id'])) {
1979
+				EE_Error::add_error(
1980
+					esc_html__(
1981
+						'Something went wrong with switching the template pack. Please try again or contact EE support',
1982
+						'event_espresso'
1983
+					),
1984
+					__FILE__,
1985
+					__FUNCTION__,
1986
+					__LINE__
1987
+				);
1988
+				$this->_template_args['error'] = true;
1989
+			} else {
1990
+				$template_label = $message_template_group->get_template_pack()->label;
1991
+				$template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
1992
+				EE_Error::add_success(
1993
+					sprintf(
1994
+						esc_html__(
1995
+							'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
1996
+							'event_espresso'
1997
+						),
1998
+						$template_label,
1999
+						$template_pack_labels->template_pack
2000
+					)
2001
+				);
2002
+				// generate the redirect url for js.
2003
+				$url = self::add_query_args_and_nonce(
2004
+					$query_args,
2005
+					$this->_admin_base_url
2006
+				);
2007
+				$this->_template_args['data']['redirect_url'] = $url;
2008
+				$this->_template_args['success'] = true;
2009
+			}
2010
+
2011
+			$this->_return_json();
2012
+		}
2013
+	}
2014
+
2015
+
2016
+	/**
2017
+	 * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2018
+	 * they want.
2019
+	 *
2020
+	 * @access protected
2021
+	 * @return array|null
2022
+	 * @throws EE_Error
2023
+	 * @throws InvalidArgumentException
2024
+	 * @throws InvalidDataTypeException
2025
+	 * @throws InvalidInterfaceException
2026
+	 */
2027
+	protected function _reset_to_default_template()
2028
+	{
2029
+
2030
+		$templates = array();
2031
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2032
+		// we need to make sure we've got the info we need.
2033
+		if (! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2034
+			EE_Error::add_error(
2035
+				esc_html__(
2036
+					'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.',
2037
+					'event_espresso'
2038
+				),
2039
+				__FILE__,
2040
+				__FUNCTION__,
2041
+				__LINE__
2042
+			);
2043
+		}
2044
+
2045
+		// all templates will be reset to whatever the defaults are
2046
+		// for the global template matching the messenger and message type.
2047
+		$success = ! empty($GRP_ID) ? true : false;
2048
+
2049
+		if ($success) {
2050
+			// let's first determine if the incoming template is a global template,
2051
+			// if it isn't then we need to get the global template matching messenger and message type.
2052
+			// $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $GRP_ID );
2053
+
2054
+
2055
+			// note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2056
+			$success = $this->_delete_mtp_permanently($GRP_ID, false);
2057
+
2058
+			if ($success) {
2059
+				// if successfully deleted, lets generate the new ones.
2060
+				// Note. We set GLOBAL to true, because resets on ANY template
2061
+				// will use the related global template defaults for regeneration.
2062
+				// This means that if a custom template is reset it resets to whatever the related global template is.
2063
+				// HOWEVER, we DO keep the template pack and template variation set
2064
+				// for the current custom template when resetting.
2065
+				$templates = $this->_generate_new_templates(
2066
+					$this->_req_data['msgr'],
2067
+					$this->_req_data['mt'],
2068
+					$GRP_ID,
2069
+					true
2070
+				);
2071
+			}
2072
+		}
2073
+
2074
+		// any error messages?
2075
+		if (! $success) {
2076
+			EE_Error::add_error(
2077
+				esc_html__(
2078
+					'Something went wrong with deleting existing templates. Unable to reset to default',
2079
+					'event_espresso'
2080
+				),
2081
+				__FILE__,
2082
+				__FUNCTION__,
2083
+				__LINE__
2084
+			);
2085
+		}
2086
+
2087
+		// all good, let's add a success message!
2088
+		if ($success && ! empty($templates)) {
2089
+			// the info for the template we generated is the first element in the returned array
2090
+			// $templates = $templates[0];
2091
+			EE_Error::overwrite_success();
2092
+			EE_Error::add_success(__('Templates have been reset to defaults.', 'event_espresso'));
2093
+		}
2094
+
2095
+
2096
+		$query_args = array(
2097
+			'id'      => isset($templates[0]['GRP_ID']) ? $templates[0]['GRP_ID'] : null,
2098
+			'context' => isset($templates[0]['MTP_context']) ? $templates[0]['MTP_context'] : null,
2099
+			'action'  => isset($templates[0]['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2100
+		);
2101
+
2102
+		// if called via ajax then we return query args otherwise redirect
2103
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2104
+			return $query_args;
2105
+		} else {
2106
+			$this->_redirect_after_action(false, '', '', $query_args, true);
2107
+
2108
+			return null;
2109
+		}
2110
+	}
2111
+
2112
+
2113
+	/**
2114
+	 * Retrieve and set the message preview for display.
2115
+	 *
2116
+	 * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2117
+	 * @return string
2118
+	 * @throws ReflectionException
2119
+	 * @throws EE_Error
2120
+	 * @throws InvalidArgumentException
2121
+	 * @throws InvalidDataTypeException
2122
+	 * @throws InvalidInterfaceException
2123
+	 */
2124
+	public function _preview_message($send = false)
2125
+	{
2126
+		// first make sure we've got the necessary parameters
2127
+		if (! isset(
2128
+			$this->_req_data['message_type'],
2129
+			$this->_req_data['messenger'],
2130
+			$this->_req_data['messenger'],
2131
+			$this->_req_data['GRP_ID']
2132
+		)) {
2133
+			EE_Error::add_error(
2134
+				esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2135
+				__FILE__,
2136
+				__FUNCTION__,
2137
+				__LINE__
2138
+			);
2139
+		}
2140
+
2141
+		EE_Registry::instance()->REQ->set('GRP_ID', $this->_req_data['GRP_ID']);
2142 2142
         
2143
-        // if we have an evt_id set on the request, use it.
2144
-        $EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
2145
-        ? absint($this->_req_data['evt_id'])
2146
-        : false;
2147
-
2148
-
2149
-        // get the preview!
2150
-        $preview = EED_Messages::preview_message(
2151
-            $this->_req_data['message_type'],
2152
-            $this->_req_data['context'],
2153
-            $this->_req_data['messenger'],
2154
-            $send
2155
-        );
2156
-
2157
-        if ($send) {
2158
-            return $preview;
2159
-        }
2160
-
2161
-        // let's add a button to go back to the edit view
2162
-        $query_args = array(
2163
-            'id'      => $this->_req_data['GRP_ID'],
2164
-            'evt_id'  => $EVT_ID,
2165
-            'context' => $this->_req_data['context'],
2166
-            'action'  => 'edit_message_template',
2167
-        );
2168
-        $go_back_url = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2169
-        $preview_button = '<a href="'
2170
-                          . $go_back_url
2171
-                          . '" class="button-secondary messages-preview-go-back-button">'
2172
-                          . esc_html__('Go Back to Edit', 'event_espresso')
2173
-                          . '</a>';
2174
-        $message_types = $this->get_installed_message_types();
2175
-        $active_messenger = $this->_message_resource_manager->get_active_messenger(
2176
-            $this->_req_data['messenger']
2177
-        );
2178
-        $active_messenger_label = $active_messenger instanceof EE_messenger
2179
-            ? ucwords($active_messenger->label['singular'])
2180
-            : esc_html__('Unknown Messenger', 'event_espresso');
2181
-        // let's provide a helpful title for context
2182
-        $preview_title = sprintf(
2183
-            esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2184
-            $active_messenger_label,
2185
-            ucwords($message_types[ $this->_req_data['message_type'] ]->label['singular'])
2186
-        );
2187
-        if (empty($preview)) {
2188
-            $this->noEventsErrorMessage();
2189
-        }
2190
-        // setup display of preview.
2191
-        $this->_admin_page_title = $preview_title;
2192
-        $this->_template_args['admin_page_title'] = $preview_title;
2193
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2194
-        $this->_template_args['data']['force_json'] = true;
2195
-
2196
-        return '';
2197
-    }
2198
-
2199
-
2200
-    /**
2201
-     * Used to set an error if there are no events available for generating a preview/test send.
2202
-     *
2203
-     * @param bool $test_send  Whether the error should be generated for the context of a test send.
2204
-     */
2205
-    protected function noEventsErrorMessage($test_send = false)
2206
-    {
2207
-        $events_url = parent::add_query_args_and_nonce(
2208
-            array(
2209
-                'action' => 'default',
2210
-                'page'   => 'espresso_events',
2211
-            ),
2212
-            admin_url('admin.php')
2213
-        );
2214
-        $message = $test_send
2215
-            ? __(
2216
-                'A test message could not be sent for this message template because there are no events created yet. The preview system uses actual events for generating the test message. %1$sGo see your events%2$s!',
2217
-                'event_espresso'
2218
-            )
2219
-            : __(
2220
-                'There is no preview for this message template available because there are no events created yet. The preview system uses actual events for generating the preview. %1$sGo see your events%2$s!',
2221
-                'event_espresso'
2222
-            );
2223
-
2224
-        EE_Error::add_attention(
2225
-            sprintf(
2226
-                $message,
2227
-                "<a href='{$events_url}'>",
2228
-                '</a>'
2229
-            )
2230
-        );
2231
-    }
2232
-
2233
-
2234
-    /**
2235
-     * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2236
-     * gets called automatically.
2237
-     *
2238
-     * @since 4.5.0
2239
-     *
2240
-     * @return string
2241
-     */
2242
-    protected function _display_preview_message()
2243
-    {
2244
-        $this->display_admin_page_with_no_sidebar();
2245
-    }
2246
-
2247
-
2248
-    /**
2249
-     * registers metaboxes that should show up on the "edit_message_template" page
2250
-     *
2251
-     * @access protected
2252
-     * @return void
2253
-     */
2254
-    protected function _register_edit_meta_boxes()
2255
-    {
2256
-        add_meta_box(
2257
-            'mtp_valid_shortcodes',
2258
-            esc_html__('Valid Shortcodes', 'event_espresso'),
2259
-            array($this, 'shortcode_meta_box'),
2260
-            $this->_current_screen->id,
2261
-            'side',
2262
-            'default'
2263
-        );
2264
-        add_meta_box(
2265
-            'mtp_extra_actions',
2266
-            esc_html__('Extra Actions', 'event_espresso'),
2267
-            array($this, 'extra_actions_meta_box'),
2268
-            $this->_current_screen->id,
2269
-            'side',
2270
-            'high'
2271
-        );
2272
-        add_meta_box(
2273
-            'mtp_templates',
2274
-            esc_html__('Template Styles', 'event_espresso'),
2275
-            array($this, 'template_pack_meta_box'),
2276
-            $this->_current_screen->id,
2277
-            'side',
2278
-            'high'
2279
-        );
2280
-    }
2281
-
2282
-
2283
-    /**
2284
-     * metabox content for all template pack and variation selection.
2285
-     *
2286
-     * @since 4.5.0
2287
-     * @return string
2288
-     * @throws DomainException
2289
-     * @throws EE_Error
2290
-     * @throws InvalidArgumentException
2291
-     * @throws ReflectionException
2292
-     * @throws InvalidDataTypeException
2293
-     * @throws InvalidInterfaceException
2294
-     */
2295
-    public function template_pack_meta_box()
2296
-    {
2297
-        $this->_set_message_template_group();
2298
-
2299
-        $tp_collection = EEH_MSG_Template::get_template_pack_collection();
2300
-
2301
-        $tp_select_values = array();
2302
-
2303
-        foreach ($tp_collection as $tp) {
2304
-            // only include template packs that support this messenger and message type!
2305
-            $supports = $tp->get_supports();
2306
-            if (! isset($supports[ $this->_message_template_group->messenger() ])
2307
-                || ! in_array(
2308
-                    $this->_message_template_group->message_type(),
2309
-                    $supports[ $this->_message_template_group->messenger() ],
2310
-                    true
2311
-                )
2312
-            ) {
2313
-                // not supported
2314
-                continue;
2315
-            }
2316
-
2317
-            $tp_select_values[] = array(
2318
-                'text' => $tp->label,
2319
-                'id'   => $tp->dbref,
2320
-            );
2321
-        }
2322
-
2323
-        // if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2324
-        // the default template pack.  This still allows for the odd template pack to override.
2325
-        if (empty($tp_select_values)) {
2326
-            $tp_select_values[] = array(
2327
-                'text' => esc_html__('Default', 'event_espresso'),
2328
-                'id'   => 'default',
2329
-            );
2330
-        }
2331
-
2332
-        // setup variation select values for the currently selected template.
2333
-        $variations = $this->_message_template_group->get_template_pack()->get_variations(
2334
-            $this->_message_template_group->messenger(),
2335
-            $this->_message_template_group->message_type()
2336
-        );
2337
-        $variations_select_values = array();
2338
-        foreach ($variations as $variation => $label) {
2339
-            $variations_select_values[] = array(
2340
-                'text' => $label,
2341
-                'id'   => $variation,
2342
-            );
2343
-        }
2344
-
2345
-        $template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2346
-
2347
-        $template_args['template_packs_selector'] = EEH_Form_Fields::select_input(
2348
-            'MTP_template_pack',
2349
-            $tp_select_values,
2350
-            $this->_message_template_group->get_template_pack_name()
2351
-        );
2352
-        $template_args['variations_selector'] = EEH_Form_Fields::select_input(
2353
-            'MTP_template_variation',
2354
-            $variations_select_values,
2355
-            $this->_message_template_group->get_template_pack_variation()
2356
-        );
2357
-        $template_args['template_pack_label'] = $template_pack_labels->template_pack;
2358
-        $template_args['template_variation_label'] = $template_pack_labels->template_variation;
2359
-        $template_args['template_pack_description'] = $template_pack_labels->template_pack_description;
2360
-        $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2361
-
2362
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2363
-
2364
-        EEH_Template::display_template($template, $template_args);
2365
-    }
2366
-
2367
-
2368
-    /**
2369
-     * This meta box holds any extra actions related to Message Templates
2370
-     * For now, this includes Resetting templates to defaults and sending a test email.
2371
-     *
2372
-     * @access  public
2373
-     * @return void
2374
-     * @throws EE_Error
2375
-     */
2376
-    public function extra_actions_meta_box()
2377
-    {
2378
-        $template_form_fields = array();
2379
-
2380
-        $extra_args = array(
2381
-            'msgr'   => $this->_message_template_group->messenger(),
2382
-            'mt'     => $this->_message_template_group->message_type(),
2383
-            'GRP_ID' => $this->_message_template_group->GRP_ID(),
2384
-        );
2385
-        // first we need to see if there are any fields
2386
-        $fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2387
-
2388
-        if (! empty($fields)) {
2389
-            // yup there be fields
2390
-            foreach ($fields as $field => $config) {
2391
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2392
-                $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2393
-                $default = isset($config['default']) ? $config['default'] : '';
2394
-                $default = isset($config['value']) ? $config['value'] : $default;
2395
-
2396
-                // if type is hidden and the value is empty
2397
-                // something may have gone wrong so let's correct with the defaults
2398
-                $fix = $config['input'] === 'hidden'
2399
-                       && isset($existing[ $field ])
2400
-                       && empty($existing[ $field ])
2401
-                    ? $default
2402
-                    : '';
2403
-                $existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2404
-                    ? $existing[ $field ]
2405
-                    : $fix;
2406
-
2407
-                $template_form_fields[ $field_id ] = array(
2408
-                    'name'       => 'test_settings_fld[' . $field . ']',
2409
-                    'label'      => $config['label'],
2410
-                    'input'      => $config['input'],
2411
-                    'type'       => $config['type'],
2412
-                    'required'   => $config['required'],
2413
-                    'validation' => $config['validation'],
2414
-                    'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2415
-                    'css_class'  => $config['css_class'],
2416
-                    'options'    => isset($config['options']) ? $config['options'] : array(),
2417
-                    'default'    => $default,
2418
-                    'format'     => $config['format'],
2419
-                );
2420
-            }
2421
-        }
2422
-
2423
-        $test_settings_fields = ! empty($template_form_fields)
2424
-            ? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2425
-            : '';
2426
-
2427
-        $test_settings_html = '';
2428
-        // print out $test_settings_fields
2429
-        if (! empty($test_settings_fields)) {
2430
-            echo $test_settings_fields;
2431
-            $test_settings_html = '<input type="submit" class="button-primary mtp-test-button alignright" ';
2432
-            $test_settings_html .= 'name="test_button" value="';
2433
-            $test_settings_html .= esc_html__('Test Send', 'event_espresso');
2434
-            $test_settings_html .= '" /><div style="clear:both"></div>';
2435
-        }
2436
-
2437
-        // and button
2438
-        $test_settings_html .= '<p>'
2439
-                               . esc_html__('Need to reset this message type and start over?', 'event_espresso')
2440
-                               . '</p>';
2441
-        $test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2442
-        $test_settings_html .= $this->get_action_link_or_button(
2443
-            'reset_to_default',
2444
-            'reset',
2445
-            $extra_args,
2446
-            'button-primary reset-default-button'
2447
-        );
2448
-        $test_settings_html .= '</div><div style="clear:both"></div>';
2449
-        echo $test_settings_html;
2450
-    }
2451
-
2452
-
2453
-    /**
2454
-     * This returns the shortcode selector skeleton for a given context and field.
2455
-     *
2456
-     * @since 4.9.rc.000
2457
-     * @param string $field           The name of the field retrieving shortcodes for.
2458
-     * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2459
-     * @return string
2460
-     * @throws DomainException
2461
-     * @throws EE_Error
2462
-     * @throws InvalidArgumentException
2463
-     * @throws ReflectionException
2464
-     * @throws InvalidDataTypeException
2465
-     * @throws InvalidInterfaceException
2466
-     */
2467
-    protected function _get_shortcode_selector($field, $linked_input_id)
2468
-    {
2469
-        $template_args = array(
2470
-            'shortcodes'      => $this->_get_shortcodes(array($field), true),
2471
-            'fieldname'       => $field,
2472
-            'linked_input_id' => $linked_input_id,
2473
-        );
2474
-
2475
-        return EEH_Template::display_template(
2476
-            EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2477
-            $template_args,
2478
-            true
2479
-        );
2480
-    }
2481
-
2482
-
2483
-    /**
2484
-     * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2485
-     * page)
2486
-     *
2487
-     * @access public
2488
-     * @return void
2489
-     * @throws EE_Error
2490
-     * @throws InvalidArgumentException
2491
-     * @throws ReflectionException
2492
-     * @throws InvalidDataTypeException
2493
-     * @throws InvalidInterfaceException
2494
-     */
2495
-    public function shortcode_meta_box()
2496
-    {
2497
-        $shortcodes = $this->_get_shortcodes(array(), false); // just make sure shortcodes property is set
2498
-        // $messenger = $this->_message_template_group->messenger_obj();
2499
-        // now let's set the content depending on the status of the shortcodes array
2500
-        if (empty($shortcodes)) {
2501
-            $content = '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2502
-            echo $content;
2503
-        } else {
2504
-            // $alt = 0;
2505
-            ?>
2143
+		// if we have an evt_id set on the request, use it.
2144
+		$EVT_ID = isset($this->_req_data['evt_id']) && ! empty($this->_req_data['evt_id'])
2145
+		? absint($this->_req_data['evt_id'])
2146
+		: false;
2147
+
2148
+
2149
+		// get the preview!
2150
+		$preview = EED_Messages::preview_message(
2151
+			$this->_req_data['message_type'],
2152
+			$this->_req_data['context'],
2153
+			$this->_req_data['messenger'],
2154
+			$send
2155
+		);
2156
+
2157
+		if ($send) {
2158
+			return $preview;
2159
+		}
2160
+
2161
+		// let's add a button to go back to the edit view
2162
+		$query_args = array(
2163
+			'id'      => $this->_req_data['GRP_ID'],
2164
+			'evt_id'  => $EVT_ID,
2165
+			'context' => $this->_req_data['context'],
2166
+			'action'  => 'edit_message_template',
2167
+		);
2168
+		$go_back_url = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2169
+		$preview_button = '<a href="'
2170
+						  . $go_back_url
2171
+						  . '" class="button-secondary messages-preview-go-back-button">'
2172
+						  . esc_html__('Go Back to Edit', 'event_espresso')
2173
+						  . '</a>';
2174
+		$message_types = $this->get_installed_message_types();
2175
+		$active_messenger = $this->_message_resource_manager->get_active_messenger(
2176
+			$this->_req_data['messenger']
2177
+		);
2178
+		$active_messenger_label = $active_messenger instanceof EE_messenger
2179
+			? ucwords($active_messenger->label['singular'])
2180
+			: esc_html__('Unknown Messenger', 'event_espresso');
2181
+		// let's provide a helpful title for context
2182
+		$preview_title = sprintf(
2183
+			esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2184
+			$active_messenger_label,
2185
+			ucwords($message_types[ $this->_req_data['message_type'] ]->label['singular'])
2186
+		);
2187
+		if (empty($preview)) {
2188
+			$this->noEventsErrorMessage();
2189
+		}
2190
+		// setup display of preview.
2191
+		$this->_admin_page_title = $preview_title;
2192
+		$this->_template_args['admin_page_title'] = $preview_title;
2193
+		$this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2194
+		$this->_template_args['data']['force_json'] = true;
2195
+
2196
+		return '';
2197
+	}
2198
+
2199
+
2200
+	/**
2201
+	 * Used to set an error if there are no events available for generating a preview/test send.
2202
+	 *
2203
+	 * @param bool $test_send  Whether the error should be generated for the context of a test send.
2204
+	 */
2205
+	protected function noEventsErrorMessage($test_send = false)
2206
+	{
2207
+		$events_url = parent::add_query_args_and_nonce(
2208
+			array(
2209
+				'action' => 'default',
2210
+				'page'   => 'espresso_events',
2211
+			),
2212
+			admin_url('admin.php')
2213
+		);
2214
+		$message = $test_send
2215
+			? __(
2216
+				'A test message could not be sent for this message template because there are no events created yet. The preview system uses actual events for generating the test message. %1$sGo see your events%2$s!',
2217
+				'event_espresso'
2218
+			)
2219
+			: __(
2220
+				'There is no preview for this message template available because there are no events created yet. The preview system uses actual events for generating the preview. %1$sGo see your events%2$s!',
2221
+				'event_espresso'
2222
+			);
2223
+
2224
+		EE_Error::add_attention(
2225
+			sprintf(
2226
+				$message,
2227
+				"<a href='{$events_url}'>",
2228
+				'</a>'
2229
+			)
2230
+		);
2231
+	}
2232
+
2233
+
2234
+	/**
2235
+	 * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2236
+	 * gets called automatically.
2237
+	 *
2238
+	 * @since 4.5.0
2239
+	 *
2240
+	 * @return string
2241
+	 */
2242
+	protected function _display_preview_message()
2243
+	{
2244
+		$this->display_admin_page_with_no_sidebar();
2245
+	}
2246
+
2247
+
2248
+	/**
2249
+	 * registers metaboxes that should show up on the "edit_message_template" page
2250
+	 *
2251
+	 * @access protected
2252
+	 * @return void
2253
+	 */
2254
+	protected function _register_edit_meta_boxes()
2255
+	{
2256
+		add_meta_box(
2257
+			'mtp_valid_shortcodes',
2258
+			esc_html__('Valid Shortcodes', 'event_espresso'),
2259
+			array($this, 'shortcode_meta_box'),
2260
+			$this->_current_screen->id,
2261
+			'side',
2262
+			'default'
2263
+		);
2264
+		add_meta_box(
2265
+			'mtp_extra_actions',
2266
+			esc_html__('Extra Actions', 'event_espresso'),
2267
+			array($this, 'extra_actions_meta_box'),
2268
+			$this->_current_screen->id,
2269
+			'side',
2270
+			'high'
2271
+		);
2272
+		add_meta_box(
2273
+			'mtp_templates',
2274
+			esc_html__('Template Styles', 'event_espresso'),
2275
+			array($this, 'template_pack_meta_box'),
2276
+			$this->_current_screen->id,
2277
+			'side',
2278
+			'high'
2279
+		);
2280
+	}
2281
+
2282
+
2283
+	/**
2284
+	 * metabox content for all template pack and variation selection.
2285
+	 *
2286
+	 * @since 4.5.0
2287
+	 * @return string
2288
+	 * @throws DomainException
2289
+	 * @throws EE_Error
2290
+	 * @throws InvalidArgumentException
2291
+	 * @throws ReflectionException
2292
+	 * @throws InvalidDataTypeException
2293
+	 * @throws InvalidInterfaceException
2294
+	 */
2295
+	public function template_pack_meta_box()
2296
+	{
2297
+		$this->_set_message_template_group();
2298
+
2299
+		$tp_collection = EEH_MSG_Template::get_template_pack_collection();
2300
+
2301
+		$tp_select_values = array();
2302
+
2303
+		foreach ($tp_collection as $tp) {
2304
+			// only include template packs that support this messenger and message type!
2305
+			$supports = $tp->get_supports();
2306
+			if (! isset($supports[ $this->_message_template_group->messenger() ])
2307
+				|| ! in_array(
2308
+					$this->_message_template_group->message_type(),
2309
+					$supports[ $this->_message_template_group->messenger() ],
2310
+					true
2311
+				)
2312
+			) {
2313
+				// not supported
2314
+				continue;
2315
+			}
2316
+
2317
+			$tp_select_values[] = array(
2318
+				'text' => $tp->label,
2319
+				'id'   => $tp->dbref,
2320
+			);
2321
+		}
2322
+
2323
+		// if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2324
+		// the default template pack.  This still allows for the odd template pack to override.
2325
+		if (empty($tp_select_values)) {
2326
+			$tp_select_values[] = array(
2327
+				'text' => esc_html__('Default', 'event_espresso'),
2328
+				'id'   => 'default',
2329
+			);
2330
+		}
2331
+
2332
+		// setup variation select values for the currently selected template.
2333
+		$variations = $this->_message_template_group->get_template_pack()->get_variations(
2334
+			$this->_message_template_group->messenger(),
2335
+			$this->_message_template_group->message_type()
2336
+		);
2337
+		$variations_select_values = array();
2338
+		foreach ($variations as $variation => $label) {
2339
+			$variations_select_values[] = array(
2340
+				'text' => $label,
2341
+				'id'   => $variation,
2342
+			);
2343
+		}
2344
+
2345
+		$template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2346
+
2347
+		$template_args['template_packs_selector'] = EEH_Form_Fields::select_input(
2348
+			'MTP_template_pack',
2349
+			$tp_select_values,
2350
+			$this->_message_template_group->get_template_pack_name()
2351
+		);
2352
+		$template_args['variations_selector'] = EEH_Form_Fields::select_input(
2353
+			'MTP_template_variation',
2354
+			$variations_select_values,
2355
+			$this->_message_template_group->get_template_pack_variation()
2356
+		);
2357
+		$template_args['template_pack_label'] = $template_pack_labels->template_pack;
2358
+		$template_args['template_variation_label'] = $template_pack_labels->template_variation;
2359
+		$template_args['template_pack_description'] = $template_pack_labels->template_pack_description;
2360
+		$template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2361
+
2362
+		$template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2363
+
2364
+		EEH_Template::display_template($template, $template_args);
2365
+	}
2366
+
2367
+
2368
+	/**
2369
+	 * This meta box holds any extra actions related to Message Templates
2370
+	 * For now, this includes Resetting templates to defaults and sending a test email.
2371
+	 *
2372
+	 * @access  public
2373
+	 * @return void
2374
+	 * @throws EE_Error
2375
+	 */
2376
+	public function extra_actions_meta_box()
2377
+	{
2378
+		$template_form_fields = array();
2379
+
2380
+		$extra_args = array(
2381
+			'msgr'   => $this->_message_template_group->messenger(),
2382
+			'mt'     => $this->_message_template_group->message_type(),
2383
+			'GRP_ID' => $this->_message_template_group->GRP_ID(),
2384
+		);
2385
+		// first we need to see if there are any fields
2386
+		$fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2387
+
2388
+		if (! empty($fields)) {
2389
+			// yup there be fields
2390
+			foreach ($fields as $field => $config) {
2391
+				$field_id = $this->_message_template_group->messenger() . '_' . $field;
2392
+				$existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2393
+				$default = isset($config['default']) ? $config['default'] : '';
2394
+				$default = isset($config['value']) ? $config['value'] : $default;
2395
+
2396
+				// if type is hidden and the value is empty
2397
+				// something may have gone wrong so let's correct with the defaults
2398
+				$fix = $config['input'] === 'hidden'
2399
+					   && isset($existing[ $field ])
2400
+					   && empty($existing[ $field ])
2401
+					? $default
2402
+					: '';
2403
+				$existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2404
+					? $existing[ $field ]
2405
+					: $fix;
2406
+
2407
+				$template_form_fields[ $field_id ] = array(
2408
+					'name'       => 'test_settings_fld[' . $field . ']',
2409
+					'label'      => $config['label'],
2410
+					'input'      => $config['input'],
2411
+					'type'       => $config['type'],
2412
+					'required'   => $config['required'],
2413
+					'validation' => $config['validation'],
2414
+					'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2415
+					'css_class'  => $config['css_class'],
2416
+					'options'    => isset($config['options']) ? $config['options'] : array(),
2417
+					'default'    => $default,
2418
+					'format'     => $config['format'],
2419
+				);
2420
+			}
2421
+		}
2422
+
2423
+		$test_settings_fields = ! empty($template_form_fields)
2424
+			? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2425
+			: '';
2426
+
2427
+		$test_settings_html = '';
2428
+		// print out $test_settings_fields
2429
+		if (! empty($test_settings_fields)) {
2430
+			echo $test_settings_fields;
2431
+			$test_settings_html = '<input type="submit" class="button-primary mtp-test-button alignright" ';
2432
+			$test_settings_html .= 'name="test_button" value="';
2433
+			$test_settings_html .= esc_html__('Test Send', 'event_espresso');
2434
+			$test_settings_html .= '" /><div style="clear:both"></div>';
2435
+		}
2436
+
2437
+		// and button
2438
+		$test_settings_html .= '<p>'
2439
+							   . esc_html__('Need to reset this message type and start over?', 'event_espresso')
2440
+							   . '</p>';
2441
+		$test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2442
+		$test_settings_html .= $this->get_action_link_or_button(
2443
+			'reset_to_default',
2444
+			'reset',
2445
+			$extra_args,
2446
+			'button-primary reset-default-button'
2447
+		);
2448
+		$test_settings_html .= '</div><div style="clear:both"></div>';
2449
+		echo $test_settings_html;
2450
+	}
2451
+
2452
+
2453
+	/**
2454
+	 * This returns the shortcode selector skeleton for a given context and field.
2455
+	 *
2456
+	 * @since 4.9.rc.000
2457
+	 * @param string $field           The name of the field retrieving shortcodes for.
2458
+	 * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2459
+	 * @return string
2460
+	 * @throws DomainException
2461
+	 * @throws EE_Error
2462
+	 * @throws InvalidArgumentException
2463
+	 * @throws ReflectionException
2464
+	 * @throws InvalidDataTypeException
2465
+	 * @throws InvalidInterfaceException
2466
+	 */
2467
+	protected function _get_shortcode_selector($field, $linked_input_id)
2468
+	{
2469
+		$template_args = array(
2470
+			'shortcodes'      => $this->_get_shortcodes(array($field), true),
2471
+			'fieldname'       => $field,
2472
+			'linked_input_id' => $linked_input_id,
2473
+		);
2474
+
2475
+		return EEH_Template::display_template(
2476
+			EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2477
+			$template_args,
2478
+			true
2479
+		);
2480
+	}
2481
+
2482
+
2483
+	/**
2484
+	 * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2485
+	 * page)
2486
+	 *
2487
+	 * @access public
2488
+	 * @return void
2489
+	 * @throws EE_Error
2490
+	 * @throws InvalidArgumentException
2491
+	 * @throws ReflectionException
2492
+	 * @throws InvalidDataTypeException
2493
+	 * @throws InvalidInterfaceException
2494
+	 */
2495
+	public function shortcode_meta_box()
2496
+	{
2497
+		$shortcodes = $this->_get_shortcodes(array(), false); // just make sure shortcodes property is set
2498
+		// $messenger = $this->_message_template_group->messenger_obj();
2499
+		// now let's set the content depending on the status of the shortcodes array
2500
+		if (empty($shortcodes)) {
2501
+			$content = '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2502
+			echo $content;
2503
+		} else {
2504
+			// $alt = 0;
2505
+			?>
2506 2506
             <div style="float:right; margin-top:10px"><?php
2507
-                            echo $this->_get_help_tab_link('message_template_shortcodes');
2508
-                            ?></div>
2507
+							echo $this->_get_help_tab_link('message_template_shortcodes');
2508
+							?></div>
2509 2509
             <p class="small-text"><?php
2510
-                                  printf(
2511
-                                      esc_html__(
2512
-                                          'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2513
-                                          'event_espresso'
2514
-                                      ),
2515
-                                      '<span class="dashicons dashicons-menu"></span>'
2516
-                                  );
2517
-                                ?>
2510
+								  printf(
2511
+									  esc_html__(
2512
+										  'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2513
+										  'event_espresso'
2514
+									  ),
2515
+									  '<span class="dashicons dashicons-menu"></span>'
2516
+								  );
2517
+								?>
2518 2518
             </p>
2519 2519
             <?php
2520
-        }
2521
-    }
2522
-
2523
-
2524
-    /**
2525
-     * used to set the $_shortcodes property for when its needed elsewhere.
2526
-     *
2527
-     * @access protected
2528
-     * @return void
2529
-     * @throws EE_Error
2530
-     * @throws InvalidArgumentException
2531
-     * @throws ReflectionException
2532
-     * @throws InvalidDataTypeException
2533
-     * @throws InvalidInterfaceException
2534
-     */
2535
-    protected function _set_shortcodes()
2536
-    {
2537
-
2538
-        // no need to run this if the property is already set
2539
-        if (! empty($this->_shortcodes)) {
2540
-            return;
2541
-        }
2542
-
2543
-        $this->_shortcodes = $this->_get_shortcodes();
2544
-    }
2545
-
2546
-
2547
-    /**
2548
-     * get's all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2549
-     * property)
2550
-     *
2551
-     * @access  protected
2552
-     * @param  array   $fields include an array of specific field names that you want to be used to get the shortcodes
2553
-     *                         for. Defaults to all (for the given context)
2554
-     * @param  boolean $merged Whether to merge all the shortcodes into one list of unique shortcodes
2555
-     * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2556
-     *                         true just an array of shortcode/label pairs.
2557
-     * @throws EE_Error
2558
-     * @throws InvalidArgumentException
2559
-     * @throws ReflectionException
2560
-     * @throws InvalidDataTypeException
2561
-     * @throws InvalidInterfaceException
2562
-     */
2563
-    protected function _get_shortcodes($fields = array(), $merged = true)
2564
-    {
2565
-        $this->_set_message_template_group();
2566
-
2567
-        // we need the messenger and message template to retrieve the valid shortcodes array.
2568
-        $GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
2569
-            ? absint($this->_req_data['id'])
2570
-            : false;
2571
-        $context = isset($this->_req_data['context'])
2572
-            ? $this->_req_data['context']
2573
-            : key($this->_message_template_group->contexts_config());
2574
-
2575
-        return ! empty($GRP_ID) ? $this->_message_template_group->get_shortcodes($context, $fields, $merged) : array();
2576
-    }
2577
-
2578
-
2579
-    /**
2580
-     * This sets the _message_template property (containing the called message_template object)
2581
-     *
2582
-     * @access protected
2583
-     * @return void
2584
-     * @throws EE_Error
2585
-     * @throws InvalidArgumentException
2586
-     * @throws ReflectionException
2587
-     * @throws InvalidDataTypeException
2588
-     * @throws InvalidInterfaceException
2589
-     */
2590
-    protected function _set_message_template_group()
2591
-    {
2592
-
2593
-        if (! empty($this->_message_template_group)) {
2594
-            return;
2595
-        } //get out if this is already set.
2596
-
2597
-        $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? absint($this->_req_data['GRP_ID']) : false;
2598
-        $GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['id']) ? $this->_req_data['id'] : $GRP_ID;
2599
-
2600
-        // let's get the message templates
2601
-        $MTP = EEM_Message_Template_Group::instance();
2602
-
2603
-        if (empty($GRP_ID)) {
2604
-            $this->_message_template_group = $MTP->create_default_object();
2605
-        } else {
2606
-            $this->_message_template_group = $MTP->get_one_by_ID($GRP_ID);
2607
-        }
2608
-
2609
-        $this->_template_pack = $this->_message_template_group->get_template_pack();
2610
-        $this->_variation = $this->_message_template_group->get_template_pack_variation();
2611
-    }
2612
-
2613
-
2614
-    /**
2615
-     * sets up a context switcher for edit forms
2616
-     *
2617
-     * @access  protected
2618
-     * @param  EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2619
-     * @param array                      $args                  various things the context switcher needs.
2620
-     * @throws EE_Error
2621
-     */
2622
-    protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2623
-    {
2624
-        $context_details = $template_group_object->contexts_config();
2625
-        $context_label = $template_group_object->context_label();
2626
-        ob_start();
2627
-        ?>
2520
+		}
2521
+	}
2522
+
2523
+
2524
+	/**
2525
+	 * used to set the $_shortcodes property for when its needed elsewhere.
2526
+	 *
2527
+	 * @access protected
2528
+	 * @return void
2529
+	 * @throws EE_Error
2530
+	 * @throws InvalidArgumentException
2531
+	 * @throws ReflectionException
2532
+	 * @throws InvalidDataTypeException
2533
+	 * @throws InvalidInterfaceException
2534
+	 */
2535
+	protected function _set_shortcodes()
2536
+	{
2537
+
2538
+		// no need to run this if the property is already set
2539
+		if (! empty($this->_shortcodes)) {
2540
+			return;
2541
+		}
2542
+
2543
+		$this->_shortcodes = $this->_get_shortcodes();
2544
+	}
2545
+
2546
+
2547
+	/**
2548
+	 * get's all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2549
+	 * property)
2550
+	 *
2551
+	 * @access  protected
2552
+	 * @param  array   $fields include an array of specific field names that you want to be used to get the shortcodes
2553
+	 *                         for. Defaults to all (for the given context)
2554
+	 * @param  boolean $merged Whether to merge all the shortcodes into one list of unique shortcodes
2555
+	 * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2556
+	 *                         true just an array of shortcode/label pairs.
2557
+	 * @throws EE_Error
2558
+	 * @throws InvalidArgumentException
2559
+	 * @throws ReflectionException
2560
+	 * @throws InvalidDataTypeException
2561
+	 * @throws InvalidInterfaceException
2562
+	 */
2563
+	protected function _get_shortcodes($fields = array(), $merged = true)
2564
+	{
2565
+		$this->_set_message_template_group();
2566
+
2567
+		// we need the messenger and message template to retrieve the valid shortcodes array.
2568
+		$GRP_ID = isset($this->_req_data['id']) && ! empty($this->_req_data['id'])
2569
+			? absint($this->_req_data['id'])
2570
+			: false;
2571
+		$context = isset($this->_req_data['context'])
2572
+			? $this->_req_data['context']
2573
+			: key($this->_message_template_group->contexts_config());
2574
+
2575
+		return ! empty($GRP_ID) ? $this->_message_template_group->get_shortcodes($context, $fields, $merged) : array();
2576
+	}
2577
+
2578
+
2579
+	/**
2580
+	 * This sets the _message_template property (containing the called message_template object)
2581
+	 *
2582
+	 * @access protected
2583
+	 * @return void
2584
+	 * @throws EE_Error
2585
+	 * @throws InvalidArgumentException
2586
+	 * @throws ReflectionException
2587
+	 * @throws InvalidDataTypeException
2588
+	 * @throws InvalidInterfaceException
2589
+	 */
2590
+	protected function _set_message_template_group()
2591
+	{
2592
+
2593
+		if (! empty($this->_message_template_group)) {
2594
+			return;
2595
+		} //get out if this is already set.
2596
+
2597
+		$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? absint($this->_req_data['GRP_ID']) : false;
2598
+		$GRP_ID = empty($GRP_ID) && ! empty($this->_req_data['id']) ? $this->_req_data['id'] : $GRP_ID;
2599
+
2600
+		// let's get the message templates
2601
+		$MTP = EEM_Message_Template_Group::instance();
2602
+
2603
+		if (empty($GRP_ID)) {
2604
+			$this->_message_template_group = $MTP->create_default_object();
2605
+		} else {
2606
+			$this->_message_template_group = $MTP->get_one_by_ID($GRP_ID);
2607
+		}
2608
+
2609
+		$this->_template_pack = $this->_message_template_group->get_template_pack();
2610
+		$this->_variation = $this->_message_template_group->get_template_pack_variation();
2611
+	}
2612
+
2613
+
2614
+	/**
2615
+	 * sets up a context switcher for edit forms
2616
+	 *
2617
+	 * @access  protected
2618
+	 * @param  EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2619
+	 * @param array                      $args                  various things the context switcher needs.
2620
+	 * @throws EE_Error
2621
+	 */
2622
+	protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2623
+	{
2624
+		$context_details = $template_group_object->contexts_config();
2625
+		$context_label = $template_group_object->context_label();
2626
+		ob_start();
2627
+		?>
2628 2628
         <div class="ee-msg-switcher-container">
2629 2629
             <form method="get" action="<?php echo EE_MSG_ADMIN_URL; ?>" id="ee-msg-context-switcher-frm">
2630 2630
                 <?php
2631
-                foreach ($args as $name => $value) {
2632
-                    if ($name === 'context' || empty($value) || $name === 'extra') {
2633
-                        continue;
2634
-                    }
2635
-                    ?>
2631
+				foreach ($args as $name => $value) {
2632
+					if ($name === 'context' || empty($value) || $name === 'extra') {
2633
+						continue;
2634
+					}
2635
+					?>
2636 2636
                     <input type="hidden" name="<?php echo $name; ?>" value="<?php echo $value; ?>"/>
2637 2637
                     <?php
2638
-                }
2639
-                // setup nonce_url
2640
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2641
-                ?>
2638
+				}
2639
+				// setup nonce_url
2640
+				wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2641
+				?>
2642 2642
                 <select name="context">
2643 2643
                     <?php
2644
-                    $context_templates = $template_group_object->context_templates();
2645
-                    if (is_array($context_templates)) :
2646
-                        foreach ($context_templates as $context => $template_fields) :
2647
-                            $checked = ($context === $args['context']) ? 'selected="selected"' : '';
2648
-                            ?>
2644
+					$context_templates = $template_group_object->context_templates();
2645
+					if (is_array($context_templates)) :
2646
+						foreach ($context_templates as $context => $template_fields) :
2647
+							$checked = ($context === $args['context']) ? 'selected="selected"' : '';
2648
+							?>
2649 2649
                             <option value="<?php echo $context; ?>" <?php echo $checked; ?>>
2650 2650
                                 <?php echo $context_details[ $context ]['label']; ?>
2651 2651
                             </option>
2652 2652
                         <?php endforeach;
2653
-                    endif; ?>
2653
+					endif; ?>
2654 2654
                 </select>
2655 2655
                 <?php $button_text = sprintf(__('Switch %s', 'event_espresso'), ucwords($context_label['label'])); ?>
2656 2656
                 <input id="submit-msg-context-switcher-sbmt" class="button-secondary" type="submit"
@@ -2659,1925 +2659,1925 @@  discard block
 block discarded – undo
2659 2659
             <?php echo $args['extra']; ?>
2660 2660
         </div> <!-- end .ee-msg-switcher-container -->
2661 2661
         <?php
2662
-        $output = ob_get_contents();
2663
-        ob_clean();
2664
-        $this->_context_switcher = $output;
2665
-    }
2666
-
2667
-
2668
-    /**
2669
-     * utility for sanitizing new values coming in.
2670
-     * Note: this is only used when updating a context.
2671
-     *
2672
-     * @access protected
2673
-     *
2674
-     * @param int $index This helps us know which template field to select from the request array.
2675
-     *
2676
-     * @return array
2677
-     */
2678
-    protected function _set_message_template_column_values($index)
2679
-    {
2680
-        if (is_array($this->_req_data['MTP_template_fields'][ $index ]['content'])) {
2681
-            foreach ($this->_req_data['MTP_template_fields'][ $index ]['content'] as $field => $value) {
2682
-                $this->_req_data['MTP_template_fields'][ $index ]['content'][ $field ] = $value;
2683
-            }
2684
-        }
2685
-
2686
-
2687
-        $set_column_values = array(
2688
-            'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][ $index ]['MTP_ID']),
2689
-            'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2690
-            'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2691
-            'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2692
-            'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2693
-            'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][ $index ]['name']),
2694
-            'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2695
-            'MTP_content'        => $this->_req_data['MTP_template_fields'][ $index ]['content'],
2696
-            'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2697
-                ? absint($this->_req_data['MTP_is_global'])
2698
-                : 0,
2699
-            'MTP_is_override'    => isset($this->_req_data['MTP_is_override'])
2700
-                ? absint($this->_req_data['MTP_is_override'])
2701
-                : 0,
2702
-            'MTP_deleted'        => absint($this->_req_data['MTP_deleted']),
2703
-            'MTP_is_active'      => absint($this->_req_data['MTP_is_active']),
2704
-        );
2705
-
2706
-
2707
-        return $set_column_values;
2708
-    }
2709
-
2710
-
2711
-    protected function _insert_or_update_message_template($new = false)
2712
-    {
2713
-
2714
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2715
-        $success = 0;
2716
-        $override = false;
2717
-
2718
-        // setup notices description
2719
-        $messenger_slug = ! empty($this->_req_data['MTP_messenger']) ? $this->_req_data['MTP_messenger'] : '';
2720
-
2721
-        // need the message type and messenger objects to be able to use the labels for the notices
2722
-        $messenger_object = $this->_message_resource_manager->get_messenger($messenger_slug);
2723
-        $messenger_label = $messenger_object instanceof EE_messenger
2724
-            ? ucwords($messenger_object->label['singular'])
2725
-            : '';
2726
-
2727
-        $message_type_slug = ! empty($this->_req_data['MTP_message_type'])
2728
-            ? $this->_req_data['MTP_message_type']
2729
-            : '';
2730
-        $message_type_object = $this->_message_resource_manager->get_message_type($message_type_slug);
2731
-
2732
-        $message_type_label = $message_type_object instanceof EE_message_type
2733
-            ? ucwords($message_type_object->label['singular'])
2734
-            : '';
2735
-
2736
-        $context_slug = ! empty($this->_req_data['MTP_context'])
2737
-            ? $this->_req_data['MTP_context']
2738
-            : '';
2739
-        $context = ucwords(str_replace('_', ' ', $context_slug));
2740
-
2741
-        $item_desc = $messenger_label && $message_type_label
2742
-            ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2743
-            : '';
2744
-        $item_desc .= 'Message Template';
2745
-        $query_args = array();
2746
-        $edit_array = array();
2747
-        $action_desc = '';
2748
-
2749
-        // if this is "new" then we need to generate the default contexts for the selected messenger/message_type for
2750
-        // user to edit.
2751
-        if ($new) {
2752
-            $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2753
-            if ($edit_array = $this->_generate_new_templates($messenger_slug, $message_type_slug, $GRP_ID)) {
2754
-                if (empty($edit_array)) {
2755
-                    $success = 0;
2756
-                } else {
2757
-                    $success = 1;
2758
-                    $edit_array = $edit_array[0];
2759
-                    $query_args = array(
2760
-                        'id'      => $edit_array['GRP_ID'],
2761
-                        'context' => $edit_array['MTP_context'],
2762
-                        'action'  => 'edit_message_template',
2763
-                    );
2764
-                }
2765
-            }
2766
-            $action_desc = 'created';
2767
-        } else {
2768
-            $MTPG = EEM_Message_Template_Group::instance();
2769
-            $MTP = EEM_Message_Template::instance();
2770
-
2771
-
2772
-            // run update for each template field in displayed context
2773
-            if (! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2774
-                EE_Error::add_error(
2775
-                    esc_html__(
2776
-                        'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2777
-                        'event_espresso'
2778
-                    ),
2779
-                    __FILE__,
2780
-                    __FUNCTION__,
2781
-                    __LINE__
2782
-                );
2783
-                $success = 0;
2784
-            } else {
2785
-                // first validate all fields!
2786
-                // this filter allows client code to add its own validation to the template fields as well.
2787
-                // returning an empty array means everything passed validation.
2788
-                // errors in validation should be represented in an array with the following shape:
2789
-                // array(
2790
-                //   'fieldname' => array(
2791
-                //          'msg' => 'error message'
2792
-                //          'value' => 'value for field producing error'
2793
-                // )
2794
-                $custom_validation = (array) apply_filters(
2795
-                    'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2796
-                    array(),
2797
-                    $this->_req_data['MTP_template_fields'],
2798
-                    $context_slug,
2799
-                    $messenger_slug,
2800
-                    $message_type_slug
2801
-                );
2802
-
2803
-                $system_validation = $MTPG->validate(
2804
-                    $this->_req_data['MTP_template_fields'],
2805
-                    $context_slug,
2806
-                    $messenger_slug,
2807
-                    $message_type_slug
2808
-                );
2809
-
2810
-                $system_validation = ! is_array($system_validation) && $system_validation ? array()
2811
-                    : $system_validation;
2812
-                $validates = array_merge($custom_validation, $system_validation);
2813
-
2814
-                // if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2815
-                // appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2816
-                //  WE need to make sure there is no actual error messages in validates.
2817
-                if (is_array($validates) && ! empty($validates)) {
2818
-                    // add the transient so when the form loads we know which fields to highlight
2819
-                    $this->_add_transient('edit_message_template', $validates);
2820
-
2821
-                    $success = 0;
2822
-
2823
-                    // setup notices
2824
-                    foreach ($validates as $field => $error) {
2825
-                        if (isset($error['msg'])) {
2826
-                            EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2827
-                        }
2828
-                    }
2829
-                } else {
2830
-                    $set_column_values = array();
2831
-                    foreach ($this->_req_data['MTP_template_fields'] as $template_field => $content) {
2832
-                        $set_column_values = $this->_set_message_template_column_values($template_field);
2833
-
2834
-                        $where_cols_n_values = array(
2835
-                            'MTP_ID' => $this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'],
2836
-                        );
2837
-                        // if they aren't allowed to use all JS, restrict them to just posty-y tags
2838
-                        if (! current_user_can('unfiltered_html')) {
2839
-                            if (is_array($set_column_values['MTP_content'])) {
2840
-                                foreach ($set_column_values['MTP_content'] as $key => $value) {
2841
-                                    // remove slashes so wp_kses works properly (its wp_kses_stripslashes() function
2842
-                                    // only removes slashes from double-quotes, so attributes using single quotes always
2843
-                                    // appear invalid.) But currently the models expect slashed data, so after wp_kses
2844
-                                    // runs we need to re-slash the data. Sheesh. See
2845
-                                    // https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
2846
-                                    $set_column_values['MTP_content'][ $key ] = addslashes(
2847
-                                        wp_kses(
2848
-                                            stripslashes($value),
2849
-                                            wp_kses_allowed_html('post')
2850
-                                        )
2851
-                                    );
2852
-                                }
2853
-                            } else {
2854
-                                $set_column_values['MTP_content'] = wp_kses(
2855
-                                    $set_column_values['MTP_content'],
2856
-                                    wp_kses_allowed_html('post')
2857
-                                );
2858
-                            }
2859
-                        }
2860
-                        $message_template_fields = array(
2861
-                            'GRP_ID'             => $set_column_values['GRP_ID'],
2862
-                            'MTP_template_field' => $set_column_values['MTP_template_field'],
2863
-                            'MTP_context'        => $set_column_values['MTP_context'],
2864
-                            'MTP_content'        => $set_column_values['MTP_content'],
2865
-                        );
2866
-                        if ($updated = $MTP->update($message_template_fields, array($where_cols_n_values))) {
2867
-                            if ($updated === false) {
2868
-                                EE_Error::add_error(
2869
-                                    sprintf(
2870
-                                        esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
2871
-                                        $template_field
2872
-                                    ),
2873
-                                    __FILE__,
2874
-                                    __FUNCTION__,
2875
-                                    __LINE__
2876
-                                );
2877
-                            } else {
2878
-                                $success = 1;
2879
-                            }
2880
-                        } else {
2881
-                            // only do this logic if we don't have a MTP_ID for this field
2882
-                            if (empty($this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'])) {
2883
-                                // this has already been through the template field validator and sanitized, so it will be
2884
-                                // safe to insert this field.  Why insert?  This typically happens when we introduce a new
2885
-                                // message template field in a messenger/message type and existing users don't have the
2886
-                                // default setup for it.
2887
-                                // @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2888
-                                $updated = $MTP->insert($message_template_fields);
2889
-                                if (! $updated || is_wp_error($updated)) {
2890
-                                    EE_Error::add_error(
2891
-                                        sprintf(
2892
-                                            esc_html__('%s field could not be updated.', 'event_espresso'),
2893
-                                            $template_field
2894
-                                        ),
2895
-                                        __FILE__,
2896
-                                        __FUNCTION__,
2897
-                                        __LINE__
2898
-                                    );
2899
-                                    $success = 0;
2900
-                                } else {
2901
-                                    $success = 1;
2902
-                                }
2903
-                            }
2904
-                        }
2905
-                        $action_desc = 'updated';
2906
-                    }
2907
-
2908
-                    // we can use the last set_column_values for the MTPG update (because its the same for all of these specific MTPs)
2909
-                    $mtpg_fields = array(
2910
-                        'MTP_user_id'      => $set_column_values['MTP_user_id'],
2911
-                        'MTP_messenger'    => $set_column_values['MTP_messenger'],
2912
-                        'MTP_message_type' => $set_column_values['MTP_message_type'],
2913
-                        'MTP_is_global'    => $set_column_values['MTP_is_global'],
2914
-                        'MTP_is_override'  => $set_column_values['MTP_is_override'],
2915
-                        'MTP_deleted'      => $set_column_values['MTP_deleted'],
2916
-                        'MTP_is_active'    => $set_column_values['MTP_is_active'],
2917
-                        'MTP_name'         => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_name'])
2918
-                            ? $this->_req_data['ee_msg_non_global_fields']['MTP_name']
2919
-                            : '',
2920
-                        'MTP_description'  => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_description'])
2921
-                            ? $this->_req_data['ee_msg_non_global_fields']['MTP_description']
2922
-                            : '',
2923
-                    );
2924
-
2925
-                    $mtpg_where = array('GRP_ID' => $set_column_values['GRP_ID']);
2926
-                    $updated = $MTPG->update($mtpg_fields, array($mtpg_where));
2927
-
2928
-                    if ($updated === false) {
2929
-                        EE_Error::add_error(
2930
-                            sprintf(
2931
-                                esc_html__(
2932
-                                    'The Message Template Group (%d) was NOT updated for some reason',
2933
-                                    'event_espresso'
2934
-                                ),
2935
-                                $set_column_values['GRP_ID']
2936
-                            ),
2937
-                            __FILE__,
2938
-                            __FUNCTION__,
2939
-                            __LINE__
2940
-                        );
2941
-                    } else {
2942
-                        // k now we need to ensure the template_pack and template_variation fields are set.
2943
-                        $template_pack = ! empty($this->_req_data['MTP_template_pack'])
2944
-                            ? $this->_req_data['MTP_template_pack']
2945
-                            : 'default';
2946
-
2947
-                        $template_variation = ! empty($this->_req_data['MTP_template_variation'])
2948
-                            ? $this->_req_data['MTP_template_variation']
2949
-                            : 'default';
2950
-
2951
-                        $mtpg_obj = $MTPG->get_one_by_ID($set_column_values['GRP_ID']);
2952
-                        if ($mtpg_obj instanceof EE_Message_Template_Group) {
2953
-                            $mtpg_obj->set_template_pack_name($template_pack);
2954
-                            $mtpg_obj->set_template_pack_variation($template_variation);
2955
-                        }
2956
-                        $success = 1;
2957
-                    }
2958
-                }
2959
-            }
2960
-        }
2961
-
2962
-        // we return things differently if doing ajax
2963
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2964
-            $this->_template_args['success'] = $success;
2965
-            $this->_template_args['error'] = ! $success ? true : false;
2966
-            $this->_template_args['content'] = '';
2967
-            $this->_template_args['data'] = array(
2968
-                'grpID'        => $edit_array['GRP_ID'],
2969
-                'templateName' => $edit_array['template_name'],
2970
-            );
2971
-            if ($success) {
2972
-                EE_Error::overwrite_success();
2973
-                EE_Error::add_success(
2974
-                    esc_html__(
2975
-                        '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.',
2976
-                        'event_espresso'
2977
-                    )
2978
-                );
2979
-            }
2980
-
2981
-            $this->_return_json();
2982
-        }
2983
-
2984
-
2985
-        // was a test send triggered?
2986
-        if (isset($this->_req_data['test_button'])) {
2987
-            EE_Error::overwrite_success();
2988
-            $this->_do_test_send($context_slug, $messenger_slug, $message_type_slug);
2989
-            $override = true;
2990
-        }
2991
-
2992
-        if (empty($query_args)) {
2993
-            $query_args = array(
2994
-                'id'      => $this->_req_data['GRP_ID'],
2995
-                'context' => $context_slug,
2996
-                'action'  => 'edit_message_template',
2997
-            );
2998
-        }
2999
-
3000
-        $this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
3001
-    }
3002
-
3003
-
3004
-    /**
3005
-     * processes a test send request to do an actual messenger delivery test for the given message template being tested
3006
-     *
3007
-     * @param  string $context      what context being tested
3008
-     * @param  string $messenger    messenger being tested
3009
-     * @param  string $message_type message type being tested
3010
-     * @throws EE_Error
3011
-     * @throws InvalidArgumentException
3012
-     * @throws InvalidDataTypeException
3013
-     * @throws InvalidInterfaceException
3014
-     */
3015
-    protected function _do_test_send($context, $messenger, $message_type)
3016
-    {
3017
-        // set things up for preview
3018
-        $this->_req_data['messenger'] = $messenger;
3019
-        $this->_req_data['message_type'] = $message_type;
3020
-        $this->_req_data['context'] = $context;
3021
-        $this->_req_data['GRP_ID'] = isset($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : '';
3022
-        $active_messenger = $this->_message_resource_manager->get_active_messenger($messenger);
3023
-
3024
-        // let's save any existing fields that might be required by the messenger
3025
-        if (isset($this->_req_data['test_settings_fld'])
3026
-            && $active_messenger instanceof EE_messenger
3027
-            && apply_filters(
3028
-                'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3029
-                true,
3030
-                $this->_req_data['test_settings_fld'],
3031
-                $active_messenger
3032
-            )
3033
-        ) {
3034
-            $active_messenger->set_existing_test_settings($this->_req_data['test_settings_fld']);
3035
-        }
3036
-
3037
-        /**
3038
-         * Use filter to add additional controls on whether message can send or not
3039
-         */
3040
-        if (apply_filters(
3041
-            'FHEE__Messages_Admin_Page__do_test_send__can_send',
3042
-            true,
3043
-            $context,
3044
-            $this->_req_data,
3045
-            $messenger,
3046
-            $message_type
3047
-        )) {
3048
-            if (EEM_Event::instance()->count() > 0) {
3049
-                $success = $this->_preview_message(true);
3050
-                if ($success) {
3051
-                    EE_Error::add_success(__('Test message sent', 'event_espresso'));
3052
-                } else {
3053
-                    EE_Error::add_error(
3054
-                        esc_html__('The test message was not sent', 'event_espresso'),
3055
-                        __FILE__,
3056
-                        __FUNCTION__,
3057
-                        __LINE__
3058
-                    );
3059
-                }
3060
-            } else {
3061
-                $this->noEventsErrorMessage(true);
3062
-            }
3063
-        }
3064
-    }
3065
-
3066
-
3067
-    /**
3068
-     * _generate_new_templates
3069
-     * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3070
-     * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3071
-     * for the event.
3072
-     *
3073
-     *
3074
-     * @param  string $messenger     the messenger we are generating templates for
3075
-     * @param array   $message_types array of message types that the templates are generated for.
3076
-     * @param int     $GRP_ID        If this is a custom template being generated then a GRP_ID needs to be included to
3077
-     *                               indicate the message_template_group being used as the base.
3078
-     *
3079
-     * @param bool    $global
3080
-     *
3081
-     * @return array|bool array of data required for the redirect to the correct edit page or bool if
3082
-     *                               encountering problems.
3083
-     * @throws EE_Error
3084
-     */
3085
-    protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3086
-    {
3087
-
3088
-        // if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3089
-        // just don't generate any templates.
3090
-        if (empty($message_types)) {
3091
-            return true;
3092
-        }
3093
-
3094
-        return EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3095
-    }
3096
-
3097
-
3098
-    /**
3099
-     * [_trash_or_restore_message_template]
3100
-     *
3101
-     * @param  boolean $trash whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3102
-     * @param boolean  $all   whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3103
-     *                        an individual context (FALSE).
3104
-     * @return void
3105
-     * @throws EE_Error
3106
-     * @throws InvalidArgumentException
3107
-     * @throws InvalidDataTypeException
3108
-     * @throws InvalidInterfaceException
3109
-     */
3110
-    protected function _trash_or_restore_message_template($trash = true, $all = false)
3111
-    {
3112
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3113
-        $MTP = EEM_Message_Template_Group::instance();
3114
-
3115
-        $success = 1;
3116
-
3117
-        // incoming GRP_IDs
3118
-        if ($all) {
3119
-            // Checkboxes
3120
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3121
-                // if array has more than one element then success message should be plural.
3122
-                // todo: what about nonce?
3123
-                $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3124
-
3125
-                // cycle through checkboxes
3126
-                while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3127
-                    $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3128
-                    if (! $trashed_or_restored) {
3129
-                        $success = 0;
3130
-                    }
3131
-                }
3132
-            } else {
3133
-                // grab single GRP_ID and handle
3134
-                $GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
3135
-                if (! empty($GRP_ID)) {
3136
-                    $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3137
-                    if (! $trashed_or_restored) {
3138
-                        $success = 0;
3139
-                    }
3140
-                } else {
3141
-                    $success = 0;
3142
-                }
3143
-            }
3144
-        }
3145
-
3146
-        $action_desc = $trash
3147
-            ? esc_html__('moved to the trash', 'event_espresso')
3148
-            : esc_html__('restored', 'event_espresso');
3149
-
3150
-        $action_desc = ! empty($this->_req_data['template_switch']) ? esc_html__('switched', 'event_espresso') : $action_desc;
3151
-
3152
-        $item_desc = $all ? _n(
3153
-            'Message Template Group',
3154
-            'Message Template Groups',
3155
-            $success,
3156
-            'event_espresso'
3157
-        ) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3158
-
3159
-        $item_desc = ! empty($this->_req_data['template_switch']) ? _n(
3160
-            'template',
3161
-            'templates',
3162
-            $success,
3163
-            'event_espresso'
3164
-        ) : $item_desc;
3165
-
3166
-        $this->_redirect_after_action($success, $item_desc, $action_desc, array());
3167
-    }
3168
-
3169
-
3170
-    /**
3171
-     * [_delete_message_template]
3172
-     * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3173
-     *
3174
-     * @return void
3175
-     * @throws EE_Error
3176
-     * @throws InvalidArgumentException
3177
-     * @throws InvalidDataTypeException
3178
-     * @throws InvalidInterfaceException
3179
-     */
3180
-    protected function _delete_message_template()
3181
-    {
3182
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3183
-
3184
-        // checkboxes
3185
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3186
-            // if array has more than one element then success message should be plural
3187
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3188
-
3189
-            // cycle through bulk action checkboxes
3190
-            while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3191
-                $success = $this->_delete_mtp_permanently($GRP_ID);
3192
-            }
3193
-        } else {
3194
-            // grab single grp_id and delete
3195
-            $GRP_ID = absint($this->_req_data['id']);
3196
-            $success = $this->_delete_mtp_permanently($GRP_ID);
3197
-        }
3198
-
3199
-        $this->_redirect_after_action($success, 'Message Templates', 'deleted', array());
3200
-    }
3201
-
3202
-
3203
-    /**
3204
-     * helper for permanently deleting a mtP group and all related message_templates
3205
-     *
3206
-     * @param  int  $GRP_ID        The group being deleted
3207
-     * @param  bool $include_group whether to delete the Message Template Group as well.
3208
-     * @return bool boolean to indicate the success of the deletes or not.
3209
-     * @throws EE_Error
3210
-     * @throws InvalidArgumentException
3211
-     * @throws InvalidDataTypeException
3212
-     * @throws InvalidInterfaceException
3213
-     */
3214
-    private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3215
-    {
3216
-        $success = 1;
3217
-        $MTPG = EEM_Message_Template_Group::instance();
3218
-        // first let's GET this group
3219
-        $MTG = $MTPG->get_one_by_ID($GRP_ID);
3220
-        // then delete permanently all the related Message Templates
3221
-        $deleted = $MTG->delete_related_permanently('Message_Template');
3222
-
3223
-        if ($deleted === 0) {
3224
-            $success = 0;
3225
-        }
3226
-
3227
-        // now delete permanently this particular group
3228
-
3229
-        if ($include_group && ! $MTG->delete_permanently()) {
3230
-            $success = 0;
3231
-        }
3232
-
3233
-        return $success;
3234
-    }
3235
-
3236
-
3237
-    /**
3238
-     *    _learn_more_about_message_templates_link
3239
-     *
3240
-     * @access protected
3241
-     * @return string
3242
-     */
3243
-    protected function _learn_more_about_message_templates_link()
3244
-    {
3245
-        return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3246
-               . esc_html__('learn more about how message templates works', 'event_espresso')
3247
-               . '</a>';
3248
-    }
3249
-
3250
-
3251
-    /**
3252
-     * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3253
-     * ajax and other routes.
3254
-     *
3255
-     * @return void
3256
-     * @throws DomainException
3257
-     */
3258
-    protected function _settings()
3259
-    {
3260
-
3261
-
3262
-        $this->_set_m_mt_settings();
3263
-
3264
-        $selected_messenger = isset($this->_req_data['selected_messenger'])
3265
-            ? $this->_req_data['selected_messenger']
3266
-            : 'email';
3267
-
3268
-        // let's setup the messenger tabs
3269
-        $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
3270
-            $this->_m_mt_settings['messenger_tabs'],
3271
-            'messenger_links',
3272
-            '|',
3273
-            $selected_messenger
3274
-        );
3275
-        $this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3276
-        $this->_template_args['after_admin_page_content'] = '</div><!-- end .ui-widget -->';
3277
-
3278
-        $this->display_admin_page_with_sidebar();
3279
-    }
3280
-
3281
-
3282
-    /**
3283
-     * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3284
-     *
3285
-     * @access protected
3286
-     * @return void
3287
-     * @throws DomainException
3288
-     */
3289
-    protected function _set_m_mt_settings()
3290
-    {
3291
-        // first if this is already set then lets get out no need to regenerate data.
3292
-        if (! empty($this->_m_mt_settings)) {
3293
-            return;
3294
-        }
3295
-
3296
-        // get all installed messengers and message_types
3297
-        /** @type EE_messenger[] $messengers */
3298
-        $messengers = $this->_message_resource_manager->installed_messengers();
3299
-        /** @type EE_message_type[] $message_types */
3300
-        $message_types = $this->_message_resource_manager->installed_message_types();
3301
-
3302
-
3303
-        // assemble the array for the _tab_text_links helper
3304
-
3305
-        foreach ($messengers as $messenger) {
3306
-            $this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = array(
3307
-                'label' => ucwords($messenger->label['singular']),
3308
-                'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3309
-                    ? 'messenger-active'
3310
-                    : '',
3311
-                'href'  => $messenger->name,
3312
-                'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3313
-                'slug'  => $messenger->name,
3314
-                'obj'   => $messenger,
3315
-            );
3316
-
3317
-
3318
-            $message_types_for_messenger = $messenger->get_valid_message_types();
3319
-
3320
-            foreach ($message_types as $message_type) {
3321
-                // first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3322
-                // it shouldn't show in either the inactive OR active metabox.
3323
-                if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3324
-                    continue;
3325
-                }
3326
-
3327
-                $a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3328
-                    $messenger->name,
3329
-                    $message_type->name
3330
-                )
3331
-                    ? 'active'
3332
-                    : 'inactive';
3333
-
3334
-                $this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = array(
3335
-                    'label'    => ucwords($message_type->label['singular']),
3336
-                    'class'    => 'message-type-' . $a_or_i,
3337
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3338
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3339
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3340
-                    'title'    => $a_or_i === 'active'
3341
-                        ? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3342
-                        : esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3343
-                    'content'  => $a_or_i === 'active'
3344
-                        ? $this->_message_type_settings_content($message_type, $messenger, true)
3345
-                        : $this->_message_type_settings_content($message_type, $messenger),
3346
-                    'slug'     => $message_type->name,
3347
-                    'active'   => $a_or_i === 'active',
3348
-                    'obj'      => $message_type,
3349
-                );
3350
-            }
3351
-        }
3352
-    }
3353
-
3354
-
3355
-    /**
3356
-     * This just prepares the content for the message type settings
3357
-     *
3358
-     * @param  EE_message_type $message_type The message type object
3359
-     * @param  EE_messenger    $messenger    The messenger object
3360
-     * @param  boolean         $active       Whether the message type is active or not
3361
-     * @return string html output for the content
3362
-     * @throws DomainException
3363
-     */
3364
-    protected function _message_type_settings_content($message_type, $messenger, $active = false)
3365
-    {
3366
-        // get message type fields
3367
-        $fields = $message_type->get_admin_settings_fields();
3368
-        $settings_template_args['template_form_fields'] = '';
3369
-
3370
-        if (! empty($fields) && $active) {
3371
-            $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3372
-            foreach ($fields as $fldname => $fldprops) {
3373
-                $field_id = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3374
-                $template_form_field[ $field_id ] = array(
3375
-                    'name'       => 'message_type_settings[' . $fldname . ']',
3376
-                    'label'      => $fldprops['label'],
3377
-                    'input'      => $fldprops['field_type'],
3378
-                    'type'       => $fldprops['value_type'],
3379
-                    'required'   => $fldprops['required'],
3380
-                    'validation' => $fldprops['validation'],
3381
-                    'value'      => isset($existing_settings[ $fldname ])
3382
-                        ? $existing_settings[ $fldname ]
3383
-                        : $fldprops['default'],
3384
-                    'options'    => isset($fldprops['options'])
3385
-                        ? $fldprops['options']
3386
-                        : array(),
3387
-                    'default'    => isset($existing_settings[ $fldname ])
3388
-                        ? $existing_settings[ $fldname ]
3389
-                        : $fldprops['default'],
3390
-                    'css_class'  => 'no-drag',
3391
-                    'format'     => $fldprops['format'],
3392
-                );
3393
-            }
3394
-
3395
-
3396
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3397
-                ? $this->_generate_admin_form_fields(
3398
-                    $template_form_field,
3399
-                    'string',
3400
-                    'ee_mt_activate_form'
3401
-                )
3402
-                : '';
3403
-        }
3404
-
3405
-        $settings_template_args['description'] = $message_type->description;
3406
-        // we also need some hidden fields
3407
-        $settings_template_args['hidden_fields'] = array(
3408
-            'message_type_settings[messenger]'    => array(
3409
-                'type'  => 'hidden',
3410
-                'value' => $messenger->name,
3411
-            ),
3412
-            'message_type_settings[message_type]' => array(
3413
-                'type'  => 'hidden',
3414
-                'value' => $message_type->name,
3415
-            ),
3416
-            'type'                                => array(
3417
-                'type'  => 'hidden',
3418
-                'value' => 'message_type',
3419
-            ),
3420
-        );
3421
-
3422
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3423
-            $settings_template_args['hidden_fields'],
3424
-            'array'
3425
-        );
3426
-        $settings_template_args['show_form'] = empty($settings_template_args['template_form_fields'])
3427
-            ? ' hidden'
3428
-            : '';
3429
-
3430
-
3431
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3432
-        $content = EEH_Template::display_template($template, $settings_template_args, true);
3433
-
3434
-        return $content;
3435
-    }
3436
-
3437
-
3438
-    /**
3439
-     * Generate all the metaboxes for the message types and register them for the messages settings page.
3440
-     *
3441
-     * @access protected
3442
-     * @return void
3443
-     * @throws DomainException
3444
-     */
3445
-    protected function _messages_settings_metaboxes()
3446
-    {
3447
-        $this->_set_m_mt_settings();
3448
-        $m_boxes = $mt_boxes = array();
3449
-        $m_template_args = $mt_template_args = array();
3450
-
3451
-        $selected_messenger = isset($this->_req_data['selected_messenger'])
3452
-            ? $this->_req_data['selected_messenger']
3453
-            : 'email';
3454
-
3455
-        if (isset($this->_m_mt_settings['messenger_tabs'])) {
3456
-            foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3457
-                $hide_on_message = $this->_message_resource_manager->is_messenger_active($messenger) ? '' : 'hidden';
3458
-                $hide_off_message = $this->_message_resource_manager->is_messenger_active($messenger) ? 'hidden' : '';
3459
-                // messenger meta boxes
3460
-                $active = $selected_messenger === $messenger;
3461
-                $active_mt_tabs = isset(
3462
-                    $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3463
-                )
3464
-                    ? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3465
-                    : '';
3466
-                $m_boxes[ $messenger . '_a_box' ] = sprintf(
3467
-                    esc_html__('%s Settings', 'event_espresso'),
3468
-                    $tab_array['label']
3469
-                );
3470
-                $m_template_args[ $messenger . '_a_box' ] = array(
3471
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3472
-                    'inactive_message_types' => isset(
3473
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3474
-                    )
3475
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3476
-                        : '',
3477
-                    'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3478
-                    'hidden'                 => $active ? '' : ' hidden',
3479
-                    'hide_on_message'        => $hide_on_message,
3480
-                    'messenger'              => $messenger,
3481
-                    'active'                 => $active,
3482
-                );
3483
-                // message type meta boxes
3484
-                // (which is really just the inactive container for each messenger
3485
-                // showing inactive message types for that messenger)
3486
-                $mt_boxes[ $messenger . '_i_box' ] = esc_html__('Inactive Message Types', 'event_espresso');
3487
-                $mt_template_args[ $messenger . '_i_box' ] = array(
3488
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3489
-                    'inactive_message_types' => isset(
3490
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3491
-                    )
3492
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3493
-                        : '',
3494
-                    'hidden'                 => $active ? '' : ' hidden',
3495
-                    'hide_on_message'        => $hide_on_message,
3496
-                    'hide_off_message'       => $hide_off_message,
3497
-                    'messenger'              => $messenger,
3498
-                    'active'                 => $active,
3499
-                );
3500
-            }
3501
-        }
3502
-
3503
-
3504
-        // register messenger metaboxes
3505
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3506
-        foreach ($m_boxes as $box => $label) {
3507
-            $callback_args = array('template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]);
3508
-            $msgr = str_replace('_a_box', '', $box);
3509
-            add_meta_box(
3510
-                'espresso_' . $msgr . '_settings',
3511
-                $label,
3512
-                function ($post, $metabox) {
3513
-                    echo EEH_Template::display_template(
3514
-                        $metabox["args"]["template_path"],
3515
-                        $metabox["args"]["template_args"],
3516
-                        true
3517
-                    );
3518
-                },
3519
-                $this->_current_screen->id,
3520
-                'normal',
3521
-                'high',
3522
-                $callback_args
3523
-            );
3524
-        }
3525
-
3526
-        // register message type metaboxes
3527
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3528
-        foreach ($mt_boxes as $box => $label) {
3529
-            $callback_args = array(
3530
-                'template_path' => $mt_template_path,
3531
-                'template_args' => $mt_template_args[ $box ],
3532
-            );
3533
-            $mt = str_replace('_i_box', '', $box);
3534
-            add_meta_box(
3535
-                'espresso_' . $mt . '_inactive_mts',
3536
-                $label,
3537
-                function ($post, $metabox) {
3538
-                    echo EEH_Template::display_template(
3539
-                        $metabox["args"]["template_path"],
3540
-                        $metabox["args"]["template_args"],
3541
-                        true
3542
-                    );
3543
-                },
3544
-                $this->_current_screen->id,
3545
-                'side',
3546
-                'high',
3547
-                $callback_args
3548
-            );
3549
-        }
3550
-
3551
-        // register metabox for global messages settings but only when on the main site.  On single site installs this
3552
-        // will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3553
-        if (is_main_site()) {
3554
-            add_meta_box(
3555
-                'espresso_global_message_settings',
3556
-                esc_html__('Global Message Settings', 'event_espresso'),
3557
-                array($this, 'global_messages_settings_metabox_content'),
3558
-                $this->_current_screen->id,
3559
-                'normal',
3560
-                'low',
3561
-                array()
3562
-            );
3563
-        }
3564
-    }
3565
-
3566
-
3567
-    /**
3568
-     *  This generates the content for the global messages settings metabox.
3569
-     *
3570
-     * @return string
3571
-     * @throws EE_Error
3572
-     * @throws InvalidArgumentException
3573
-     * @throws ReflectionException
3574
-     * @throws InvalidDataTypeException
3575
-     * @throws InvalidInterfaceException
3576
-     */
3577
-    public function global_messages_settings_metabox_content()
3578
-    {
3579
-        $form = $this->_generate_global_settings_form();
3580
-        echo $form->form_open(
3581
-            $this->add_query_args_and_nonce(array('action' => 'update_global_settings'), EE_MSG_ADMIN_URL),
3582
-            'POST'
3583
-        )
3584
-             . $form->get_html()
3585
-             . $form->form_close();
3586
-    }
3587
-
3588
-
3589
-    /**
3590
-     * This generates and returns the form object for the global messages settings.
3591
-     *
3592
-     * @return EE_Form_Section_Proper
3593
-     * @throws EE_Error
3594
-     * @throws InvalidArgumentException
3595
-     * @throws ReflectionException
3596
-     * @throws InvalidDataTypeException
3597
-     * @throws InvalidInterfaceException
3598
-     */
3599
-    protected function _generate_global_settings_form()
3600
-    {
3601
-        EE_Registry::instance()->load_helper('HTML');
3602
-        /** @var EE_Network_Core_Config $network_config */
3603
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3604
-
3605
-        return new EE_Form_Section_Proper(
3606
-            array(
3607
-                'name'            => 'global_messages_settings',
3608
-                'html_id'         => 'global_messages_settings',
3609
-                'html_class'      => 'form-table',
3610
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3611
-                'subsections'     => apply_filters(
3612
-                    'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3613
-                    array(
3614
-                        'do_messages_on_same_request' => new EE_Select_Input(
3615
-                            array(
3616
-                                true  => esc_html__("On the same request", "event_espresso"),
3617
-                                false => esc_html__("On a separate request", "event_espresso"),
3618
-                            ),
3619
-                            array(
3620
-                                'default'         => $network_config->do_messages_on_same_request,
3621
-                                'html_label_text' => esc_html__(
3622
-                                    'Generate and send all messages:',
3623
-                                    'event_espresso'
3624
-                                ),
3625
-                                'html_help_text'  => esc_html__(
3626
-                                    '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.',
3627
-                                    'event_espresso'
3628
-                                ),
3629
-                            )
3630
-                        ),
3631
-                        'delete_threshold'            => new EE_Select_Input(
3632
-                            array(
3633
-                                0  => esc_html__('Forever', 'event_espresso'),
3634
-                                3  => esc_html__('3 Months', 'event_espresso'),
3635
-                                6  => esc_html__('6 Months', 'event_espresso'),
3636
-                                9  => esc_html__('9 Months', 'event_espresso'),
3637
-                                12 => esc_html__('12 Months', 'event_espresso'),
3638
-                                24 => esc_html__('24 Months', 'event_espresso'),
3639
-                                36 => esc_html__('36 Months', 'event_espresso'),
3640
-                            ),
3641
-                            array(
3642
-                                'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3643
-                                'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3644
-                                'html_help_text'  => esc_html__(
3645
-                                    'You can control how long a record of processed messages is kept via this option.',
3646
-                                    'event_espresso'
3647
-                                ),
3648
-                            )
3649
-                        ),
3650
-                        'update_settings'             => new EE_Submit_Input(
3651
-                            array(
3652
-                                'default'         => esc_html__('Update', 'event_espresso'),
3653
-                                'html_label_text' => '&nbsp',
3654
-                            )
3655
-                        ),
3656
-                    )
3657
-                ),
3658
-            )
3659
-        );
3660
-    }
3661
-
3662
-
3663
-    /**
3664
-     * This handles updating the global settings set on the admin page.
3665
-     *
3666
-     * @throws EE_Error
3667
-     * @throws InvalidDataTypeException
3668
-     * @throws InvalidInterfaceException
3669
-     * @throws InvalidArgumentException
3670
-     * @throws ReflectionException
3671
-     */
3672
-    protected function _update_global_settings()
3673
-    {
3674
-        /** @var EE_Network_Core_Config $network_config */
3675
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3676
-        $messages_config = EE_Registry::instance()->CFG->messages;
3677
-        $form = $this->_generate_global_settings_form();
3678
-        if ($form->was_submitted()) {
3679
-            $form->receive_form_submission();
3680
-            if ($form->is_valid()) {
3681
-                $valid_data = $form->valid_data();
3682
-                foreach ($valid_data as $property => $value) {
3683
-                    $setter = 'set_' . $property;
3684
-                    if (method_exists($network_config, $setter)) {
3685
-                        $network_config->{$setter}($value);
3686
-                    } elseif (property_exists($network_config, $property)
3687
-                        && $network_config->{$property} !== $value
3688
-                    ) {
3689
-                        $network_config->{$property} = $value;
3690
-                    } elseif (property_exists($messages_config, $property)
3691
-                        && $messages_config->{$property} !== $value
3692
-                    ) {
3693
-                        $messages_config->{$property} = $value;
3694
-                    }
3695
-                }
3696
-                // only update if the form submission was valid!
3697
-                EE_Registry::instance()->NET_CFG->update_config(true, false);
3698
-                EE_Registry::instance()->CFG->update_espresso_config();
3699
-                EE_Error::overwrite_success();
3700
-                EE_Error::add_success(__('Global message settings were updated', 'event_espresso'));
3701
-            }
3702
-        }
3703
-        $this->_redirect_after_action(0, '', '', array('action' => 'settings'), true);
3704
-    }
3705
-
3706
-
3707
-    /**
3708
-     * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3709
-     *
3710
-     * @param  array $tab_array This is an array of message type tab details used to generate the tabs
3711
-     * @return string html formatted tabs
3712
-     * @throws DomainException
3713
-     */
3714
-    protected function _get_mt_tabs($tab_array)
3715
-    {
3716
-        $tab_array = (array) $tab_array;
3717
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3718
-        $tabs = '';
3719
-
3720
-        foreach ($tab_array as $tab) {
3721
-            $tabs .= EEH_Template::display_template($template, $tab, true);
3722
-        }
3723
-
3724
-        return $tabs;
3725
-    }
3726
-
3727
-
3728
-    /**
3729
-     * This prepares the content of the messenger meta box admin settings
3730
-     *
3731
-     * @param  EE_messenger $messenger The messenger we're setting up content for
3732
-     * @return string html formatted content
3733
-     * @throws DomainException
3734
-     */
3735
-    protected function _get_messenger_box_content(EE_messenger $messenger)
3736
-    {
3737
-
3738
-        $fields = $messenger->get_admin_settings_fields();
3739
-        $settings_template_args['template_form_fields'] = '';
3740
-
3741
-        // is $messenger active?
3742
-        $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3743
-
3744
-
3745
-        if (! empty($fields)) {
3746
-            $existing_settings = $messenger->get_existing_admin_settings();
3747
-
3748
-            foreach ($fields as $fldname => $fldprops) {
3749
-                $field_id = $messenger->name . '-' . $fldname;
3750
-                $template_form_field[ $field_id ] = array(
3751
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3752
-                    'label'      => $fldprops['label'],
3753
-                    'input'      => $fldprops['field_type'],
3754
-                    'type'       => $fldprops['value_type'],
3755
-                    'required'   => $fldprops['required'],
3756
-                    'validation' => $fldprops['validation'],
3757
-                    'value'      => isset($existing_settings[ $field_id ])
3758
-                        ? $existing_settings[ $field_id ]
3759
-                        : $fldprops['default'],
3760
-                    'css_class'  => '',
3761
-                    'format'     => $fldprops['format'],
3762
-                );
3763
-            }
3764
-
3765
-
3766
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3767
-                ? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3768
-                : '';
3769
-        }
3770
-
3771
-        // we also need some hidden fields
3772
-        $settings_template_args['hidden_fields'] = array(
3773
-            'messenger_settings[messenger]' => array(
3774
-                'type'  => 'hidden',
3775
-                'value' => $messenger->name,
3776
-            ),
3777
-            'type'                          => array(
3778
-                'type'  => 'hidden',
3779
-                'value' => 'messenger',
3780
-            ),
3781
-        );
3782
-
3783
-        // make sure any active message types that are existing are included in the hidden fields
3784
-        if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3785
-            foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3786
-                $settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = array(
3787
-                    'type'  => 'hidden',
3788
-                    'value' => $mt,
3789
-                );
3790
-            }
3791
-        }
3792
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3793
-            $settings_template_args['hidden_fields'],
3794
-            'array'
3795
-        );
3796
-        $active = $this->_message_resource_manager->is_messenger_active($messenger->name);
3797
-
3798
-        $settings_template_args['messenger'] = $messenger->name;
3799
-        $settings_template_args['description'] = $messenger->description;
3800
-        $settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3801
-
3802
-
3803
-        $settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3804
-            $messenger->name
3805
-        )
3806
-            ? $settings_template_args['show_hide_edit_form']
3807
-            : ' hidden';
3808
-
3809
-        $settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3810
-            ? ' hidden'
3811
-            : $settings_template_args['show_hide_edit_form'];
3812
-
3813
-
3814
-        $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3815
-        $settings_template_args['nonce'] = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3816
-        $settings_template_args['on_off_status'] = $active ? true : false;
3817
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3818
-        $content = EEH_Template::display_template(
3819
-            $template,
3820
-            $settings_template_args,
3821
-            true
3822
-        );
3823
-
3824
-        return $content;
3825
-    }
3826
-
3827
-
3828
-    /**
3829
-     * used by ajax on the messages settings page to activate|deactivate the messenger
3830
-     *
3831
-     * @throws DomainException
3832
-     * @throws EE_Error
3833
-     * @throws InvalidDataTypeException
3834
-     * @throws InvalidInterfaceException
3835
-     * @throws InvalidArgumentException
3836
-     * @throws ReflectionException
3837
-     */
3838
-    public function activate_messenger_toggle()
3839
-    {
3840
-        $success = true;
3841
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3842
-        // let's check that we have required data
3843
-        if (! isset($this->_req_data['messenger'])) {
3844
-            EE_Error::add_error(
3845
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3846
-                __FILE__,
3847
-                __FUNCTION__,
3848
-                __LINE__
3849
-            );
3850
-            $success = false;
3851
-        }
3852
-
3853
-        // do a nonce check here since we're not arriving via a normal route
3854
-        $nonce = isset($this->_req_data['activate_nonce'])
3855
-            ? sanitize_text_field($this->_req_data['activate_nonce'])
3856
-            : '';
3857
-        $nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3858
-
3859
-        $this->_verify_nonce($nonce, $nonce_ref);
3860
-
3861
-
3862
-        if (! isset($this->_req_data['status'])) {
3863
-            EE_Error::add_error(
3864
-                esc_html__(
3865
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3866
-                    'event_espresso'
3867
-                ),
3868
-                __FILE__,
3869
-                __FUNCTION__,
3870
-                __LINE__
3871
-            );
3872
-            $success = false;
3873
-        }
3874
-
3875
-        // do check to verify we have a valid status.
3876
-        $status = $this->_req_data['status'];
3877
-
3878
-        if ($status !== 'off' && $status !== 'on') {
3879
-            EE_Error::add_error(
3880
-                sprintf(
3881
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3882
-                    $this->_req_data['status']
3883
-                ),
3884
-                __FILE__,
3885
-                __FUNCTION__,
3886
-                __LINE__
3887
-            );
3888
-            $success = false;
3889
-        }
3890
-
3891
-        if ($success) {
3892
-            // made it here?  Stop dawdling then!!
3893
-            $success = $status === 'off'
3894
-                ? $this->_deactivate_messenger($this->_req_data['messenger'])
3895
-                : $this->_activate_messenger($this->_req_data['messenger']);
3896
-        }
3897
-
3898
-        $this->_template_args['success'] = $success;
3899
-
3900
-        // no special instructions so let's just do the json return (which should automatically do all the special stuff).
3901
-        $this->_return_json();
3902
-    }
3903
-
3904
-
3905
-    /**
3906
-     * used by ajax from the messages settings page to activate|deactivate a message type
3907
-     *
3908
-     * @throws DomainException
3909
-     * @throws EE_Error
3910
-     * @throws ReflectionException
3911
-     * @throws InvalidDataTypeException
3912
-     * @throws InvalidInterfaceException
3913
-     * @throws InvalidArgumentException
3914
-     */
3915
-    public function activate_mt_toggle()
3916
-    {
3917
-        $success = true;
3918
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3919
-
3920
-        // let's make sure we have the necessary data
3921
-        if (! isset($this->_req_data['message_type'])) {
3922
-            EE_Error::add_error(
3923
-                esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3924
-                __FILE__,
3925
-                __FUNCTION__,
3926
-                __LINE__
3927
-            );
3928
-            $success = false;
3929
-        }
3930
-
3931
-        if (! isset($this->_req_data['messenger'])) {
3932
-            EE_Error::add_error(
3933
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3934
-                __FILE__,
3935
-                __FUNCTION__,
3936
-                __LINE__
3937
-            );
3938
-            $success = false;
3939
-        }
3940
-
3941
-        if (! isset($this->_req_data['status'])) {
3942
-            EE_Error::add_error(
3943
-                esc_html__(
3944
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3945
-                    'event_espresso'
3946
-                ),
3947
-                __FILE__,
3948
-                __FUNCTION__,
3949
-                __LINE__
3950
-            );
3951
-            $success = false;
3952
-        }
3953
-
3954
-
3955
-        // do check to verify we have a valid status.
3956
-        $status = $this->_req_data['status'];
3957
-
3958
-        if ($status !== 'activate' && $status !== 'deactivate') {
3959
-            EE_Error::add_error(
3960
-                sprintf(
3961
-                    esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3962
-                    $this->_req_data['status']
3963
-                ),
3964
-                __FILE__,
3965
-                __FUNCTION__,
3966
-                __LINE__
3967
-            );
3968
-            $success = false;
3969
-        }
3970
-
3971
-
3972
-        // do a nonce check here since we're not arriving via a normal route
3973
-        $nonce = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3974
-        $nonce_ref = $this->_req_data['message_type'] . '_nonce';
3975
-
3976
-        $this->_verify_nonce($nonce, $nonce_ref);
3977
-
3978
-        if ($success) {
3979
-            // made it here? um, what are you waiting for then?
3980
-            $success = $status === 'deactivate'
3981
-                ? $this->_deactivate_message_type_for_messenger(
3982
-                    $this->_req_data['messenger'],
3983
-                    $this->_req_data['message_type']
3984
-                )
3985
-                : $this->_activate_message_type_for_messenger(
3986
-                    $this->_req_data['messenger'],
3987
-                    $this->_req_data['message_type']
3988
-                );
3989
-        }
3990
-
3991
-        $this->_template_args['success'] = $success;
3992
-        $this->_return_json();
3993
-    }
3994
-
3995
-
3996
-    /**
3997
-     * Takes care of processing activating a messenger and preparing the appropriate response.
3998
-     *
3999
-     * @param string $messenger_name The name of the messenger being activated
4000
-     * @return bool
4001
-     * @throws DomainException
4002
-     * @throws EE_Error
4003
-     * @throws InvalidArgumentException
4004
-     * @throws ReflectionException
4005
-     * @throws InvalidDataTypeException
4006
-     * @throws InvalidInterfaceException
4007
-     */
4008
-    protected function _activate_messenger($messenger_name)
4009
-    {
4010
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4011
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4012
-        $message_types_to_activate = $active_messenger instanceof EE_Messenger
4013
-            ? $active_messenger->get_default_message_types()
4014
-            : array();
4015
-
4016
-        // ensure is active
4017
-        $this->_message_resource_manager->activate_messenger($messenger_name, $message_types_to_activate);
4018
-
4019
-        // set response_data for reload
4020
-        foreach ($message_types_to_activate as $message_type_name) {
4021
-            /** @var EE_message_type $message_type */
4022
-            $message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4023
-            if ($this->_message_resource_manager->is_message_type_active_for_messenger(
4024
-                $messenger_name,
4025
-                $message_type_name
4026
-            )
4027
-                && $message_type instanceof EE_message_type
4028
-            ) {
4029
-                $this->_template_args['data']['active_mts'][] = $message_type_name;
4030
-                if ($message_type->get_admin_settings_fields()) {
4031
-                    $this->_template_args['data']['mt_reload'][] = $message_type_name;
4032
-                }
4033
-            }
4034
-        }
4035
-
4036
-        // add success message for activating messenger
4037
-        return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4038
-    }
4039
-
4040
-
4041
-    /**
4042
-     * Takes care of processing deactivating a messenger and preparing the appropriate response.
4043
-     *
4044
-     * @param string $messenger_name The name of the messenger being activated
4045
-     * @return bool
4046
-     * @throws DomainException
4047
-     * @throws EE_Error
4048
-     * @throws InvalidArgumentException
4049
-     * @throws ReflectionException
4050
-     * @throws InvalidDataTypeException
4051
-     * @throws InvalidInterfaceException
4052
-     */
4053
-    protected function _deactivate_messenger($messenger_name)
4054
-    {
4055
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4056
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4057
-        $this->_message_resource_manager->deactivate_messenger($messenger_name);
4058
-
4059
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4060
-    }
4061
-
4062
-
4063
-    /**
4064
-     * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4065
-     *
4066
-     * @param string $messenger_name    The name of the messenger the message type is being activated for.
4067
-     * @param string $message_type_name The name of the message type being activated for the messenger
4068
-     * @return bool
4069
-     * @throws DomainException
4070
-     * @throws EE_Error
4071
-     * @throws InvalidArgumentException
4072
-     * @throws ReflectionException
4073
-     * @throws InvalidDataTypeException
4074
-     * @throws InvalidInterfaceException
4075
-     */
4076
-    protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4077
-    {
4078
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4079
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4080
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4081
-        $message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4082
-
4083
-        // ensure is active
4084
-        $this->_message_resource_manager->activate_messenger($messenger_name, $message_type_name);
4085
-
4086
-        // set response for load
4087
-        if ($this->_message_resource_manager->is_message_type_active_for_messenger(
4088
-            $messenger_name,
4089
-            $message_type_name
4090
-        )
4091
-        ) {
4092
-            $this->_template_args['data']['active_mts'][] = $message_type_name;
4093
-            if ($message_type_to_activate->get_admin_settings_fields()) {
4094
-                $this->_template_args['data']['mt_reload'][] = $message_type_name;
4095
-            }
4096
-        }
4097
-
4098
-        return $this->_setup_response_message_for_activating_messenger_with_message_types(
4099
-            $active_messenger,
4100
-            $message_type_to_activate
4101
-        );
4102
-    }
4103
-
4104
-
4105
-    /**
4106
-     * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4107
-     *
4108
-     * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4109
-     * @param string $message_type_name The name of the message type being deactivated for the messenger
4110
-     * @return bool
4111
-     * @throws DomainException
4112
-     * @throws EE_Error
4113
-     * @throws InvalidArgumentException
4114
-     * @throws ReflectionException
4115
-     * @throws InvalidDataTypeException
4116
-     * @throws InvalidInterfaceException
4117
-     */
4118
-    protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4119
-    {
4120
-        /** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4121
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4122
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4123
-        $message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4124
-        $this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4125
-
4126
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4127
-            $active_messenger,
4128
-            $message_type_to_deactivate
4129
-        );
4130
-    }
4131
-
4132
-
4133
-    /**
4134
-     * This just initializes the defaults for activating messenger and message type responses.
4135
-     */
4136
-    protected function _prep_default_response_for_messenger_or_message_type_toggle()
4137
-    {
4138
-        $this->_template_args['data']['active_mts'] = array();
4139
-        $this->_template_args['data']['mt_reload'] = array();
4140
-    }
4141
-
4142
-
4143
-    /**
4144
-     * Setup appropriate response for activating a messenger and/or message types
4145
-     *
4146
-     * @param EE_messenger         $messenger
4147
-     * @param EE_message_type|null $message_type
4148
-     * @return bool
4149
-     * @throws DomainException
4150
-     * @throws EE_Error
4151
-     * @throws InvalidArgumentException
4152
-     * @throws ReflectionException
4153
-     * @throws InvalidDataTypeException
4154
-     * @throws InvalidInterfaceException
4155
-     */
4156
-    protected function _setup_response_message_for_activating_messenger_with_message_types(
4157
-        $messenger,
4158
-        EE_Message_Type $message_type = null
4159
-    ) {
4160
-        // if $messenger isn't a valid messenger object then get out.
4161
-        if (! $messenger instanceof EE_Messenger) {
4162
-            EE_Error::add_error(
4163
-                esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4164
-                __FILE__,
4165
-                __FUNCTION__,
4166
-                __LINE__
4167
-            );
4168
-
4169
-            return false;
4170
-        }
4171
-        // activated
4172
-        if ($this->_template_args['data']['active_mts']) {
4173
-            EE_Error::overwrite_success();
4174
-            // activated a message type with the messenger
4175
-            if ($message_type instanceof EE_message_type) {
4176
-                EE_Error::add_success(
4177
-                    sprintf(
4178
-                        esc_html__(
4179
-                            '%s message type has been successfully activated with the %s messenger',
4180
-                            'event_espresso'
4181
-                        ),
4182
-                        ucwords($message_type->label['singular']),
4183
-                        ucwords($messenger->label['singular'])
4184
-                    )
4185
-                );
4186
-
4187
-                // if message type was invoice then let's make sure we activate the invoice payment method.
4188
-                if ($message_type->name === 'invoice') {
4189
-                    EE_Registry::instance()->load_lib('Payment_Method_Manager');
4190
-                    $pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4191
-                    if ($pm instanceof EE_Payment_Method) {
4192
-                        EE_Error::add_attention(
4193
-                            esc_html__(
4194
-                                '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.',
4195
-                                'event_espresso'
4196
-                            )
4197
-                        );
4198
-                    }
4199
-                }
4200
-                // just toggles the entire messenger
4201
-            } else {
4202
-                EE_Error::add_success(
4203
-                    sprintf(
4204
-                        esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4205
-                        ucwords($messenger->label['singular'])
4206
-                    )
4207
-                );
4208
-            }
4209
-
4210
-            return true;
4211
-
4212
-            // possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4213
-            // message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4214
-            // in which case we just give a success message for the messenger being successfully activated.
4215
-        } else {
4216
-            if (! $messenger->get_default_message_types()) {
4217
-                // messenger doesn't have any default message types so still a success.
4218
-                EE_Error::add_success(
4219
-                    sprintf(
4220
-                        esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4221
-                        ucwords($messenger->label['singular'])
4222
-                    )
4223
-                );
4224
-
4225
-                return true;
4226
-            } else {
4227
-                EE_Error::add_error(
4228
-                    $message_type instanceof EE_message_type
4229
-                        ? sprintf(
4230
-                            esc_html__(
4231
-                                '%s message type was not successfully activated with the %s messenger',
4232
-                                'event_espresso'
4233
-                            ),
4234
-                            ucwords($message_type->label['singular']),
4235
-                            ucwords($messenger->label['singular'])
4236
-                        )
4237
-                        : sprintf(
4238
-                            esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4239
-                            ucwords($messenger->label['singular'])
4240
-                        ),
4241
-                    __FILE__,
4242
-                    __FUNCTION__,
4243
-                    __LINE__
4244
-                );
4245
-
4246
-                return false;
4247
-            }
4248
-        }
4249
-    }
4250
-
4251
-
4252
-    /**
4253
-     * This sets up the appropriate response for deactivating a messenger and/or message type.
4254
-     *
4255
-     * @param EE_messenger         $messenger
4256
-     * @param EE_message_type|null $message_type
4257
-     * @return bool
4258
-     * @throws DomainException
4259
-     * @throws EE_Error
4260
-     * @throws InvalidArgumentException
4261
-     * @throws ReflectionException
4262
-     * @throws InvalidDataTypeException
4263
-     * @throws InvalidInterfaceException
4264
-     */
4265
-    protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4266
-        $messenger,
4267
-        EE_message_type $message_type = null
4268
-    ) {
4269
-        EE_Error::overwrite_success();
4270
-
4271
-        // if $messenger isn't a valid messenger object then get out.
4272
-        if (! $messenger instanceof EE_Messenger) {
4273
-            EE_Error::add_error(
4274
-                esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4275
-                __FILE__,
4276
-                __FUNCTION__,
4277
-                __LINE__
4278
-            );
4279
-
4280
-            return false;
4281
-        }
4282
-
4283
-        if ($message_type instanceof EE_message_type) {
4284
-            $message_type_name = $message_type->name;
4285
-            EE_Error::add_success(
4286
-                sprintf(
4287
-                    esc_html__(
4288
-                        '%s message type has been successfully deactivated for the %s messenger.',
4289
-                        'event_espresso'
4290
-                    ),
4291
-                    ucwords($message_type->label['singular']),
4292
-                    ucwords($messenger->label['singular'])
4293
-                )
4294
-            );
4295
-        } else {
4296
-            $message_type_name = '';
4297
-            EE_Error::add_success(
4298
-                sprintf(
4299
-                    esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4300
-                    ucwords($messenger->label['singular'])
4301
-                )
4302
-            );
4303
-        }
4304
-
4305
-        // if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4306
-        if ($messenger->name === 'html' || $message_type_name === 'invoice') {
4307
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
4308
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4309
-            if ($count_updated > 0) {
4310
-                $msg = $message_type_name === 'invoice'
4311
-                    ? esc_html__(
4312
-                        '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.',
4313
-                        'event_espresso'
4314
-                    )
4315
-                    : esc_html__(
4316
-                        '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.',
4317
-                        'event_espresso'
4318
-                    );
4319
-                EE_Error::add_attention($msg);
4320
-            }
4321
-        }
4322
-
4323
-        return true;
4324
-    }
4325
-
4326
-
4327
-    /**
4328
-     * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4329
-     *
4330
-     * @throws DomainException
4331
-     */
4332
-    public function update_mt_form()
4333
-    {
4334
-        if (! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4335
-            EE_Error::add_error(
4336
-                esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4337
-                __FILE__,
4338
-                __FUNCTION__,
4339
-                __LINE__
4340
-            );
4341
-            $this->_return_json();
4342
-        }
4343
-
4344
-        $message_types = $this->get_installed_message_types();
4345
-
4346
-        $message_type = $message_types[ $this->_req_data['message_type'] ];
4347
-        $messenger = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
4348
-
4349
-        $content = $this->_message_type_settings_content(
4350
-            $message_type,
4351
-            $messenger,
4352
-            true
4353
-        );
4354
-        $this->_template_args['success'] = true;
4355
-        $this->_template_args['content'] = $content;
4356
-        $this->_return_json();
4357
-    }
4358
-
4359
-
4360
-    /**
4361
-     * this handles saving the settings for a messenger or message type
4362
-     *
4363
-     */
4364
-    public function save_settings()
4365
-    {
4366
-        if (! isset($this->_req_data['type'])) {
4367
-            EE_Error::add_error(
4368
-                esc_html__(
4369
-                    'Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
4370
-                    'event_espresso'
4371
-                ),
4372
-                __FILE__,
4373
-                __FUNCTION__,
4374
-                __LINE__
4375
-            );
4376
-            $this->_template_args['error'] = true;
4377
-            $this->_return_json();
4378
-        }
4379
-
4380
-
4381
-        if ($this->_req_data['type'] === 'messenger') {
4382
-            // this should be an array.
4383
-            $settings = $this->_req_data['messenger_settings'];
4384
-            $messenger = $settings['messenger'];
4385
-            // let's setup the settings data
4386
-            foreach ($settings as $key => $value) {
4387
-                switch ($key) {
4388
-                    case 'messenger':
4389
-                        unset($settings['messenger']);
4390
-                        break;
4391
-                    case 'message_types':
4392
-                        unset($settings['message_types']);
4393
-                        break;
4394
-                    default:
4395
-                        $settings[ $key ] = $value;
4396
-                        break;
4397
-                }
4398
-            }
4399
-            $this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4400
-        } elseif ($this->_req_data['type'] === 'message_type') {
4401
-            $settings = $this->_req_data['message_type_settings'];
4402
-            $messenger = $settings['messenger'];
4403
-            $message_type = $settings['message_type'];
4404
-
4405
-            foreach ($settings as $key => $value) {
4406
-                switch ($key) {
4407
-                    case 'messenger':
4408
-                        unset($settings['messenger']);
4409
-                        break;
4410
-                    case 'message_type':
4411
-                        unset($settings['message_type']);
4412
-                        break;
4413
-                    default:
4414
-                        $settings[ $key ] = $value;
4415
-                        break;
4416
-                }
4417
-            }
4418
-
4419
-            $this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4420
-        }
4421
-
4422
-        // okay we should have the data all setup.  Now we just update!
4423
-        $success = $this->_message_resource_manager->update_active_messengers_option();
4424
-
4425
-        if ($success) {
4426
-            EE_Error::add_success(__('Settings updated', 'event_espresso'));
4427
-        } else {
4428
-            EE_Error::add_error(
4429
-                esc_html__(
4430
-                    'Settings did not get updated',
4431
-                    'event_espresso'
4432
-                ),
4433
-                __FILE__,
4434
-                __FUNCTION__,
4435
-                __LINE__
4436
-            );
4437
-        }
4438
-
4439
-        $this->_template_args['success'] = $success;
4440
-        $this->_return_json();
4441
-    }
4442
-
4443
-
4444
-
4445
-
4446
-    /**  EE MESSAGE PROCESSING ACTIONS **/
4447
-
4448
-
4449
-    /**
4450
-     * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4451
-     * However, this does not send immediately, it just queues for sending.
4452
-     *
4453
-     * @since 4.9.0
4454
-     * @throws EE_Error
4455
-     * @throws InvalidDataTypeException
4456
-     * @throws InvalidInterfaceException
4457
-     * @throws InvalidArgumentException
4458
-     * @throws ReflectionException
4459
-     */
4460
-    protected function _generate_now()
4461
-    {
4462
-        EED_Messages::generate_now($this->_get_msg_ids_from_request());
4463
-        $this->_redirect_after_action(false, '', '', array(), true);
4464
-    }
4465
-
4466
-
4467
-    /**
4468
-     * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4469
-     * are EEM_Message::status_resend or EEM_Message::status_idle
4470
-     *
4471
-     * @since 4.9.0
4472
-     * @throws EE_Error
4473
-     * @throws InvalidDataTypeException
4474
-     * @throws InvalidInterfaceException
4475
-     * @throws InvalidArgumentException
4476
-     * @throws ReflectionException
4477
-     */
4478
-    protected function _generate_and_send_now()
4479
-    {
4480
-        EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4481
-        $this->_redirect_after_action(false, '', '', array(), true);
4482
-    }
4483
-
4484
-
4485
-    /**
4486
-     * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4487
-     *
4488
-     * @since 4.9.0
4489
-     * @throws EE_Error
4490
-     * @throws InvalidDataTypeException
4491
-     * @throws InvalidInterfaceException
4492
-     * @throws InvalidArgumentException
4493
-     * @throws ReflectionException
4494
-     */
4495
-    protected function _queue_for_resending()
4496
-    {
4497
-        EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4498
-        $this->_redirect_after_action(false, '', '', array(), true);
4499
-    }
4500
-
4501
-
4502
-    /**
4503
-     *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4504
-     *
4505
-     * @since 4.9.0
4506
-     * @throws EE_Error
4507
-     * @throws InvalidDataTypeException
4508
-     * @throws InvalidInterfaceException
4509
-     * @throws InvalidArgumentException
4510
-     * @throws ReflectionException
4511
-     */
4512
-    protected function _send_now()
4513
-    {
4514
-        EED_Messages::send_now($this->_get_msg_ids_from_request());
4515
-        $this->_redirect_after_action(false, '', '', array(), true);
4516
-    }
4517
-
4518
-
4519
-    /**
4520
-     * Deletes EE_messages for IDs in the request.
4521
-     *
4522
-     * @since 4.9.0
4523
-     * @throws EE_Error
4524
-     * @throws InvalidDataTypeException
4525
-     * @throws InvalidInterfaceException
4526
-     * @throws InvalidArgumentException
4527
-     */
4528
-    protected function _delete_ee_messages()
4529
-    {
4530
-        $msg_ids = $this->_get_msg_ids_from_request();
4531
-        $deleted_count = 0;
4532
-        foreach ($msg_ids as $msg_id) {
4533
-            if (EEM_Message::instance()->delete_by_ID($msg_id)) {
4534
-                $deleted_count++;
4535
-            }
4536
-        }
4537
-        if ($deleted_count) {
4538
-            EE_Error::add_success(
4539
-                esc_html(
4540
-                    _n(
4541
-                        'Message successfully deleted',
4542
-                        'Messages successfully deleted',
4543
-                        $deleted_count,
4544
-                        'event_espresso'
4545
-                    )
4546
-                )
4547
-            );
4548
-            $this->_redirect_after_action(
4549
-                false,
4550
-                '',
4551
-                '',
4552
-                array(),
4553
-                true
4554
-            );
4555
-        } else {
4556
-            EE_Error::add_error(
4557
-                _n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
4558
-                __FILE__,
4559
-                __FUNCTION__,
4560
-                __LINE__
4561
-            );
4562
-            $this->_redirect_after_action(false, '', '', array(), true);
4563
-        }
4564
-    }
4565
-
4566
-
4567
-    /**
4568
-     *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4569
-     *
4570
-     * @since 4.9.0
4571
-     * @return array
4572
-     */
4573
-    protected function _get_msg_ids_from_request()
4574
-    {
4575
-        if (! isset($this->_req_data['MSG_ID'])) {
4576
-            return array();
4577
-        }
4578
-
4579
-        return is_array($this->_req_data['MSG_ID'])
4580
-            ? array_keys($this->_req_data['MSG_ID'])
4581
-            : array($this->_req_data['MSG_ID']);
4582
-    }
2662
+		$output = ob_get_contents();
2663
+		ob_clean();
2664
+		$this->_context_switcher = $output;
2665
+	}
2666
+
2667
+
2668
+	/**
2669
+	 * utility for sanitizing new values coming in.
2670
+	 * Note: this is only used when updating a context.
2671
+	 *
2672
+	 * @access protected
2673
+	 *
2674
+	 * @param int $index This helps us know which template field to select from the request array.
2675
+	 *
2676
+	 * @return array
2677
+	 */
2678
+	protected function _set_message_template_column_values($index)
2679
+	{
2680
+		if (is_array($this->_req_data['MTP_template_fields'][ $index ]['content'])) {
2681
+			foreach ($this->_req_data['MTP_template_fields'][ $index ]['content'] as $field => $value) {
2682
+				$this->_req_data['MTP_template_fields'][ $index ]['content'][ $field ] = $value;
2683
+			}
2684
+		}
2685
+
2686
+
2687
+		$set_column_values = array(
2688
+			'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][ $index ]['MTP_ID']),
2689
+			'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2690
+			'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2691
+			'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2692
+			'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2693
+			'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][ $index ]['name']),
2694
+			'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2695
+			'MTP_content'        => $this->_req_data['MTP_template_fields'][ $index ]['content'],
2696
+			'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2697
+				? absint($this->_req_data['MTP_is_global'])
2698
+				: 0,
2699
+			'MTP_is_override'    => isset($this->_req_data['MTP_is_override'])
2700
+				? absint($this->_req_data['MTP_is_override'])
2701
+				: 0,
2702
+			'MTP_deleted'        => absint($this->_req_data['MTP_deleted']),
2703
+			'MTP_is_active'      => absint($this->_req_data['MTP_is_active']),
2704
+		);
2705
+
2706
+
2707
+		return $set_column_values;
2708
+	}
2709
+
2710
+
2711
+	protected function _insert_or_update_message_template($new = false)
2712
+	{
2713
+
2714
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2715
+		$success = 0;
2716
+		$override = false;
2717
+
2718
+		// setup notices description
2719
+		$messenger_slug = ! empty($this->_req_data['MTP_messenger']) ? $this->_req_data['MTP_messenger'] : '';
2720
+
2721
+		// need the message type and messenger objects to be able to use the labels for the notices
2722
+		$messenger_object = $this->_message_resource_manager->get_messenger($messenger_slug);
2723
+		$messenger_label = $messenger_object instanceof EE_messenger
2724
+			? ucwords($messenger_object->label['singular'])
2725
+			: '';
2726
+
2727
+		$message_type_slug = ! empty($this->_req_data['MTP_message_type'])
2728
+			? $this->_req_data['MTP_message_type']
2729
+			: '';
2730
+		$message_type_object = $this->_message_resource_manager->get_message_type($message_type_slug);
2731
+
2732
+		$message_type_label = $message_type_object instanceof EE_message_type
2733
+			? ucwords($message_type_object->label['singular'])
2734
+			: '';
2735
+
2736
+		$context_slug = ! empty($this->_req_data['MTP_context'])
2737
+			? $this->_req_data['MTP_context']
2738
+			: '';
2739
+		$context = ucwords(str_replace('_', ' ', $context_slug));
2740
+
2741
+		$item_desc = $messenger_label && $message_type_label
2742
+			? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2743
+			: '';
2744
+		$item_desc .= 'Message Template';
2745
+		$query_args = array();
2746
+		$edit_array = array();
2747
+		$action_desc = '';
2748
+
2749
+		// if this is "new" then we need to generate the default contexts for the selected messenger/message_type for
2750
+		// user to edit.
2751
+		if ($new) {
2752
+			$GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2753
+			if ($edit_array = $this->_generate_new_templates($messenger_slug, $message_type_slug, $GRP_ID)) {
2754
+				if (empty($edit_array)) {
2755
+					$success = 0;
2756
+				} else {
2757
+					$success = 1;
2758
+					$edit_array = $edit_array[0];
2759
+					$query_args = array(
2760
+						'id'      => $edit_array['GRP_ID'],
2761
+						'context' => $edit_array['MTP_context'],
2762
+						'action'  => 'edit_message_template',
2763
+					);
2764
+				}
2765
+			}
2766
+			$action_desc = 'created';
2767
+		} else {
2768
+			$MTPG = EEM_Message_Template_Group::instance();
2769
+			$MTP = EEM_Message_Template::instance();
2770
+
2771
+
2772
+			// run update for each template field in displayed context
2773
+			if (! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2774
+				EE_Error::add_error(
2775
+					esc_html__(
2776
+						'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2777
+						'event_espresso'
2778
+					),
2779
+					__FILE__,
2780
+					__FUNCTION__,
2781
+					__LINE__
2782
+				);
2783
+				$success = 0;
2784
+			} else {
2785
+				// first validate all fields!
2786
+				// this filter allows client code to add its own validation to the template fields as well.
2787
+				// returning an empty array means everything passed validation.
2788
+				// errors in validation should be represented in an array with the following shape:
2789
+				// array(
2790
+				//   'fieldname' => array(
2791
+				//          'msg' => 'error message'
2792
+				//          'value' => 'value for field producing error'
2793
+				// )
2794
+				$custom_validation = (array) apply_filters(
2795
+					'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2796
+					array(),
2797
+					$this->_req_data['MTP_template_fields'],
2798
+					$context_slug,
2799
+					$messenger_slug,
2800
+					$message_type_slug
2801
+				);
2802
+
2803
+				$system_validation = $MTPG->validate(
2804
+					$this->_req_data['MTP_template_fields'],
2805
+					$context_slug,
2806
+					$messenger_slug,
2807
+					$message_type_slug
2808
+				);
2809
+
2810
+				$system_validation = ! is_array($system_validation) && $system_validation ? array()
2811
+					: $system_validation;
2812
+				$validates = array_merge($custom_validation, $system_validation);
2813
+
2814
+				// if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2815
+				// appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2816
+				//  WE need to make sure there is no actual error messages in validates.
2817
+				if (is_array($validates) && ! empty($validates)) {
2818
+					// add the transient so when the form loads we know which fields to highlight
2819
+					$this->_add_transient('edit_message_template', $validates);
2820
+
2821
+					$success = 0;
2822
+
2823
+					// setup notices
2824
+					foreach ($validates as $field => $error) {
2825
+						if (isset($error['msg'])) {
2826
+							EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2827
+						}
2828
+					}
2829
+				} else {
2830
+					$set_column_values = array();
2831
+					foreach ($this->_req_data['MTP_template_fields'] as $template_field => $content) {
2832
+						$set_column_values = $this->_set_message_template_column_values($template_field);
2833
+
2834
+						$where_cols_n_values = array(
2835
+							'MTP_ID' => $this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'],
2836
+						);
2837
+						// if they aren't allowed to use all JS, restrict them to just posty-y tags
2838
+						if (! current_user_can('unfiltered_html')) {
2839
+							if (is_array($set_column_values['MTP_content'])) {
2840
+								foreach ($set_column_values['MTP_content'] as $key => $value) {
2841
+									// remove slashes so wp_kses works properly (its wp_kses_stripslashes() function
2842
+									// only removes slashes from double-quotes, so attributes using single quotes always
2843
+									// appear invalid.) But currently the models expect slashed data, so after wp_kses
2844
+									// runs we need to re-slash the data. Sheesh. See
2845
+									// https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
2846
+									$set_column_values['MTP_content'][ $key ] = addslashes(
2847
+										wp_kses(
2848
+											stripslashes($value),
2849
+											wp_kses_allowed_html('post')
2850
+										)
2851
+									);
2852
+								}
2853
+							} else {
2854
+								$set_column_values['MTP_content'] = wp_kses(
2855
+									$set_column_values['MTP_content'],
2856
+									wp_kses_allowed_html('post')
2857
+								);
2858
+							}
2859
+						}
2860
+						$message_template_fields = array(
2861
+							'GRP_ID'             => $set_column_values['GRP_ID'],
2862
+							'MTP_template_field' => $set_column_values['MTP_template_field'],
2863
+							'MTP_context'        => $set_column_values['MTP_context'],
2864
+							'MTP_content'        => $set_column_values['MTP_content'],
2865
+						);
2866
+						if ($updated = $MTP->update($message_template_fields, array($where_cols_n_values))) {
2867
+							if ($updated === false) {
2868
+								EE_Error::add_error(
2869
+									sprintf(
2870
+										esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
2871
+										$template_field
2872
+									),
2873
+									__FILE__,
2874
+									__FUNCTION__,
2875
+									__LINE__
2876
+								);
2877
+							} else {
2878
+								$success = 1;
2879
+							}
2880
+						} else {
2881
+							// only do this logic if we don't have a MTP_ID for this field
2882
+							if (empty($this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'])) {
2883
+								// this has already been through the template field validator and sanitized, so it will be
2884
+								// safe to insert this field.  Why insert?  This typically happens when we introduce a new
2885
+								// message template field in a messenger/message type and existing users don't have the
2886
+								// default setup for it.
2887
+								// @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2888
+								$updated = $MTP->insert($message_template_fields);
2889
+								if (! $updated || is_wp_error($updated)) {
2890
+									EE_Error::add_error(
2891
+										sprintf(
2892
+											esc_html__('%s field could not be updated.', 'event_espresso'),
2893
+											$template_field
2894
+										),
2895
+										__FILE__,
2896
+										__FUNCTION__,
2897
+										__LINE__
2898
+									);
2899
+									$success = 0;
2900
+								} else {
2901
+									$success = 1;
2902
+								}
2903
+							}
2904
+						}
2905
+						$action_desc = 'updated';
2906
+					}
2907
+
2908
+					// we can use the last set_column_values for the MTPG update (because its the same for all of these specific MTPs)
2909
+					$mtpg_fields = array(
2910
+						'MTP_user_id'      => $set_column_values['MTP_user_id'],
2911
+						'MTP_messenger'    => $set_column_values['MTP_messenger'],
2912
+						'MTP_message_type' => $set_column_values['MTP_message_type'],
2913
+						'MTP_is_global'    => $set_column_values['MTP_is_global'],
2914
+						'MTP_is_override'  => $set_column_values['MTP_is_override'],
2915
+						'MTP_deleted'      => $set_column_values['MTP_deleted'],
2916
+						'MTP_is_active'    => $set_column_values['MTP_is_active'],
2917
+						'MTP_name'         => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_name'])
2918
+							? $this->_req_data['ee_msg_non_global_fields']['MTP_name']
2919
+							: '',
2920
+						'MTP_description'  => ! empty($this->_req_data['ee_msg_non_global_fields']['MTP_description'])
2921
+							? $this->_req_data['ee_msg_non_global_fields']['MTP_description']
2922
+							: '',
2923
+					);
2924
+
2925
+					$mtpg_where = array('GRP_ID' => $set_column_values['GRP_ID']);
2926
+					$updated = $MTPG->update($mtpg_fields, array($mtpg_where));
2927
+
2928
+					if ($updated === false) {
2929
+						EE_Error::add_error(
2930
+							sprintf(
2931
+								esc_html__(
2932
+									'The Message Template Group (%d) was NOT updated for some reason',
2933
+									'event_espresso'
2934
+								),
2935
+								$set_column_values['GRP_ID']
2936
+							),
2937
+							__FILE__,
2938
+							__FUNCTION__,
2939
+							__LINE__
2940
+						);
2941
+					} else {
2942
+						// k now we need to ensure the template_pack and template_variation fields are set.
2943
+						$template_pack = ! empty($this->_req_data['MTP_template_pack'])
2944
+							? $this->_req_data['MTP_template_pack']
2945
+							: 'default';
2946
+
2947
+						$template_variation = ! empty($this->_req_data['MTP_template_variation'])
2948
+							? $this->_req_data['MTP_template_variation']
2949
+							: 'default';
2950
+
2951
+						$mtpg_obj = $MTPG->get_one_by_ID($set_column_values['GRP_ID']);
2952
+						if ($mtpg_obj instanceof EE_Message_Template_Group) {
2953
+							$mtpg_obj->set_template_pack_name($template_pack);
2954
+							$mtpg_obj->set_template_pack_variation($template_variation);
2955
+						}
2956
+						$success = 1;
2957
+					}
2958
+				}
2959
+			}
2960
+		}
2961
+
2962
+		// we return things differently if doing ajax
2963
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2964
+			$this->_template_args['success'] = $success;
2965
+			$this->_template_args['error'] = ! $success ? true : false;
2966
+			$this->_template_args['content'] = '';
2967
+			$this->_template_args['data'] = array(
2968
+				'grpID'        => $edit_array['GRP_ID'],
2969
+				'templateName' => $edit_array['template_name'],
2970
+			);
2971
+			if ($success) {
2972
+				EE_Error::overwrite_success();
2973
+				EE_Error::add_success(
2974
+					esc_html__(
2975
+						'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.',
2976
+						'event_espresso'
2977
+					)
2978
+				);
2979
+			}
2980
+
2981
+			$this->_return_json();
2982
+		}
2983
+
2984
+
2985
+		// was a test send triggered?
2986
+		if (isset($this->_req_data['test_button'])) {
2987
+			EE_Error::overwrite_success();
2988
+			$this->_do_test_send($context_slug, $messenger_slug, $message_type_slug);
2989
+			$override = true;
2990
+		}
2991
+
2992
+		if (empty($query_args)) {
2993
+			$query_args = array(
2994
+				'id'      => $this->_req_data['GRP_ID'],
2995
+				'context' => $context_slug,
2996
+				'action'  => 'edit_message_template',
2997
+			);
2998
+		}
2999
+
3000
+		$this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
3001
+	}
3002
+
3003
+
3004
+	/**
3005
+	 * processes a test send request to do an actual messenger delivery test for the given message template being tested
3006
+	 *
3007
+	 * @param  string $context      what context being tested
3008
+	 * @param  string $messenger    messenger being tested
3009
+	 * @param  string $message_type message type being tested
3010
+	 * @throws EE_Error
3011
+	 * @throws InvalidArgumentException
3012
+	 * @throws InvalidDataTypeException
3013
+	 * @throws InvalidInterfaceException
3014
+	 */
3015
+	protected function _do_test_send($context, $messenger, $message_type)
3016
+	{
3017
+		// set things up for preview
3018
+		$this->_req_data['messenger'] = $messenger;
3019
+		$this->_req_data['message_type'] = $message_type;
3020
+		$this->_req_data['context'] = $context;
3021
+		$this->_req_data['GRP_ID'] = isset($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : '';
3022
+		$active_messenger = $this->_message_resource_manager->get_active_messenger($messenger);
3023
+
3024
+		// let's save any existing fields that might be required by the messenger
3025
+		if (isset($this->_req_data['test_settings_fld'])
3026
+			&& $active_messenger instanceof EE_messenger
3027
+			&& apply_filters(
3028
+				'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3029
+				true,
3030
+				$this->_req_data['test_settings_fld'],
3031
+				$active_messenger
3032
+			)
3033
+		) {
3034
+			$active_messenger->set_existing_test_settings($this->_req_data['test_settings_fld']);
3035
+		}
3036
+
3037
+		/**
3038
+		 * Use filter to add additional controls on whether message can send or not
3039
+		 */
3040
+		if (apply_filters(
3041
+			'FHEE__Messages_Admin_Page__do_test_send__can_send',
3042
+			true,
3043
+			$context,
3044
+			$this->_req_data,
3045
+			$messenger,
3046
+			$message_type
3047
+		)) {
3048
+			if (EEM_Event::instance()->count() > 0) {
3049
+				$success = $this->_preview_message(true);
3050
+				if ($success) {
3051
+					EE_Error::add_success(__('Test message sent', 'event_espresso'));
3052
+				} else {
3053
+					EE_Error::add_error(
3054
+						esc_html__('The test message was not sent', 'event_espresso'),
3055
+						__FILE__,
3056
+						__FUNCTION__,
3057
+						__LINE__
3058
+					);
3059
+				}
3060
+			} else {
3061
+				$this->noEventsErrorMessage(true);
3062
+			}
3063
+		}
3064
+	}
3065
+
3066
+
3067
+	/**
3068
+	 * _generate_new_templates
3069
+	 * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3070
+	 * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3071
+	 * for the event.
3072
+	 *
3073
+	 *
3074
+	 * @param  string $messenger     the messenger we are generating templates for
3075
+	 * @param array   $message_types array of message types that the templates are generated for.
3076
+	 * @param int     $GRP_ID        If this is a custom template being generated then a GRP_ID needs to be included to
3077
+	 *                               indicate the message_template_group being used as the base.
3078
+	 *
3079
+	 * @param bool    $global
3080
+	 *
3081
+	 * @return array|bool array of data required for the redirect to the correct edit page or bool if
3082
+	 *                               encountering problems.
3083
+	 * @throws EE_Error
3084
+	 */
3085
+	protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3086
+	{
3087
+
3088
+		// if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3089
+		// just don't generate any templates.
3090
+		if (empty($message_types)) {
3091
+			return true;
3092
+		}
3093
+
3094
+		return EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3095
+	}
3096
+
3097
+
3098
+	/**
3099
+	 * [_trash_or_restore_message_template]
3100
+	 *
3101
+	 * @param  boolean $trash whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3102
+	 * @param boolean  $all   whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3103
+	 *                        an individual context (FALSE).
3104
+	 * @return void
3105
+	 * @throws EE_Error
3106
+	 * @throws InvalidArgumentException
3107
+	 * @throws InvalidDataTypeException
3108
+	 * @throws InvalidInterfaceException
3109
+	 */
3110
+	protected function _trash_or_restore_message_template($trash = true, $all = false)
3111
+	{
3112
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3113
+		$MTP = EEM_Message_Template_Group::instance();
3114
+
3115
+		$success = 1;
3116
+
3117
+		// incoming GRP_IDs
3118
+		if ($all) {
3119
+			// Checkboxes
3120
+			if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3121
+				// if array has more than one element then success message should be plural.
3122
+				// todo: what about nonce?
3123
+				$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3124
+
3125
+				// cycle through checkboxes
3126
+				while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3127
+					$trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3128
+					if (! $trashed_or_restored) {
3129
+						$success = 0;
3130
+					}
3131
+				}
3132
+			} else {
3133
+				// grab single GRP_ID and handle
3134
+				$GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
3135
+				if (! empty($GRP_ID)) {
3136
+					$trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3137
+					if (! $trashed_or_restored) {
3138
+						$success = 0;
3139
+					}
3140
+				} else {
3141
+					$success = 0;
3142
+				}
3143
+			}
3144
+		}
3145
+
3146
+		$action_desc = $trash
3147
+			? esc_html__('moved to the trash', 'event_espresso')
3148
+			: esc_html__('restored', 'event_espresso');
3149
+
3150
+		$action_desc = ! empty($this->_req_data['template_switch']) ? esc_html__('switched', 'event_espresso') : $action_desc;
3151
+
3152
+		$item_desc = $all ? _n(
3153
+			'Message Template Group',
3154
+			'Message Template Groups',
3155
+			$success,
3156
+			'event_espresso'
3157
+		) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3158
+
3159
+		$item_desc = ! empty($this->_req_data['template_switch']) ? _n(
3160
+			'template',
3161
+			'templates',
3162
+			$success,
3163
+			'event_espresso'
3164
+		) : $item_desc;
3165
+
3166
+		$this->_redirect_after_action($success, $item_desc, $action_desc, array());
3167
+	}
3168
+
3169
+
3170
+	/**
3171
+	 * [_delete_message_template]
3172
+	 * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3173
+	 *
3174
+	 * @return void
3175
+	 * @throws EE_Error
3176
+	 * @throws InvalidArgumentException
3177
+	 * @throws InvalidDataTypeException
3178
+	 * @throws InvalidInterfaceException
3179
+	 */
3180
+	protected function _delete_message_template()
3181
+	{
3182
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3183
+
3184
+		// checkboxes
3185
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3186
+			// if array has more than one element then success message should be plural
3187
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3188
+
3189
+			// cycle through bulk action checkboxes
3190
+			while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3191
+				$success = $this->_delete_mtp_permanently($GRP_ID);
3192
+			}
3193
+		} else {
3194
+			// grab single grp_id and delete
3195
+			$GRP_ID = absint($this->_req_data['id']);
3196
+			$success = $this->_delete_mtp_permanently($GRP_ID);
3197
+		}
3198
+
3199
+		$this->_redirect_after_action($success, 'Message Templates', 'deleted', array());
3200
+	}
3201
+
3202
+
3203
+	/**
3204
+	 * helper for permanently deleting a mtP group and all related message_templates
3205
+	 *
3206
+	 * @param  int  $GRP_ID        The group being deleted
3207
+	 * @param  bool $include_group whether to delete the Message Template Group as well.
3208
+	 * @return bool boolean to indicate the success of the deletes or not.
3209
+	 * @throws EE_Error
3210
+	 * @throws InvalidArgumentException
3211
+	 * @throws InvalidDataTypeException
3212
+	 * @throws InvalidInterfaceException
3213
+	 */
3214
+	private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3215
+	{
3216
+		$success = 1;
3217
+		$MTPG = EEM_Message_Template_Group::instance();
3218
+		// first let's GET this group
3219
+		$MTG = $MTPG->get_one_by_ID($GRP_ID);
3220
+		// then delete permanently all the related Message Templates
3221
+		$deleted = $MTG->delete_related_permanently('Message_Template');
3222
+
3223
+		if ($deleted === 0) {
3224
+			$success = 0;
3225
+		}
3226
+
3227
+		// now delete permanently this particular group
3228
+
3229
+		if ($include_group && ! $MTG->delete_permanently()) {
3230
+			$success = 0;
3231
+		}
3232
+
3233
+		return $success;
3234
+	}
3235
+
3236
+
3237
+	/**
3238
+	 *    _learn_more_about_message_templates_link
3239
+	 *
3240
+	 * @access protected
3241
+	 * @return string
3242
+	 */
3243
+	protected function _learn_more_about_message_templates_link()
3244
+	{
3245
+		return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3246
+			   . esc_html__('learn more about how message templates works', 'event_espresso')
3247
+			   . '</a>';
3248
+	}
3249
+
3250
+
3251
+	/**
3252
+	 * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3253
+	 * ajax and other routes.
3254
+	 *
3255
+	 * @return void
3256
+	 * @throws DomainException
3257
+	 */
3258
+	protected function _settings()
3259
+	{
3260
+
3261
+
3262
+		$this->_set_m_mt_settings();
3263
+
3264
+		$selected_messenger = isset($this->_req_data['selected_messenger'])
3265
+			? $this->_req_data['selected_messenger']
3266
+			: 'email';
3267
+
3268
+		// let's setup the messenger tabs
3269
+		$this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
3270
+			$this->_m_mt_settings['messenger_tabs'],
3271
+			'messenger_links',
3272
+			'|',
3273
+			$selected_messenger
3274
+		);
3275
+		$this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3276
+		$this->_template_args['after_admin_page_content'] = '</div><!-- end .ui-widget -->';
3277
+
3278
+		$this->display_admin_page_with_sidebar();
3279
+	}
3280
+
3281
+
3282
+	/**
3283
+	 * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3284
+	 *
3285
+	 * @access protected
3286
+	 * @return void
3287
+	 * @throws DomainException
3288
+	 */
3289
+	protected function _set_m_mt_settings()
3290
+	{
3291
+		// first if this is already set then lets get out no need to regenerate data.
3292
+		if (! empty($this->_m_mt_settings)) {
3293
+			return;
3294
+		}
3295
+
3296
+		// get all installed messengers and message_types
3297
+		/** @type EE_messenger[] $messengers */
3298
+		$messengers = $this->_message_resource_manager->installed_messengers();
3299
+		/** @type EE_message_type[] $message_types */
3300
+		$message_types = $this->_message_resource_manager->installed_message_types();
3301
+
3302
+
3303
+		// assemble the array for the _tab_text_links helper
3304
+
3305
+		foreach ($messengers as $messenger) {
3306
+			$this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = array(
3307
+				'label' => ucwords($messenger->label['singular']),
3308
+				'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3309
+					? 'messenger-active'
3310
+					: '',
3311
+				'href'  => $messenger->name,
3312
+				'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3313
+				'slug'  => $messenger->name,
3314
+				'obj'   => $messenger,
3315
+			);
3316
+
3317
+
3318
+			$message_types_for_messenger = $messenger->get_valid_message_types();
3319
+
3320
+			foreach ($message_types as $message_type) {
3321
+				// first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3322
+				// it shouldn't show in either the inactive OR active metabox.
3323
+				if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3324
+					continue;
3325
+				}
3326
+
3327
+				$a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3328
+					$messenger->name,
3329
+					$message_type->name
3330
+				)
3331
+					? 'active'
3332
+					: 'inactive';
3333
+
3334
+				$this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = array(
3335
+					'label'    => ucwords($message_type->label['singular']),
3336
+					'class'    => 'message-type-' . $a_or_i,
3337
+					'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3338
+					'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3339
+					'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3340
+					'title'    => $a_or_i === 'active'
3341
+						? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3342
+						: esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3343
+					'content'  => $a_or_i === 'active'
3344
+						? $this->_message_type_settings_content($message_type, $messenger, true)
3345
+						: $this->_message_type_settings_content($message_type, $messenger),
3346
+					'slug'     => $message_type->name,
3347
+					'active'   => $a_or_i === 'active',
3348
+					'obj'      => $message_type,
3349
+				);
3350
+			}
3351
+		}
3352
+	}
3353
+
3354
+
3355
+	/**
3356
+	 * This just prepares the content for the message type settings
3357
+	 *
3358
+	 * @param  EE_message_type $message_type The message type object
3359
+	 * @param  EE_messenger    $messenger    The messenger object
3360
+	 * @param  boolean         $active       Whether the message type is active or not
3361
+	 * @return string html output for the content
3362
+	 * @throws DomainException
3363
+	 */
3364
+	protected function _message_type_settings_content($message_type, $messenger, $active = false)
3365
+	{
3366
+		// get message type fields
3367
+		$fields = $message_type->get_admin_settings_fields();
3368
+		$settings_template_args['template_form_fields'] = '';
3369
+
3370
+		if (! empty($fields) && $active) {
3371
+			$existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3372
+			foreach ($fields as $fldname => $fldprops) {
3373
+				$field_id = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3374
+				$template_form_field[ $field_id ] = array(
3375
+					'name'       => 'message_type_settings[' . $fldname . ']',
3376
+					'label'      => $fldprops['label'],
3377
+					'input'      => $fldprops['field_type'],
3378
+					'type'       => $fldprops['value_type'],
3379
+					'required'   => $fldprops['required'],
3380
+					'validation' => $fldprops['validation'],
3381
+					'value'      => isset($existing_settings[ $fldname ])
3382
+						? $existing_settings[ $fldname ]
3383
+						: $fldprops['default'],
3384
+					'options'    => isset($fldprops['options'])
3385
+						? $fldprops['options']
3386
+						: array(),
3387
+					'default'    => isset($existing_settings[ $fldname ])
3388
+						? $existing_settings[ $fldname ]
3389
+						: $fldprops['default'],
3390
+					'css_class'  => 'no-drag',
3391
+					'format'     => $fldprops['format'],
3392
+				);
3393
+			}
3394
+
3395
+
3396
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3397
+				? $this->_generate_admin_form_fields(
3398
+					$template_form_field,
3399
+					'string',
3400
+					'ee_mt_activate_form'
3401
+				)
3402
+				: '';
3403
+		}
3404
+
3405
+		$settings_template_args['description'] = $message_type->description;
3406
+		// we also need some hidden fields
3407
+		$settings_template_args['hidden_fields'] = array(
3408
+			'message_type_settings[messenger]'    => array(
3409
+				'type'  => 'hidden',
3410
+				'value' => $messenger->name,
3411
+			),
3412
+			'message_type_settings[message_type]' => array(
3413
+				'type'  => 'hidden',
3414
+				'value' => $message_type->name,
3415
+			),
3416
+			'type'                                => array(
3417
+				'type'  => 'hidden',
3418
+				'value' => 'message_type',
3419
+			),
3420
+		);
3421
+
3422
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3423
+			$settings_template_args['hidden_fields'],
3424
+			'array'
3425
+		);
3426
+		$settings_template_args['show_form'] = empty($settings_template_args['template_form_fields'])
3427
+			? ' hidden'
3428
+			: '';
3429
+
3430
+
3431
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3432
+		$content = EEH_Template::display_template($template, $settings_template_args, true);
3433
+
3434
+		return $content;
3435
+	}
3436
+
3437
+
3438
+	/**
3439
+	 * Generate all the metaboxes for the message types and register them for the messages settings page.
3440
+	 *
3441
+	 * @access protected
3442
+	 * @return void
3443
+	 * @throws DomainException
3444
+	 */
3445
+	protected function _messages_settings_metaboxes()
3446
+	{
3447
+		$this->_set_m_mt_settings();
3448
+		$m_boxes = $mt_boxes = array();
3449
+		$m_template_args = $mt_template_args = array();
3450
+
3451
+		$selected_messenger = isset($this->_req_data['selected_messenger'])
3452
+			? $this->_req_data['selected_messenger']
3453
+			: 'email';
3454
+
3455
+		if (isset($this->_m_mt_settings['messenger_tabs'])) {
3456
+			foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3457
+				$hide_on_message = $this->_message_resource_manager->is_messenger_active($messenger) ? '' : 'hidden';
3458
+				$hide_off_message = $this->_message_resource_manager->is_messenger_active($messenger) ? 'hidden' : '';
3459
+				// messenger meta boxes
3460
+				$active = $selected_messenger === $messenger;
3461
+				$active_mt_tabs = isset(
3462
+					$this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3463
+				)
3464
+					? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3465
+					: '';
3466
+				$m_boxes[ $messenger . '_a_box' ] = sprintf(
3467
+					esc_html__('%s Settings', 'event_espresso'),
3468
+					$tab_array['label']
3469
+				);
3470
+				$m_template_args[ $messenger . '_a_box' ] = array(
3471
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3472
+					'inactive_message_types' => isset(
3473
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3474
+					)
3475
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3476
+						: '',
3477
+					'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3478
+					'hidden'                 => $active ? '' : ' hidden',
3479
+					'hide_on_message'        => $hide_on_message,
3480
+					'messenger'              => $messenger,
3481
+					'active'                 => $active,
3482
+				);
3483
+				// message type meta boxes
3484
+				// (which is really just the inactive container for each messenger
3485
+				// showing inactive message types for that messenger)
3486
+				$mt_boxes[ $messenger . '_i_box' ] = esc_html__('Inactive Message Types', 'event_espresso');
3487
+				$mt_template_args[ $messenger . '_i_box' ] = array(
3488
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3489
+					'inactive_message_types' => isset(
3490
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3491
+					)
3492
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3493
+						: '',
3494
+					'hidden'                 => $active ? '' : ' hidden',
3495
+					'hide_on_message'        => $hide_on_message,
3496
+					'hide_off_message'       => $hide_off_message,
3497
+					'messenger'              => $messenger,
3498
+					'active'                 => $active,
3499
+				);
3500
+			}
3501
+		}
3502
+
3503
+
3504
+		// register messenger metaboxes
3505
+		$m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3506
+		foreach ($m_boxes as $box => $label) {
3507
+			$callback_args = array('template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]);
3508
+			$msgr = str_replace('_a_box', '', $box);
3509
+			add_meta_box(
3510
+				'espresso_' . $msgr . '_settings',
3511
+				$label,
3512
+				function ($post, $metabox) {
3513
+					echo EEH_Template::display_template(
3514
+						$metabox["args"]["template_path"],
3515
+						$metabox["args"]["template_args"],
3516
+						true
3517
+					);
3518
+				},
3519
+				$this->_current_screen->id,
3520
+				'normal',
3521
+				'high',
3522
+				$callback_args
3523
+			);
3524
+		}
3525
+
3526
+		// register message type metaboxes
3527
+		$mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3528
+		foreach ($mt_boxes as $box => $label) {
3529
+			$callback_args = array(
3530
+				'template_path' => $mt_template_path,
3531
+				'template_args' => $mt_template_args[ $box ],
3532
+			);
3533
+			$mt = str_replace('_i_box', '', $box);
3534
+			add_meta_box(
3535
+				'espresso_' . $mt . '_inactive_mts',
3536
+				$label,
3537
+				function ($post, $metabox) {
3538
+					echo EEH_Template::display_template(
3539
+						$metabox["args"]["template_path"],
3540
+						$metabox["args"]["template_args"],
3541
+						true
3542
+					);
3543
+				},
3544
+				$this->_current_screen->id,
3545
+				'side',
3546
+				'high',
3547
+				$callback_args
3548
+			);
3549
+		}
3550
+
3551
+		// register metabox for global messages settings but only when on the main site.  On single site installs this
3552
+		// will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3553
+		if (is_main_site()) {
3554
+			add_meta_box(
3555
+				'espresso_global_message_settings',
3556
+				esc_html__('Global Message Settings', 'event_espresso'),
3557
+				array($this, 'global_messages_settings_metabox_content'),
3558
+				$this->_current_screen->id,
3559
+				'normal',
3560
+				'low',
3561
+				array()
3562
+			);
3563
+		}
3564
+	}
3565
+
3566
+
3567
+	/**
3568
+	 *  This generates the content for the global messages settings metabox.
3569
+	 *
3570
+	 * @return string
3571
+	 * @throws EE_Error
3572
+	 * @throws InvalidArgumentException
3573
+	 * @throws ReflectionException
3574
+	 * @throws InvalidDataTypeException
3575
+	 * @throws InvalidInterfaceException
3576
+	 */
3577
+	public function global_messages_settings_metabox_content()
3578
+	{
3579
+		$form = $this->_generate_global_settings_form();
3580
+		echo $form->form_open(
3581
+			$this->add_query_args_and_nonce(array('action' => 'update_global_settings'), EE_MSG_ADMIN_URL),
3582
+			'POST'
3583
+		)
3584
+			 . $form->get_html()
3585
+			 . $form->form_close();
3586
+	}
3587
+
3588
+
3589
+	/**
3590
+	 * This generates and returns the form object for the global messages settings.
3591
+	 *
3592
+	 * @return EE_Form_Section_Proper
3593
+	 * @throws EE_Error
3594
+	 * @throws InvalidArgumentException
3595
+	 * @throws ReflectionException
3596
+	 * @throws InvalidDataTypeException
3597
+	 * @throws InvalidInterfaceException
3598
+	 */
3599
+	protected function _generate_global_settings_form()
3600
+	{
3601
+		EE_Registry::instance()->load_helper('HTML');
3602
+		/** @var EE_Network_Core_Config $network_config */
3603
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3604
+
3605
+		return new EE_Form_Section_Proper(
3606
+			array(
3607
+				'name'            => 'global_messages_settings',
3608
+				'html_id'         => 'global_messages_settings',
3609
+				'html_class'      => 'form-table',
3610
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3611
+				'subsections'     => apply_filters(
3612
+					'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3613
+					array(
3614
+						'do_messages_on_same_request' => new EE_Select_Input(
3615
+							array(
3616
+								true  => esc_html__("On the same request", "event_espresso"),
3617
+								false => esc_html__("On a separate request", "event_espresso"),
3618
+							),
3619
+							array(
3620
+								'default'         => $network_config->do_messages_on_same_request,
3621
+								'html_label_text' => esc_html__(
3622
+									'Generate and send all messages:',
3623
+									'event_espresso'
3624
+								),
3625
+								'html_help_text'  => esc_html__(
3626
+									'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.',
3627
+									'event_espresso'
3628
+								),
3629
+							)
3630
+						),
3631
+						'delete_threshold'            => new EE_Select_Input(
3632
+							array(
3633
+								0  => esc_html__('Forever', 'event_espresso'),
3634
+								3  => esc_html__('3 Months', 'event_espresso'),
3635
+								6  => esc_html__('6 Months', 'event_espresso'),
3636
+								9  => esc_html__('9 Months', 'event_espresso'),
3637
+								12 => esc_html__('12 Months', 'event_espresso'),
3638
+								24 => esc_html__('24 Months', 'event_espresso'),
3639
+								36 => esc_html__('36 Months', 'event_espresso'),
3640
+							),
3641
+							array(
3642
+								'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3643
+								'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3644
+								'html_help_text'  => esc_html__(
3645
+									'You can control how long a record of processed messages is kept via this option.',
3646
+									'event_espresso'
3647
+								),
3648
+							)
3649
+						),
3650
+						'update_settings'             => new EE_Submit_Input(
3651
+							array(
3652
+								'default'         => esc_html__('Update', 'event_espresso'),
3653
+								'html_label_text' => '&nbsp',
3654
+							)
3655
+						),
3656
+					)
3657
+				),
3658
+			)
3659
+		);
3660
+	}
3661
+
3662
+
3663
+	/**
3664
+	 * This handles updating the global settings set on the admin page.
3665
+	 *
3666
+	 * @throws EE_Error
3667
+	 * @throws InvalidDataTypeException
3668
+	 * @throws InvalidInterfaceException
3669
+	 * @throws InvalidArgumentException
3670
+	 * @throws ReflectionException
3671
+	 */
3672
+	protected function _update_global_settings()
3673
+	{
3674
+		/** @var EE_Network_Core_Config $network_config */
3675
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3676
+		$messages_config = EE_Registry::instance()->CFG->messages;
3677
+		$form = $this->_generate_global_settings_form();
3678
+		if ($form->was_submitted()) {
3679
+			$form->receive_form_submission();
3680
+			if ($form->is_valid()) {
3681
+				$valid_data = $form->valid_data();
3682
+				foreach ($valid_data as $property => $value) {
3683
+					$setter = 'set_' . $property;
3684
+					if (method_exists($network_config, $setter)) {
3685
+						$network_config->{$setter}($value);
3686
+					} elseif (property_exists($network_config, $property)
3687
+						&& $network_config->{$property} !== $value
3688
+					) {
3689
+						$network_config->{$property} = $value;
3690
+					} elseif (property_exists($messages_config, $property)
3691
+						&& $messages_config->{$property} !== $value
3692
+					) {
3693
+						$messages_config->{$property} = $value;
3694
+					}
3695
+				}
3696
+				// only update if the form submission was valid!
3697
+				EE_Registry::instance()->NET_CFG->update_config(true, false);
3698
+				EE_Registry::instance()->CFG->update_espresso_config();
3699
+				EE_Error::overwrite_success();
3700
+				EE_Error::add_success(__('Global message settings were updated', 'event_espresso'));
3701
+			}
3702
+		}
3703
+		$this->_redirect_after_action(0, '', '', array('action' => 'settings'), true);
3704
+	}
3705
+
3706
+
3707
+	/**
3708
+	 * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3709
+	 *
3710
+	 * @param  array $tab_array This is an array of message type tab details used to generate the tabs
3711
+	 * @return string html formatted tabs
3712
+	 * @throws DomainException
3713
+	 */
3714
+	protected function _get_mt_tabs($tab_array)
3715
+	{
3716
+		$tab_array = (array) $tab_array;
3717
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3718
+		$tabs = '';
3719
+
3720
+		foreach ($tab_array as $tab) {
3721
+			$tabs .= EEH_Template::display_template($template, $tab, true);
3722
+		}
3723
+
3724
+		return $tabs;
3725
+	}
3726
+
3727
+
3728
+	/**
3729
+	 * This prepares the content of the messenger meta box admin settings
3730
+	 *
3731
+	 * @param  EE_messenger $messenger The messenger we're setting up content for
3732
+	 * @return string html formatted content
3733
+	 * @throws DomainException
3734
+	 */
3735
+	protected function _get_messenger_box_content(EE_messenger $messenger)
3736
+	{
3737
+
3738
+		$fields = $messenger->get_admin_settings_fields();
3739
+		$settings_template_args['template_form_fields'] = '';
3740
+
3741
+		// is $messenger active?
3742
+		$settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3743
+
3744
+
3745
+		if (! empty($fields)) {
3746
+			$existing_settings = $messenger->get_existing_admin_settings();
3747
+
3748
+			foreach ($fields as $fldname => $fldprops) {
3749
+				$field_id = $messenger->name . '-' . $fldname;
3750
+				$template_form_field[ $field_id ] = array(
3751
+					'name'       => 'messenger_settings[' . $field_id . ']',
3752
+					'label'      => $fldprops['label'],
3753
+					'input'      => $fldprops['field_type'],
3754
+					'type'       => $fldprops['value_type'],
3755
+					'required'   => $fldprops['required'],
3756
+					'validation' => $fldprops['validation'],
3757
+					'value'      => isset($existing_settings[ $field_id ])
3758
+						? $existing_settings[ $field_id ]
3759
+						: $fldprops['default'],
3760
+					'css_class'  => '',
3761
+					'format'     => $fldprops['format'],
3762
+				);
3763
+			}
3764
+
3765
+
3766
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3767
+				? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3768
+				: '';
3769
+		}
3770
+
3771
+		// we also need some hidden fields
3772
+		$settings_template_args['hidden_fields'] = array(
3773
+			'messenger_settings[messenger]' => array(
3774
+				'type'  => 'hidden',
3775
+				'value' => $messenger->name,
3776
+			),
3777
+			'type'                          => array(
3778
+				'type'  => 'hidden',
3779
+				'value' => 'messenger',
3780
+			),
3781
+		);
3782
+
3783
+		// make sure any active message types that are existing are included in the hidden fields
3784
+		if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3785
+			foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3786
+				$settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = array(
3787
+					'type'  => 'hidden',
3788
+					'value' => $mt,
3789
+				);
3790
+			}
3791
+		}
3792
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3793
+			$settings_template_args['hidden_fields'],
3794
+			'array'
3795
+		);
3796
+		$active = $this->_message_resource_manager->is_messenger_active($messenger->name);
3797
+
3798
+		$settings_template_args['messenger'] = $messenger->name;
3799
+		$settings_template_args['description'] = $messenger->description;
3800
+		$settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3801
+
3802
+
3803
+		$settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3804
+			$messenger->name
3805
+		)
3806
+			? $settings_template_args['show_hide_edit_form']
3807
+			: ' hidden';
3808
+
3809
+		$settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3810
+			? ' hidden'
3811
+			: $settings_template_args['show_hide_edit_form'];
3812
+
3813
+
3814
+		$settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3815
+		$settings_template_args['nonce'] = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3816
+		$settings_template_args['on_off_status'] = $active ? true : false;
3817
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3818
+		$content = EEH_Template::display_template(
3819
+			$template,
3820
+			$settings_template_args,
3821
+			true
3822
+		);
3823
+
3824
+		return $content;
3825
+	}
3826
+
3827
+
3828
+	/**
3829
+	 * used by ajax on the messages settings page to activate|deactivate the messenger
3830
+	 *
3831
+	 * @throws DomainException
3832
+	 * @throws EE_Error
3833
+	 * @throws InvalidDataTypeException
3834
+	 * @throws InvalidInterfaceException
3835
+	 * @throws InvalidArgumentException
3836
+	 * @throws ReflectionException
3837
+	 */
3838
+	public function activate_messenger_toggle()
3839
+	{
3840
+		$success = true;
3841
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3842
+		// let's check that we have required data
3843
+		if (! isset($this->_req_data['messenger'])) {
3844
+			EE_Error::add_error(
3845
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3846
+				__FILE__,
3847
+				__FUNCTION__,
3848
+				__LINE__
3849
+			);
3850
+			$success = false;
3851
+		}
3852
+
3853
+		// do a nonce check here since we're not arriving via a normal route
3854
+		$nonce = isset($this->_req_data['activate_nonce'])
3855
+			? sanitize_text_field($this->_req_data['activate_nonce'])
3856
+			: '';
3857
+		$nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3858
+
3859
+		$this->_verify_nonce($nonce, $nonce_ref);
3860
+
3861
+
3862
+		if (! isset($this->_req_data['status'])) {
3863
+			EE_Error::add_error(
3864
+				esc_html__(
3865
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3866
+					'event_espresso'
3867
+				),
3868
+				__FILE__,
3869
+				__FUNCTION__,
3870
+				__LINE__
3871
+			);
3872
+			$success = false;
3873
+		}
3874
+
3875
+		// do check to verify we have a valid status.
3876
+		$status = $this->_req_data['status'];
3877
+
3878
+		if ($status !== 'off' && $status !== 'on') {
3879
+			EE_Error::add_error(
3880
+				sprintf(
3881
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3882
+					$this->_req_data['status']
3883
+				),
3884
+				__FILE__,
3885
+				__FUNCTION__,
3886
+				__LINE__
3887
+			);
3888
+			$success = false;
3889
+		}
3890
+
3891
+		if ($success) {
3892
+			// made it here?  Stop dawdling then!!
3893
+			$success = $status === 'off'
3894
+				? $this->_deactivate_messenger($this->_req_data['messenger'])
3895
+				: $this->_activate_messenger($this->_req_data['messenger']);
3896
+		}
3897
+
3898
+		$this->_template_args['success'] = $success;
3899
+
3900
+		// no special instructions so let's just do the json return (which should automatically do all the special stuff).
3901
+		$this->_return_json();
3902
+	}
3903
+
3904
+
3905
+	/**
3906
+	 * used by ajax from the messages settings page to activate|deactivate a message type
3907
+	 *
3908
+	 * @throws DomainException
3909
+	 * @throws EE_Error
3910
+	 * @throws ReflectionException
3911
+	 * @throws InvalidDataTypeException
3912
+	 * @throws InvalidInterfaceException
3913
+	 * @throws InvalidArgumentException
3914
+	 */
3915
+	public function activate_mt_toggle()
3916
+	{
3917
+		$success = true;
3918
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3919
+
3920
+		// let's make sure we have the necessary data
3921
+		if (! isset($this->_req_data['message_type'])) {
3922
+			EE_Error::add_error(
3923
+				esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3924
+				__FILE__,
3925
+				__FUNCTION__,
3926
+				__LINE__
3927
+			);
3928
+			$success = false;
3929
+		}
3930
+
3931
+		if (! isset($this->_req_data['messenger'])) {
3932
+			EE_Error::add_error(
3933
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3934
+				__FILE__,
3935
+				__FUNCTION__,
3936
+				__LINE__
3937
+			);
3938
+			$success = false;
3939
+		}
3940
+
3941
+		if (! isset($this->_req_data['status'])) {
3942
+			EE_Error::add_error(
3943
+				esc_html__(
3944
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3945
+					'event_espresso'
3946
+				),
3947
+				__FILE__,
3948
+				__FUNCTION__,
3949
+				__LINE__
3950
+			);
3951
+			$success = false;
3952
+		}
3953
+
3954
+
3955
+		// do check to verify we have a valid status.
3956
+		$status = $this->_req_data['status'];
3957
+
3958
+		if ($status !== 'activate' && $status !== 'deactivate') {
3959
+			EE_Error::add_error(
3960
+				sprintf(
3961
+					esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3962
+					$this->_req_data['status']
3963
+				),
3964
+				__FILE__,
3965
+				__FUNCTION__,
3966
+				__LINE__
3967
+			);
3968
+			$success = false;
3969
+		}
3970
+
3971
+
3972
+		// do a nonce check here since we're not arriving via a normal route
3973
+		$nonce = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3974
+		$nonce_ref = $this->_req_data['message_type'] . '_nonce';
3975
+
3976
+		$this->_verify_nonce($nonce, $nonce_ref);
3977
+
3978
+		if ($success) {
3979
+			// made it here? um, what are you waiting for then?
3980
+			$success = $status === 'deactivate'
3981
+				? $this->_deactivate_message_type_for_messenger(
3982
+					$this->_req_data['messenger'],
3983
+					$this->_req_data['message_type']
3984
+				)
3985
+				: $this->_activate_message_type_for_messenger(
3986
+					$this->_req_data['messenger'],
3987
+					$this->_req_data['message_type']
3988
+				);
3989
+		}
3990
+
3991
+		$this->_template_args['success'] = $success;
3992
+		$this->_return_json();
3993
+	}
3994
+
3995
+
3996
+	/**
3997
+	 * Takes care of processing activating a messenger and preparing the appropriate response.
3998
+	 *
3999
+	 * @param string $messenger_name The name of the messenger being activated
4000
+	 * @return bool
4001
+	 * @throws DomainException
4002
+	 * @throws EE_Error
4003
+	 * @throws InvalidArgumentException
4004
+	 * @throws ReflectionException
4005
+	 * @throws InvalidDataTypeException
4006
+	 * @throws InvalidInterfaceException
4007
+	 */
4008
+	protected function _activate_messenger($messenger_name)
4009
+	{
4010
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4011
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4012
+		$message_types_to_activate = $active_messenger instanceof EE_Messenger
4013
+			? $active_messenger->get_default_message_types()
4014
+			: array();
4015
+
4016
+		// ensure is active
4017
+		$this->_message_resource_manager->activate_messenger($messenger_name, $message_types_to_activate);
4018
+
4019
+		// set response_data for reload
4020
+		foreach ($message_types_to_activate as $message_type_name) {
4021
+			/** @var EE_message_type $message_type */
4022
+			$message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4023
+			if ($this->_message_resource_manager->is_message_type_active_for_messenger(
4024
+				$messenger_name,
4025
+				$message_type_name
4026
+			)
4027
+				&& $message_type instanceof EE_message_type
4028
+			) {
4029
+				$this->_template_args['data']['active_mts'][] = $message_type_name;
4030
+				if ($message_type->get_admin_settings_fields()) {
4031
+					$this->_template_args['data']['mt_reload'][] = $message_type_name;
4032
+				}
4033
+			}
4034
+		}
4035
+
4036
+		// add success message for activating messenger
4037
+		return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4038
+	}
4039
+
4040
+
4041
+	/**
4042
+	 * Takes care of processing deactivating a messenger and preparing the appropriate response.
4043
+	 *
4044
+	 * @param string $messenger_name The name of the messenger being activated
4045
+	 * @return bool
4046
+	 * @throws DomainException
4047
+	 * @throws EE_Error
4048
+	 * @throws InvalidArgumentException
4049
+	 * @throws ReflectionException
4050
+	 * @throws InvalidDataTypeException
4051
+	 * @throws InvalidInterfaceException
4052
+	 */
4053
+	protected function _deactivate_messenger($messenger_name)
4054
+	{
4055
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4056
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4057
+		$this->_message_resource_manager->deactivate_messenger($messenger_name);
4058
+
4059
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4060
+	}
4061
+
4062
+
4063
+	/**
4064
+	 * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4065
+	 *
4066
+	 * @param string $messenger_name    The name of the messenger the message type is being activated for.
4067
+	 * @param string $message_type_name The name of the message type being activated for the messenger
4068
+	 * @return bool
4069
+	 * @throws DomainException
4070
+	 * @throws EE_Error
4071
+	 * @throws InvalidArgumentException
4072
+	 * @throws ReflectionException
4073
+	 * @throws InvalidDataTypeException
4074
+	 * @throws InvalidInterfaceException
4075
+	 */
4076
+	protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4077
+	{
4078
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4079
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4080
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4081
+		$message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4082
+
4083
+		// ensure is active
4084
+		$this->_message_resource_manager->activate_messenger($messenger_name, $message_type_name);
4085
+
4086
+		// set response for load
4087
+		if ($this->_message_resource_manager->is_message_type_active_for_messenger(
4088
+			$messenger_name,
4089
+			$message_type_name
4090
+		)
4091
+		) {
4092
+			$this->_template_args['data']['active_mts'][] = $message_type_name;
4093
+			if ($message_type_to_activate->get_admin_settings_fields()) {
4094
+				$this->_template_args['data']['mt_reload'][] = $message_type_name;
4095
+			}
4096
+		}
4097
+
4098
+		return $this->_setup_response_message_for_activating_messenger_with_message_types(
4099
+			$active_messenger,
4100
+			$message_type_to_activate
4101
+		);
4102
+	}
4103
+
4104
+
4105
+	/**
4106
+	 * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4107
+	 *
4108
+	 * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4109
+	 * @param string $message_type_name The name of the message type being deactivated for the messenger
4110
+	 * @return bool
4111
+	 * @throws DomainException
4112
+	 * @throws EE_Error
4113
+	 * @throws InvalidArgumentException
4114
+	 * @throws ReflectionException
4115
+	 * @throws InvalidDataTypeException
4116
+	 * @throws InvalidInterfaceException
4117
+	 */
4118
+	protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4119
+	{
4120
+		/** @var EE_messenger $active_messenger This will be present because it can't be toggled if it isn't */
4121
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4122
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4123
+		$message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4124
+		$this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4125
+
4126
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4127
+			$active_messenger,
4128
+			$message_type_to_deactivate
4129
+		);
4130
+	}
4131
+
4132
+
4133
+	/**
4134
+	 * This just initializes the defaults for activating messenger and message type responses.
4135
+	 */
4136
+	protected function _prep_default_response_for_messenger_or_message_type_toggle()
4137
+	{
4138
+		$this->_template_args['data']['active_mts'] = array();
4139
+		$this->_template_args['data']['mt_reload'] = array();
4140
+	}
4141
+
4142
+
4143
+	/**
4144
+	 * Setup appropriate response for activating a messenger and/or message types
4145
+	 *
4146
+	 * @param EE_messenger         $messenger
4147
+	 * @param EE_message_type|null $message_type
4148
+	 * @return bool
4149
+	 * @throws DomainException
4150
+	 * @throws EE_Error
4151
+	 * @throws InvalidArgumentException
4152
+	 * @throws ReflectionException
4153
+	 * @throws InvalidDataTypeException
4154
+	 * @throws InvalidInterfaceException
4155
+	 */
4156
+	protected function _setup_response_message_for_activating_messenger_with_message_types(
4157
+		$messenger,
4158
+		EE_Message_Type $message_type = null
4159
+	) {
4160
+		// if $messenger isn't a valid messenger object then get out.
4161
+		if (! $messenger instanceof EE_Messenger) {
4162
+			EE_Error::add_error(
4163
+				esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4164
+				__FILE__,
4165
+				__FUNCTION__,
4166
+				__LINE__
4167
+			);
4168
+
4169
+			return false;
4170
+		}
4171
+		// activated
4172
+		if ($this->_template_args['data']['active_mts']) {
4173
+			EE_Error::overwrite_success();
4174
+			// activated a message type with the messenger
4175
+			if ($message_type instanceof EE_message_type) {
4176
+				EE_Error::add_success(
4177
+					sprintf(
4178
+						esc_html__(
4179
+							'%s message type has been successfully activated with the %s messenger',
4180
+							'event_espresso'
4181
+						),
4182
+						ucwords($message_type->label['singular']),
4183
+						ucwords($messenger->label['singular'])
4184
+					)
4185
+				);
4186
+
4187
+				// if message type was invoice then let's make sure we activate the invoice payment method.
4188
+				if ($message_type->name === 'invoice') {
4189
+					EE_Registry::instance()->load_lib('Payment_Method_Manager');
4190
+					$pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4191
+					if ($pm instanceof EE_Payment_Method) {
4192
+						EE_Error::add_attention(
4193
+							esc_html__(
4194
+								'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.',
4195
+								'event_espresso'
4196
+							)
4197
+						);
4198
+					}
4199
+				}
4200
+				// just toggles the entire messenger
4201
+			} else {
4202
+				EE_Error::add_success(
4203
+					sprintf(
4204
+						esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4205
+						ucwords($messenger->label['singular'])
4206
+					)
4207
+				);
4208
+			}
4209
+
4210
+			return true;
4211
+
4212
+			// possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4213
+			// message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4214
+			// in which case we just give a success message for the messenger being successfully activated.
4215
+		} else {
4216
+			if (! $messenger->get_default_message_types()) {
4217
+				// messenger doesn't have any default message types so still a success.
4218
+				EE_Error::add_success(
4219
+					sprintf(
4220
+						esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4221
+						ucwords($messenger->label['singular'])
4222
+					)
4223
+				);
4224
+
4225
+				return true;
4226
+			} else {
4227
+				EE_Error::add_error(
4228
+					$message_type instanceof EE_message_type
4229
+						? sprintf(
4230
+							esc_html__(
4231
+								'%s message type was not successfully activated with the %s messenger',
4232
+								'event_espresso'
4233
+							),
4234
+							ucwords($message_type->label['singular']),
4235
+							ucwords($messenger->label['singular'])
4236
+						)
4237
+						: sprintf(
4238
+							esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4239
+							ucwords($messenger->label['singular'])
4240
+						),
4241
+					__FILE__,
4242
+					__FUNCTION__,
4243
+					__LINE__
4244
+				);
4245
+
4246
+				return false;
4247
+			}
4248
+		}
4249
+	}
4250
+
4251
+
4252
+	/**
4253
+	 * This sets up the appropriate response for deactivating a messenger and/or message type.
4254
+	 *
4255
+	 * @param EE_messenger         $messenger
4256
+	 * @param EE_message_type|null $message_type
4257
+	 * @return bool
4258
+	 * @throws DomainException
4259
+	 * @throws EE_Error
4260
+	 * @throws InvalidArgumentException
4261
+	 * @throws ReflectionException
4262
+	 * @throws InvalidDataTypeException
4263
+	 * @throws InvalidInterfaceException
4264
+	 */
4265
+	protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4266
+		$messenger,
4267
+		EE_message_type $message_type = null
4268
+	) {
4269
+		EE_Error::overwrite_success();
4270
+
4271
+		// if $messenger isn't a valid messenger object then get out.
4272
+		if (! $messenger instanceof EE_Messenger) {
4273
+			EE_Error::add_error(
4274
+				esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4275
+				__FILE__,
4276
+				__FUNCTION__,
4277
+				__LINE__
4278
+			);
4279
+
4280
+			return false;
4281
+		}
4282
+
4283
+		if ($message_type instanceof EE_message_type) {
4284
+			$message_type_name = $message_type->name;
4285
+			EE_Error::add_success(
4286
+				sprintf(
4287
+					esc_html__(
4288
+						'%s message type has been successfully deactivated for the %s messenger.',
4289
+						'event_espresso'
4290
+					),
4291
+					ucwords($message_type->label['singular']),
4292
+					ucwords($messenger->label['singular'])
4293
+				)
4294
+			);
4295
+		} else {
4296
+			$message_type_name = '';
4297
+			EE_Error::add_success(
4298
+				sprintf(
4299
+					esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4300
+					ucwords($messenger->label['singular'])
4301
+				)
4302
+			);
4303
+		}
4304
+
4305
+		// if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4306
+		if ($messenger->name === 'html' || $message_type_name === 'invoice') {
4307
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
4308
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4309
+			if ($count_updated > 0) {
4310
+				$msg = $message_type_name === 'invoice'
4311
+					? esc_html__(
4312
+						'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.',
4313
+						'event_espresso'
4314
+					)
4315
+					: esc_html__(
4316
+						'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.',
4317
+						'event_espresso'
4318
+					);
4319
+				EE_Error::add_attention($msg);
4320
+			}
4321
+		}
4322
+
4323
+		return true;
4324
+	}
4325
+
4326
+
4327
+	/**
4328
+	 * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4329
+	 *
4330
+	 * @throws DomainException
4331
+	 */
4332
+	public function update_mt_form()
4333
+	{
4334
+		if (! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4335
+			EE_Error::add_error(
4336
+				esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4337
+				__FILE__,
4338
+				__FUNCTION__,
4339
+				__LINE__
4340
+			);
4341
+			$this->_return_json();
4342
+		}
4343
+
4344
+		$message_types = $this->get_installed_message_types();
4345
+
4346
+		$message_type = $message_types[ $this->_req_data['message_type'] ];
4347
+		$messenger = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
4348
+
4349
+		$content = $this->_message_type_settings_content(
4350
+			$message_type,
4351
+			$messenger,
4352
+			true
4353
+		);
4354
+		$this->_template_args['success'] = true;
4355
+		$this->_template_args['content'] = $content;
4356
+		$this->_return_json();
4357
+	}
4358
+
4359
+
4360
+	/**
4361
+	 * this handles saving the settings for a messenger or message type
4362
+	 *
4363
+	 */
4364
+	public function save_settings()
4365
+	{
4366
+		if (! isset($this->_req_data['type'])) {
4367
+			EE_Error::add_error(
4368
+				esc_html__(
4369
+					'Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
4370
+					'event_espresso'
4371
+				),
4372
+				__FILE__,
4373
+				__FUNCTION__,
4374
+				__LINE__
4375
+			);
4376
+			$this->_template_args['error'] = true;
4377
+			$this->_return_json();
4378
+		}
4379
+
4380
+
4381
+		if ($this->_req_data['type'] === 'messenger') {
4382
+			// this should be an array.
4383
+			$settings = $this->_req_data['messenger_settings'];
4384
+			$messenger = $settings['messenger'];
4385
+			// let's setup the settings data
4386
+			foreach ($settings as $key => $value) {
4387
+				switch ($key) {
4388
+					case 'messenger':
4389
+						unset($settings['messenger']);
4390
+						break;
4391
+					case 'message_types':
4392
+						unset($settings['message_types']);
4393
+						break;
4394
+					default:
4395
+						$settings[ $key ] = $value;
4396
+						break;
4397
+				}
4398
+			}
4399
+			$this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4400
+		} elseif ($this->_req_data['type'] === 'message_type') {
4401
+			$settings = $this->_req_data['message_type_settings'];
4402
+			$messenger = $settings['messenger'];
4403
+			$message_type = $settings['message_type'];
4404
+
4405
+			foreach ($settings as $key => $value) {
4406
+				switch ($key) {
4407
+					case 'messenger':
4408
+						unset($settings['messenger']);
4409
+						break;
4410
+					case 'message_type':
4411
+						unset($settings['message_type']);
4412
+						break;
4413
+					default:
4414
+						$settings[ $key ] = $value;
4415
+						break;
4416
+				}
4417
+			}
4418
+
4419
+			$this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4420
+		}
4421
+
4422
+		// okay we should have the data all setup.  Now we just update!
4423
+		$success = $this->_message_resource_manager->update_active_messengers_option();
4424
+
4425
+		if ($success) {
4426
+			EE_Error::add_success(__('Settings updated', 'event_espresso'));
4427
+		} else {
4428
+			EE_Error::add_error(
4429
+				esc_html__(
4430
+					'Settings did not get updated',
4431
+					'event_espresso'
4432
+				),
4433
+				__FILE__,
4434
+				__FUNCTION__,
4435
+				__LINE__
4436
+			);
4437
+		}
4438
+
4439
+		$this->_template_args['success'] = $success;
4440
+		$this->_return_json();
4441
+	}
4442
+
4443
+
4444
+
4445
+
4446
+	/**  EE MESSAGE PROCESSING ACTIONS **/
4447
+
4448
+
4449
+	/**
4450
+	 * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4451
+	 * However, this does not send immediately, it just queues for sending.
4452
+	 *
4453
+	 * @since 4.9.0
4454
+	 * @throws EE_Error
4455
+	 * @throws InvalidDataTypeException
4456
+	 * @throws InvalidInterfaceException
4457
+	 * @throws InvalidArgumentException
4458
+	 * @throws ReflectionException
4459
+	 */
4460
+	protected function _generate_now()
4461
+	{
4462
+		EED_Messages::generate_now($this->_get_msg_ids_from_request());
4463
+		$this->_redirect_after_action(false, '', '', array(), true);
4464
+	}
4465
+
4466
+
4467
+	/**
4468
+	 * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4469
+	 * are EEM_Message::status_resend or EEM_Message::status_idle
4470
+	 *
4471
+	 * @since 4.9.0
4472
+	 * @throws EE_Error
4473
+	 * @throws InvalidDataTypeException
4474
+	 * @throws InvalidInterfaceException
4475
+	 * @throws InvalidArgumentException
4476
+	 * @throws ReflectionException
4477
+	 */
4478
+	protected function _generate_and_send_now()
4479
+	{
4480
+		EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4481
+		$this->_redirect_after_action(false, '', '', array(), true);
4482
+	}
4483
+
4484
+
4485
+	/**
4486
+	 * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4487
+	 *
4488
+	 * @since 4.9.0
4489
+	 * @throws EE_Error
4490
+	 * @throws InvalidDataTypeException
4491
+	 * @throws InvalidInterfaceException
4492
+	 * @throws InvalidArgumentException
4493
+	 * @throws ReflectionException
4494
+	 */
4495
+	protected function _queue_for_resending()
4496
+	{
4497
+		EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4498
+		$this->_redirect_after_action(false, '', '', array(), true);
4499
+	}
4500
+
4501
+
4502
+	/**
4503
+	 *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4504
+	 *
4505
+	 * @since 4.9.0
4506
+	 * @throws EE_Error
4507
+	 * @throws InvalidDataTypeException
4508
+	 * @throws InvalidInterfaceException
4509
+	 * @throws InvalidArgumentException
4510
+	 * @throws ReflectionException
4511
+	 */
4512
+	protected function _send_now()
4513
+	{
4514
+		EED_Messages::send_now($this->_get_msg_ids_from_request());
4515
+		$this->_redirect_after_action(false, '', '', array(), true);
4516
+	}
4517
+
4518
+
4519
+	/**
4520
+	 * Deletes EE_messages for IDs in the request.
4521
+	 *
4522
+	 * @since 4.9.0
4523
+	 * @throws EE_Error
4524
+	 * @throws InvalidDataTypeException
4525
+	 * @throws InvalidInterfaceException
4526
+	 * @throws InvalidArgumentException
4527
+	 */
4528
+	protected function _delete_ee_messages()
4529
+	{
4530
+		$msg_ids = $this->_get_msg_ids_from_request();
4531
+		$deleted_count = 0;
4532
+		foreach ($msg_ids as $msg_id) {
4533
+			if (EEM_Message::instance()->delete_by_ID($msg_id)) {
4534
+				$deleted_count++;
4535
+			}
4536
+		}
4537
+		if ($deleted_count) {
4538
+			EE_Error::add_success(
4539
+				esc_html(
4540
+					_n(
4541
+						'Message successfully deleted',
4542
+						'Messages successfully deleted',
4543
+						$deleted_count,
4544
+						'event_espresso'
4545
+					)
4546
+				)
4547
+			);
4548
+			$this->_redirect_after_action(
4549
+				false,
4550
+				'',
4551
+				'',
4552
+				array(),
4553
+				true
4554
+			);
4555
+		} else {
4556
+			EE_Error::add_error(
4557
+				_n('The message was not deleted.', 'The messages were not deleted', count($msg_ids), 'event_espresso'),
4558
+				__FILE__,
4559
+				__FUNCTION__,
4560
+				__LINE__
4561
+			);
4562
+			$this->_redirect_after_action(false, '', '', array(), true);
4563
+		}
4564
+	}
4565
+
4566
+
4567
+	/**
4568
+	 *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4569
+	 *
4570
+	 * @since 4.9.0
4571
+	 * @return array
4572
+	 */
4573
+	protected function _get_msg_ids_from_request()
4574
+	{
4575
+		if (! isset($this->_req_data['MSG_ID'])) {
4576
+			return array();
4577
+		}
4578
+
4579
+		return is_array($this->_req_data['MSG_ID'])
4580
+			? array_keys($this->_req_data['MSG_ID'])
4581
+			: array($this->_req_data['MSG_ID']);
4582
+	}
4583 4583
 }
Please login to merge, or discard this patch.
Spacing   +210 added lines, -210 removed lines patch added patch discarded remove patch
@@ -141,8 +141,8 @@  discard block
 block discarded – undo
141 141
         $i = 1;
142 142
         foreach ($active_messengers as $active_messenger) {
143 143
             if ($active_messenger instanceof EE_Message) {
144
-                $m_values[ $i ]['id'] = $active_messenger->messenger();
145
-                $m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
144
+                $m_values[$i]['id'] = $active_messenger->messenger();
145
+                $m_values[$i]['text'] = ucwords($active_messenger->messenger_label());
146 146
                 $i++;
147 147
             }
148 148
         }
@@ -178,8 +178,8 @@  discard block
 block discarded – undo
178 178
         $i = 1;
179 179
         foreach ($active_messages as $active_message) {
180 180
             if ($active_message instanceof EE_Message) {
181
-                $mt_values[ $i ]['id'] = $active_message->message_type();
182
-                $mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
181
+                $mt_values[$i]['id'] = $active_message->message_type();
182
+                $mt_values[$i]['text'] = ucwords($active_message->message_type_label());
183 183
                 $i++;
184 184
             }
185 185
         }
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
                 if ($message_type instanceof EE_message_type) {
219 219
                     $message_type_contexts = $message_type->get_contexts();
220 220
                     foreach ($message_type_contexts as $context => $context_details) {
221
-                        $contexts[ $context ] = $context_details['label'];
221
+                        $contexts[$context] = $context_details['label'];
222 222
                     }
223 223
                 }
224 224
             }
@@ -709,53 +709,53 @@  discard block
 block discarded – undo
709 709
 
710 710
     public function messages_help_tab()
711 711
     {
712
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
712
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messages_help_tab.template.php');
713 713
     }
714 714
 
715 715
 
716 716
     public function messengers_help_tab()
717 717
     {
718
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
718
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messenger_help_tab.template.php');
719 719
     }
720 720
 
721 721
 
722 722
     public function message_types_help_tab()
723 723
     {
724
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
724
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_message_type_help_tab.template.php');
725 725
     }
726 726
 
727 727
 
728 728
     public function messages_overview_help_tab()
729 729
     {
730
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
730
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_overview_help_tab.template.php');
731 731
     }
732 732
 
733 733
 
734 734
     public function message_templates_help_tab()
735 735
     {
736
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
736
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_message_templates_help_tab.template.php');
737 737
     }
738 738
 
739 739
 
740 740
     public function edit_message_template_help_tab()
741 741
     {
742
-        $args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
742
+        $args['img1'] = '<img src="'.EE_MSG_ASSETS_URL.'images/editor.png'.'" alt="'
743 743
                         . esc_attr__('Editor Title', 'event_espresso')
744 744
                         . '" />';
745
-        $args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
745
+        $args['img2'] = '<img src="'.EE_MSG_ASSETS_URL.'images/switch-context.png'.'" alt="'
746 746
                         . esc_attr__('Context Switcher and Preview', 'event_espresso')
747 747
                         . '" />';
748
-        $args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
748
+        $args['img3'] = '<img class="left" src="'.EE_MSG_ASSETS_URL.'images/form-fields.png'.'" alt="'
749 749
                         . esc_attr__('Message Template Form Fields', 'event_espresso')
750 750
                         . '" />';
751
-        $args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
751
+        $args['img4'] = '<img class="right" src="'.EE_MSG_ASSETS_URL.'images/shortcodes-metabox.png'.'" alt="'
752 752
                         . esc_attr__('Shortcodes Metabox', 'event_espresso')
753 753
                         . '" />';
754
-        $args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
754
+        $args['img5'] = '<img class="right" src="'.EE_MSG_ASSETS_URL.'images/publish-meta-box.png'.'" alt="'
755 755
                         . esc_attr__('Publish Metabox', 'event_espresso')
756 756
                         . '" />';
757 757
         EEH_Template::display_template(
758
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
758
+            EE_MSG_TEMPLATE_PATH.'ee_msg_messages_templates_editor_help_tab.template.php',
759 759
             $args
760 760
         );
761 761
     }
@@ -766,7 +766,7 @@  discard block
 block discarded – undo
766 766
         $this->_set_shortcodes();
767 767
         $args['shortcodes'] = $this->_shortcodes;
768 768
         EEH_Template::display_template(
769
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
769
+            EE_MSG_TEMPLATE_PATH.'ee_msg_messages_shortcodes_help_tab.template.php',
770 770
             $args
771 771
         );
772 772
     }
@@ -774,16 +774,16 @@  discard block
 block discarded – undo
774 774
 
775 775
     public function preview_message_help_tab()
776 776
     {
777
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
777
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_preview_help_tab.template.php');
778 778
     }
779 779
 
780 780
 
781 781
     public function settings_help_tab()
782 782
     {
783
-        $args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
784
-                        . '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
785
-        $args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
786
-                        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
783
+        $args['img1'] = '<img class="inline-text" src="'.EE_MSG_ASSETS_URL.'images/email-tab-active.png'
784
+                        . '" alt="'.esc_attr__('Active Email Tab', 'event_espresso').'" />';
785
+        $args['img2'] = '<img class="inline-text" src="'.EE_MSG_ASSETS_URL.'images/email-tab-inactive.png'
786
+                        . '" alt="'.esc_attr__('Inactive Email Tab', 'event_espresso').'" />';
787 787
         $args['img3'] = '<div class="switch">'
788 788
                         . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
789 789
                         . ' type="checkbox" checked="checked">'
@@ -794,25 +794,25 @@  discard block
 block discarded – undo
794 794
                         . ' type="checkbox">'
795 795
                         . '<label for="ee-on-off-toggle-on"></label>'
796 796
                         . '</div>';
797
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
797
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messages_settings_help_tab.template.php', $args);
798 798
     }
799 799
 
800 800
 
801 801
     public function load_scripts_styles()
802 802
     {
803
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
803
+        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL.'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
804 804
         wp_enqueue_style('espresso_ee_msg');
805 805
 
806 806
         wp_register_script(
807 807
             'ee-messages-settings',
808
-            EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
808
+            EE_MSG_ASSETS_URL.'ee-messages-settings.js',
809 809
             array('jquery-ui-droppable', 'ee-serialize-full-array'),
810 810
             EVENT_ESPRESSO_VERSION,
811 811
             true
812 812
         );
813 813
         wp_register_script(
814 814
             'ee-msg-list-table-js',
815
-            EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
815
+            EE_MSG_ASSETS_URL.'ee_message_admin_list_table.js',
816 816
             array('ee-dialog'),
817 817
             EVENT_ESPRESSO_VERSION
818 818
         );
@@ -870,7 +870,7 @@  discard block
 block discarded – undo
870 870
 
871 871
         wp_register_script(
872 872
             'ee_msgs_edit_js',
873
-            EE_MSG_ASSETS_URL . 'ee_message_editor.js',
873
+            EE_MSG_ASSETS_URL.'ee_message_editor.js',
874 874
             array('jquery'),
875 875
             EVENT_ESPRESSO_VERSION
876 876
         );
@@ -914,7 +914,7 @@  discard block
 block discarded – undo
914 914
     {
915 915
         wp_register_style(
916 916
             'ee-message-settings',
917
-            EE_MSG_ASSETS_URL . 'ee_message_settings.css',
917
+            EE_MSG_ASSETS_URL.'ee_message_settings.css',
918 918
             array(),
919 919
             EVENT_ESPRESSO_VERSION
920 920
         );
@@ -1000,7 +1000,7 @@  discard block
 block discarded – undo
1000 1000
             }
1001 1001
             $status_bulk_actions = $common_bulk_actions;
1002 1002
             // unset bulk actions not applying to status
1003
-            if (! empty($status_bulk_actions)) {
1003
+            if ( ! empty($status_bulk_actions)) {
1004 1004
                 switch ($status) {
1005 1005
                     case EEM_Message::status_idle:
1006 1006
                     case EEM_Message::status_resend:
@@ -1029,7 +1029,7 @@  discard block
 block discarded – undo
1029 1029
                 continue;
1030 1030
             }
1031 1031
 
1032
-            $this->_views[ strtolower($status) ] = array(
1032
+            $this->_views[strtolower($status)] = array(
1033 1033
                 'slug'        => strtolower($status),
1034 1034
                 'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1035 1035
                 'count'       => 0,
@@ -1068,7 +1068,7 @@  discard block
 block discarded – undo
1068 1068
             if ($action_item === 'see_notifications_for') {
1069 1069
                 continue;
1070 1070
             }
1071
-            $action_items[ $action_item ] = array(
1071
+            $action_items[$action_item] = array(
1072 1072
                 'class' => $action_details['css_class'],
1073 1073
                 'desc'  => $action_details['label'],
1074 1074
             );
@@ -1077,37 +1077,37 @@  discard block
 block discarded – undo
1077 1077
         /** @type array $status_items status legend setup */
1078 1078
         $status_items = array(
1079 1079
             'incomplete_status'          => array(
1080
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1080
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_incomplete,
1081 1081
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1082 1082
             ),
1083 1083
             'idle_status'                => array(
1084
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1084
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_idle,
1085 1085
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1086 1086
             ),
1087 1087
             'resend_status'              => array(
1088
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1088
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_resend,
1089 1089
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1090 1090
             ),
1091 1091
             'messenger_executing_status' => array(
1092
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1092
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_messenger_executing,
1093 1093
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1094 1094
             ),
1095 1095
             'sent_status'                => array(
1096
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1096
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_sent,
1097 1097
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1098 1098
             ),
1099 1099
             'retry_status'               => array(
1100
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1100
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_retry,
1101 1101
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1102 1102
             ),
1103 1103
             'failed_status'              => array(
1104
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1104
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_failed,
1105 1105
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1106 1106
             ),
1107 1107
         );
1108 1108
         if (EEM_Message::debug()) {
1109 1109
             $status_items['debug_only_status'] = array(
1110
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1110
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Message::status_debug_only,
1111 1111
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1112 1112
             );
1113 1113
         }
@@ -1119,11 +1119,11 @@  discard block
 block discarded – undo
1119 1119
     protected function _custom_mtps_preview()
1120 1120
     {
1121 1121
         $this->_admin_page_title = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1122
-        $this->_template_args['preview_img'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1123
-                                               . ' alt="' . esc_attr__(
1122
+        $this->_template_args['preview_img'] = '<img src="'.EE_MSG_ASSETS_URL.'images/custom_mtps_preview.png"'
1123
+                                               . ' alt="'.esc_attr__(
1124 1124
                                                    'Preview Custom Message Templates screenshot',
1125 1125
                                                    'event_espresso'
1126
-                                               ) . '" />';
1126
+                                               ).'" />';
1127 1127
         $this->_template_args['preview_text'] = '<strong>'
1128 1128
                                                 . esc_html__(
1129 1129
                                                     '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.',
@@ -1203,7 +1203,7 @@  discard block
 block discarded – undo
1203 1203
         $installed = array();
1204 1204
 
1205 1205
         foreach ($installed_message_types as $message_type) {
1206
-            $installed[ $message_type->name ] = $message_type;
1206
+            $installed[$message_type->name] = $message_type;
1207 1207
         }
1208 1208
 
1209 1209
         return $installed;
@@ -1352,7 +1352,7 @@  discard block
 block discarded – undo
1352 1352
         // we need to assemble the title from Various details
1353 1353
         $context_label = sprintf(
1354 1354
             esc_html__('(%s %s)', 'event_espresso'),
1355
-            $c_config[ $context ]['label'],
1355
+            $c_config[$context]['label'],
1356 1356
             ucwords($c_label['label'])
1357 1357
         );
1358 1358
 
@@ -1374,7 +1374,7 @@  discard block
 block discarded – undo
1374 1374
             $message_template_group->message_type()
1375 1375
         );
1376 1376
 
1377
-        if (! $template_field_structure) {
1377
+        if ( ! $template_field_structure) {
1378 1378
             $template_field_structure = false;
1379 1379
             $template_fields = esc_html__(
1380 1380
                 'There was an error in assembling the fields for this display (you should see an error message)',
@@ -1388,21 +1388,21 @@  discard block
 block discarded – undo
1388 1388
 
1389 1389
         // if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1390 1390
         // will get handled in the "extra" array.
1391
-        if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1392
-            foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1393
-                unset($template_field_structure[ $context ][ $reference_field ]);
1391
+        if (is_array($template_field_structure[$context]) && isset($template_field_structure[$context]['extra'])) {
1392
+            foreach ($template_field_structure[$context]['extra'] as $reference_field => $new_fields) {
1393
+                unset($template_field_structure[$context][$reference_field]);
1394 1394
             }
1395 1395
         }
1396 1396
 
1397 1397
         // let's loop through the template_field_structure and actually assemble the input fields!
1398
-        if (! empty($template_field_structure)) {
1399
-            foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1398
+        if ( ! empty($template_field_structure)) {
1399
+            foreach ($template_field_structure[$context] as $template_field => $field_setup_array) {
1400 1400
                 // if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1401 1401
                 // the extra array and reset them.
1402 1402
                 if ($template_field === 'extra') {
1403 1403
                     $this->_template_args['is_extra_fields'] = true;
1404 1404
                     foreach ($field_setup_array as $reference_field => $new_fields_array) {
1405
-                        $message_template = $message_templates[ $context ][ $reference_field ];
1405
+                        $message_template = $message_templates[$context][$reference_field];
1406 1406
                         $content = $message_template instanceof EE_Message_Template
1407 1407
                             ? $message_template->get('MTP_content')
1408 1408
                             : '';
@@ -1411,7 +1411,7 @@  discard block
 block discarded – undo
1411 1411
                             $continue = false;
1412 1412
                             if (isset($extra_array['shortcodes_required'])) {
1413 1413
                                 foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1414
-                                    if (! array_key_exists($shortcode, $this->_shortcodes)) {
1414
+                                    if ( ! array_key_exists($shortcode, $this->_shortcodes)) {
1415 1415
                                         $continue = true;
1416 1416
                                     }
1417 1417
                                 }
@@ -1424,57 +1424,57 @@  discard block
 block discarded – undo
1424 1424
                                         . '-'
1425 1425
                                         . $extra_field
1426 1426
                                         . '-content';
1427
-                            $template_form_fields[ $field_id ] = $extra_array;
1428
-                            $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1427
+                            $template_form_fields[$field_id] = $extra_array;
1428
+                            $template_form_fields[$field_id]['name'] = 'MTP_template_fields['
1429 1429
                                                                          . $reference_field
1430 1430
                                                                          . '][content]['
1431
-                                                                         . $extra_field . ']';
1431
+                                                                         . $extra_field.']';
1432 1432
                             $css_class = isset($extra_array['css_class'])
1433 1433
                                 ? $extra_array['css_class']
1434 1434
                                 : '';
1435 1435
 
1436
-                            $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1436
+                            $template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
1437 1437
                                                                               && in_array($extra_field, $v_fields, true)
1438 1438
                                                                               &&
1439 1439
                                                                               (
1440
-                                                                                  is_array($validators[ $extra_field ])
1441
-                                                                                  && isset($validators[ $extra_field ]['msg'])
1440
+                                                                                  is_array($validators[$extra_field])
1441
+                                                                                  && isset($validators[$extra_field]['msg'])
1442 1442
                                                                               )
1443
-                                ? 'validate-error ' . $css_class
1443
+                                ? 'validate-error '.$css_class
1444 1444
                                 : $css_class;
1445 1445
 
1446
-                            $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1447
-                                                                          && isset($content[ $extra_field ])
1448
-                                ? $content[ $extra_field ]
1446
+                            $template_form_fields[$field_id]['value'] = ! empty($message_templates)
1447
+                                                                          && isset($content[$extra_field])
1448
+                                ? $content[$extra_field]
1449 1449
                                 : '';
1450 1450
 
1451 1451
                             // do we have a validation error?  if we do then let's use that value instead
1452
-                            $template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1453
-                                ? $validators[ $extra_field ]['value']
1454
-                                : $template_form_fields[ $field_id ]['value'];
1452
+                            $template_form_fields[$field_id]['value'] = isset($validators[$extra_field])
1453
+                                ? $validators[$extra_field]['value']
1454
+                                : $template_form_fields[$field_id]['value'];
1455 1455
 
1456 1456
 
1457
-                            $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1457
+                            $template_form_fields[$field_id]['db-col'] = 'MTP_content';
1458 1458
 
1459 1459
                             // shortcode selector
1460 1460
                             $field_name_to_use = $extra_field === 'main'
1461 1461
                                 ? 'content'
1462 1462
                                 : $extra_field;
1463
-                            $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1463
+                            $template_form_fields[$field_id]['append_content'] = $this->_get_shortcode_selector(
1464 1464
                                 $field_name_to_use,
1465 1465
                                 $field_id
1466 1466
                             );
1467 1467
 
1468 1468
                             if (isset($extra_array['input']) && $extra_array['input'] === 'wp_editor') {
1469 1469
                                 // we want to decode the entities
1470
-                                $template_form_fields[ $field_id ]['value'] = $template_form_fields[ $field_id ]['value'];
1470
+                                $template_form_fields[$field_id]['value'] = $template_form_fields[$field_id]['value'];
1471 1471
                             }/**/
1472 1472
                         }
1473
-                        $templatefield_MTP_id = $reference_field . '-MTP_ID';
1474
-                        $templatefield_templatename_id = $reference_field . '-name';
1473
+                        $templatefield_MTP_id = $reference_field.'-MTP_ID';
1474
+                        $templatefield_templatename_id = $reference_field.'-name';
1475 1475
 
1476
-                        $template_form_fields[ $templatefield_MTP_id ] = array(
1477
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1476
+                        $template_form_fields[$templatefield_MTP_id] = array(
1477
+                            'name'       => 'MTP_template_fields['.$reference_field.'][MTP_ID]',
1478 1478
                             'label'      => null,
1479 1479
                             'input'      => 'hidden',
1480 1480
                             'type'       => 'int',
@@ -1486,8 +1486,8 @@  discard block
 block discarded – undo
1486 1486
                             'db-col'     => 'MTP_ID',
1487 1487
                         );
1488 1488
 
1489
-                        $template_form_fields[ $templatefield_templatename_id ] = array(
1490
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1489
+                        $template_form_fields[$templatefield_templatename_id] = array(
1490
+                            'name'       => 'MTP_template_fields['.$reference_field.'][name]',
1491 1491
                             'label'      => null,
1492 1492
                             'input'      => 'hidden',
1493 1493
                             'type'       => 'string',
@@ -1501,36 +1501,36 @@  discard block
 block discarded – undo
1501 1501
                     }
1502 1502
                     continue; // skip the next stuff, we got the necessary fields here for this dataset.
1503 1503
                 } else {
1504
-                    $field_id = $template_field . '-content';
1505
-                    $template_form_fields[ $field_id ] = $field_setup_array;
1506
-                    $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields[' . $template_field . '][content]';
1507
-                    $message_template = isset($message_templates[ $context ][ $template_field ])
1508
-                        ? $message_templates[ $context ][ $template_field ]
1504
+                    $field_id = $template_field.'-content';
1505
+                    $template_form_fields[$field_id] = $field_setup_array;
1506
+                    $template_form_fields[$field_id]['name'] = 'MTP_template_fields['.$template_field.'][content]';
1507
+                    $message_template = isset($message_templates[$context][$template_field])
1508
+                        ? $message_templates[$context][$template_field]
1509 1509
                         : null;
1510
-                    $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1511
-                                                                  && is_array($message_templates[ $context ])
1510
+                    $template_form_fields[$field_id]['value'] = ! empty($message_templates)
1511
+                                                                  && is_array($message_templates[$context])
1512 1512
                                                                   && $message_template instanceof EE_Message_Template
1513 1513
                         ? $message_template->get('MTP_content')
1514 1514
                         : '';
1515 1515
 
1516 1516
                     // do we have a validator error for this field?  if we do then we'll use that value instead
1517
-                    $template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1518
-                        ? $validators[ $template_field ]['value']
1519
-                        : $template_form_fields[ $field_id ]['value'];
1517
+                    $template_form_fields[$field_id]['value'] = isset($validators[$template_field])
1518
+                        ? $validators[$template_field]['value']
1519
+                        : $template_form_fields[$field_id]['value'];
1520 1520
 
1521 1521
 
1522
-                    $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1522
+                    $template_form_fields[$field_id]['db-col'] = 'MTP_content';
1523 1523
                     $css_class = isset($field_setup_array['css_class'])
1524 1524
                         ? $field_setup_array['css_class']
1525 1525
                         : '';
1526
-                    $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1526
+                    $template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
1527 1527
                                                                       && in_array($template_field, $v_fields, true)
1528
-                                                                      && isset($validators[ $template_field ]['msg'])
1529
-                        ? 'validate-error ' . $css_class
1528
+                                                                      && isset($validators[$template_field]['msg'])
1529
+                        ? 'validate-error '.$css_class
1530 1530
                         : $css_class;
1531 1531
 
1532 1532
                     // shortcode selector
1533
-                    $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1533
+                    $template_form_fields[$field_id]['append_content'] = $this->_get_shortcode_selector(
1534 1534
                         $template_field,
1535 1535
                         $field_id
1536 1536
                     );
@@ -1538,12 +1538,12 @@  discard block
 block discarded – undo
1538 1538
 
1539 1539
                 // k took care of content field(s) now let's take care of others.
1540 1540
 
1541
-                $templatefield_MTP_id = $template_field . '-MTP_ID';
1542
-                $templatefield_field_templatename_id = $template_field . '-name';
1541
+                $templatefield_MTP_id = $template_field.'-MTP_ID';
1542
+                $templatefield_field_templatename_id = $template_field.'-name';
1543 1543
 
1544 1544
                 // foreach template field there are actually two form fields created
1545
-                $template_form_fields[ $templatefield_MTP_id ] = array(
1546
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1545
+                $template_form_fields[$templatefield_MTP_id] = array(
1546
+                    'name'       => 'MTP_template_fields['.$template_field.'][MTP_ID]',
1547 1547
                     'label'      => null,
1548 1548
                     'input'      => 'hidden',
1549 1549
                     'type'       => 'int',
@@ -1555,8 +1555,8 @@  discard block
 block discarded – undo
1555 1555
                     'db-col'     => 'MTP_ID',
1556 1556
                 );
1557 1557
 
1558
-                $template_form_fields[ $templatefield_field_templatename_id ] = array(
1559
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1558
+                $template_form_fields[$templatefield_field_templatename_id] = array(
1559
+                    'name'       => 'MTP_template_fields['.$template_field.'][name]',
1560 1560
                     'label'      => null,
1561 1561
                     'input'      => 'hidden',
1562 1562
                     'type'       => 'string',
@@ -1699,10 +1699,10 @@  discard block
 block discarded – undo
1699 1699
                 'value' => $GRP_ID,
1700 1700
             );
1701 1701
             $sidebar_form_fields['ee-msg-evt-nonce'] = array(
1702
-                'name'  => $action . '_nonce',
1702
+                'name'  => $action.'_nonce',
1703 1703
                 'input' => 'hidden',
1704 1704
                 'type'  => 'string',
1705
-                'value' => wp_create_nonce($action . '_nonce'),
1705
+                'value' => wp_create_nonce($action.'_nonce'),
1706 1706
             );
1707 1707
 
1708 1708
             if (isset($this->_req_data['template_switch']) && $this->_req_data['template_switch']) {
@@ -1743,7 +1743,7 @@  discard block
 block discarded – undo
1743 1743
             ),
1744 1744
             $this->_admin_base_url
1745 1745
         );
1746
-        $preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1746
+        $preview_button = '<a href="'.$preview_url.'" class="button-secondary messages-preview-button">'
1747 1747
                           . esc_html__('Preview', 'event_espresso')
1748 1748
                           . '</a>';
1749 1749
 
@@ -1781,7 +1781,7 @@  discard block
 block discarded – undo
1781 1781
 
1782 1782
         $this->_template_path = $this->_template_args['GRP_ID']
1783 1783
             ? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1784
-            : EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1784
+            : EE_MSG_TEMPLATE_PATH.'ee_msg_details_main_add_meta_box.template.php';
1785 1785
 
1786 1786
         // send along EE_Message_Template_Group object for further template use.
1787 1787
         $this->_template_args['MTP'] = $message_template_group;
@@ -1836,7 +1836,7 @@  discard block
 block discarded – undo
1836 1836
     ) {
1837 1837
         $template_args = array(
1838 1838
             'context'                   => $context,
1839
-            'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1839
+            'nonce'                     => wp_create_nonce('activate_'.$context.'_toggle_nonce'),
1840 1840
             'is_active'                 => $message_template_group->is_context_active($context),
1841 1841
             'on_off_action'             => $message_template_group->is_context_active($context)
1842 1842
                 ? 'context-off'
@@ -1845,7 +1845,7 @@  discard block
 block discarded – undo
1845 1845
             'message_template_group_id' => $message_template_group->ID(),
1846 1846
         );
1847 1847
         return EEH_Template::display_template(
1848
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1848
+            EE_MSG_TEMPLATE_PATH.'ee_msg_editor_active_context_element.template.php',
1849 1849
             $template_args,
1850 1850
             true
1851 1851
         );
@@ -1866,7 +1866,7 @@  discard block
 block discarded – undo
1866 1866
     {
1867 1867
         $success = true;
1868 1868
         // check for required data
1869
-        if (! isset(
1869
+        if ( ! isset(
1870 1870
             $this->_req_data['message_template_group_id'],
1871 1871
             $this->_req_data['context'],
1872 1872
             $this->_req_data['status']
@@ -1883,7 +1883,7 @@  discard block
 block discarded – undo
1883 1883
         $nonce = isset($this->_req_data['toggle_context_nonce'])
1884 1884
             ? sanitize_text_field($this->_req_data['toggle_context_nonce'])
1885 1885
             : '';
1886
-        $nonce_ref = 'activate_' . $this->_req_data['context'] . '_toggle_nonce';
1886
+        $nonce_ref = 'activate_'.$this->_req_data['context'].'_toggle_nonce';
1887 1887
         $this->_verify_nonce($nonce, $nonce_ref);
1888 1888
         $status = $this->_req_data['status'];
1889 1889
         if ($status !== 'off' && $status !== 'on') {
@@ -1901,7 +1901,7 @@  discard block
 block discarded – undo
1901 1901
         $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID(
1902 1902
             $this->_req_data['message_template_group_id']
1903 1903
         );
1904
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
1904
+        if ( ! $message_template_group instanceof EE_Message_Template_Group) {
1905 1905
             EE_Error::add_error(
1906 1906
                 sprintf(
1907 1907
                     esc_html__(
@@ -2030,7 +2030,7 @@  discard block
 block discarded – undo
2030 2030
         $templates = array();
2031 2031
         $GRP_ID = ! empty($this->_req_data['GRP_ID']) ? $this->_req_data['GRP_ID'] : 0;
2032 2032
         // we need to make sure we've got the info we need.
2033
-        if (! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2033
+        if ( ! isset($this->_req_data['msgr'], $this->_req_data['mt'], $this->_req_data['GRP_ID'])) {
2034 2034
             EE_Error::add_error(
2035 2035
                 esc_html__(
2036 2036
                     '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.',
@@ -2072,7 +2072,7 @@  discard block
 block discarded – undo
2072 2072
         }
2073 2073
 
2074 2074
         // any error messages?
2075
-        if (! $success) {
2075
+        if ( ! $success) {
2076 2076
             EE_Error::add_error(
2077 2077
                 esc_html__(
2078 2078
                     'Something went wrong with deleting existing templates. Unable to reset to default',
@@ -2124,7 +2124,7 @@  discard block
 block discarded – undo
2124 2124
     public function _preview_message($send = false)
2125 2125
     {
2126 2126
         // first make sure we've got the necessary parameters
2127
-        if (! isset(
2127
+        if ( ! isset(
2128 2128
             $this->_req_data['message_type'],
2129 2129
             $this->_req_data['messenger'],
2130 2130
             $this->_req_data['messenger'],
@@ -2182,7 +2182,7 @@  discard block
 block discarded – undo
2182 2182
         $preview_title = sprintf(
2183 2183
             esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2184 2184
             $active_messenger_label,
2185
-            ucwords($message_types[ $this->_req_data['message_type'] ]->label['singular'])
2185
+            ucwords($message_types[$this->_req_data['message_type']]->label['singular'])
2186 2186
         );
2187 2187
         if (empty($preview)) {
2188 2188
             $this->noEventsErrorMessage();
@@ -2190,7 +2190,7 @@  discard block
 block discarded – undo
2190 2190
         // setup display of preview.
2191 2191
         $this->_admin_page_title = $preview_title;
2192 2192
         $this->_template_args['admin_page_title'] = $preview_title;
2193
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2193
+        $this->_template_args['admin_page_content'] = $preview_button.'<br />'.$preview;
2194 2194
         $this->_template_args['data']['force_json'] = true;
2195 2195
 
2196 2196
         return '';
@@ -2303,10 +2303,10 @@  discard block
 block discarded – undo
2303 2303
         foreach ($tp_collection as $tp) {
2304 2304
             // only include template packs that support this messenger and message type!
2305 2305
             $supports = $tp->get_supports();
2306
-            if (! isset($supports[ $this->_message_template_group->messenger() ])
2306
+            if ( ! isset($supports[$this->_message_template_group->messenger()])
2307 2307
                 || ! in_array(
2308 2308
                     $this->_message_template_group->message_type(),
2309
-                    $supports[ $this->_message_template_group->messenger() ],
2309
+                    $supports[$this->_message_template_group->messenger()],
2310 2310
                     true
2311 2311
                 )
2312 2312
             ) {
@@ -2359,7 +2359,7 @@  discard block
 block discarded – undo
2359 2359
         $template_args['template_pack_description'] = $template_pack_labels->template_pack_description;
2360 2360
         $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2361 2361
 
2362
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2362
+        $template = EE_MSG_TEMPLATE_PATH.'template_pack_and_variations_metabox.template.php';
2363 2363
 
2364 2364
         EEH_Template::display_template($template, $template_args);
2365 2365
     }
@@ -2385,10 +2385,10 @@  discard block
 block discarded – undo
2385 2385
         // first we need to see if there are any fields
2386 2386
         $fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2387 2387
 
2388
-        if (! empty($fields)) {
2388
+        if ( ! empty($fields)) {
2389 2389
             // yup there be fields
2390 2390
             foreach ($fields as $field => $config) {
2391
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2391
+                $field_id = $this->_message_template_group->messenger().'_'.$field;
2392 2392
                 $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2393 2393
                 $default = isset($config['default']) ? $config['default'] : '';
2394 2394
                 $default = isset($config['value']) ? $config['value'] : $default;
@@ -2396,22 +2396,22 @@  discard block
 block discarded – undo
2396 2396
                 // if type is hidden and the value is empty
2397 2397
                 // something may have gone wrong so let's correct with the defaults
2398 2398
                 $fix = $config['input'] === 'hidden'
2399
-                       && isset($existing[ $field ])
2400
-                       && empty($existing[ $field ])
2399
+                       && isset($existing[$field])
2400
+                       && empty($existing[$field])
2401 2401
                     ? $default
2402 2402
                     : '';
2403
-                $existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2404
-                    ? $existing[ $field ]
2403
+                $existing[$field] = isset($existing[$field]) && empty($fix)
2404
+                    ? $existing[$field]
2405 2405
                     : $fix;
2406 2406
 
2407
-                $template_form_fields[ $field_id ] = array(
2408
-                    'name'       => 'test_settings_fld[' . $field . ']',
2407
+                $template_form_fields[$field_id] = array(
2408
+                    'name'       => 'test_settings_fld['.$field.']',
2409 2409
                     'label'      => $config['label'],
2410 2410
                     'input'      => $config['input'],
2411 2411
                     'type'       => $config['type'],
2412 2412
                     'required'   => $config['required'],
2413 2413
                     'validation' => $config['validation'],
2414
-                    'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2414
+                    'value'      => isset($existing[$field]) ? $existing[$field] : $default,
2415 2415
                     'css_class'  => $config['css_class'],
2416 2416
                     'options'    => isset($config['options']) ? $config['options'] : array(),
2417 2417
                     'default'    => $default,
@@ -2426,7 +2426,7 @@  discard block
 block discarded – undo
2426 2426
 
2427 2427
         $test_settings_html = '';
2428 2428
         // print out $test_settings_fields
2429
-        if (! empty($test_settings_fields)) {
2429
+        if ( ! empty($test_settings_fields)) {
2430 2430
             echo $test_settings_fields;
2431 2431
             $test_settings_html = '<input type="submit" class="button-primary mtp-test-button alignright" ';
2432 2432
             $test_settings_html .= 'name="test_button" value="';
@@ -2473,7 +2473,7 @@  discard block
 block discarded – undo
2473 2473
         );
2474 2474
 
2475 2475
         return EEH_Template::display_template(
2476
-            EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2476
+            EE_MSG_TEMPLATE_PATH.'shortcode_selector_skeleton.template.php',
2477 2477
             $template_args,
2478 2478
             true
2479 2479
         );
@@ -2498,7 +2498,7 @@  discard block
 block discarded – undo
2498 2498
         // $messenger = $this->_message_template_group->messenger_obj();
2499 2499
         // now let's set the content depending on the status of the shortcodes array
2500 2500
         if (empty($shortcodes)) {
2501
-            $content = '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2501
+            $content = '<p>'.esc_html__('There are no valid shortcodes available', 'event_espresso').'</p>';
2502 2502
             echo $content;
2503 2503
         } else {
2504 2504
             // $alt = 0;
@@ -2536,7 +2536,7 @@  discard block
 block discarded – undo
2536 2536
     {
2537 2537
 
2538 2538
         // no need to run this if the property is already set
2539
-        if (! empty($this->_shortcodes)) {
2539
+        if ( ! empty($this->_shortcodes)) {
2540 2540
             return;
2541 2541
         }
2542 2542
 
@@ -2590,7 +2590,7 @@  discard block
 block discarded – undo
2590 2590
     protected function _set_message_template_group()
2591 2591
     {
2592 2592
 
2593
-        if (! empty($this->_message_template_group)) {
2593
+        if ( ! empty($this->_message_template_group)) {
2594 2594
             return;
2595 2595
         } //get out if this is already set.
2596 2596
 
@@ -2637,7 +2637,7 @@  discard block
 block discarded – undo
2637 2637
                     <?php
2638 2638
                 }
2639 2639
                 // setup nonce_url
2640
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2640
+                wp_nonce_field($args['action'].'_nonce', $args['action'].'_nonce', false);
2641 2641
                 ?>
2642 2642
                 <select name="context">
2643 2643
                     <?php
@@ -2647,7 +2647,7 @@  discard block
 block discarded – undo
2647 2647
                             $checked = ($context === $args['context']) ? 'selected="selected"' : '';
2648 2648
                             ?>
2649 2649
                             <option value="<?php echo $context; ?>" <?php echo $checked; ?>>
2650
-                                <?php echo $context_details[ $context ]['label']; ?>
2650
+                                <?php echo $context_details[$context]['label']; ?>
2651 2651
                             </option>
2652 2652
                         <?php endforeach;
2653 2653
                     endif; ?>
@@ -2677,22 +2677,22 @@  discard block
 block discarded – undo
2677 2677
      */
2678 2678
     protected function _set_message_template_column_values($index)
2679 2679
     {
2680
-        if (is_array($this->_req_data['MTP_template_fields'][ $index ]['content'])) {
2681
-            foreach ($this->_req_data['MTP_template_fields'][ $index ]['content'] as $field => $value) {
2682
-                $this->_req_data['MTP_template_fields'][ $index ]['content'][ $field ] = $value;
2680
+        if (is_array($this->_req_data['MTP_template_fields'][$index]['content'])) {
2681
+            foreach ($this->_req_data['MTP_template_fields'][$index]['content'] as $field => $value) {
2682
+                $this->_req_data['MTP_template_fields'][$index]['content'][$field] = $value;
2683 2683
             }
2684 2684
         }
2685 2685
 
2686 2686
 
2687 2687
         $set_column_values = array(
2688
-            'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][ $index ]['MTP_ID']),
2688
+            'MTP_ID'             => absint($this->_req_data['MTP_template_fields'][$index]['MTP_ID']),
2689 2689
             'GRP_ID'             => absint($this->_req_data['GRP_ID']),
2690 2690
             'MTP_user_id'        => absint($this->_req_data['MTP_user_id']),
2691 2691
             'MTP_messenger'      => strtolower($this->_req_data['MTP_messenger']),
2692 2692
             'MTP_message_type'   => strtolower($this->_req_data['MTP_message_type']),
2693
-            'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][ $index ]['name']),
2693
+            'MTP_template_field' => strtolower($this->_req_data['MTP_template_fields'][$index]['name']),
2694 2694
             'MTP_context'        => strtolower($this->_req_data['MTP_context']),
2695
-            'MTP_content'        => $this->_req_data['MTP_template_fields'][ $index ]['content'],
2695
+            'MTP_content'        => $this->_req_data['MTP_template_fields'][$index]['content'],
2696 2696
             'MTP_is_global'      => isset($this->_req_data['MTP_is_global'])
2697 2697
                 ? absint($this->_req_data['MTP_is_global'])
2698 2698
                 : 0,
@@ -2739,7 +2739,7 @@  discard block
 block discarded – undo
2739 2739
         $context = ucwords(str_replace('_', ' ', $context_slug));
2740 2740
 
2741 2741
         $item_desc = $messenger_label && $message_type_label
2742
-            ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2742
+            ? $messenger_label.' '.$message_type_label.' '.$context.' '
2743 2743
             : '';
2744 2744
         $item_desc .= 'Message Template';
2745 2745
         $query_args = array();
@@ -2770,7 +2770,7 @@  discard block
 block discarded – undo
2770 2770
 
2771 2771
 
2772 2772
             // run update for each template field in displayed context
2773
-            if (! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2773
+            if ( ! isset($this->_req_data['MTP_template_fields']) && empty($this->_req_data['MTP_template_fields'])) {
2774 2774
                 EE_Error::add_error(
2775 2775
                     esc_html__(
2776 2776
                         'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
@@ -2832,10 +2832,10 @@  discard block
 block discarded – undo
2832 2832
                         $set_column_values = $this->_set_message_template_column_values($template_field);
2833 2833
 
2834 2834
                         $where_cols_n_values = array(
2835
-                            'MTP_ID' => $this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'],
2835
+                            'MTP_ID' => $this->_req_data['MTP_template_fields'][$template_field]['MTP_ID'],
2836 2836
                         );
2837 2837
                         // if they aren't allowed to use all JS, restrict them to just posty-y tags
2838
-                        if (! current_user_can('unfiltered_html')) {
2838
+                        if ( ! current_user_can('unfiltered_html')) {
2839 2839
                             if (is_array($set_column_values['MTP_content'])) {
2840 2840
                                 foreach ($set_column_values['MTP_content'] as $key => $value) {
2841 2841
                                     // remove slashes so wp_kses works properly (its wp_kses_stripslashes() function
@@ -2843,7 +2843,7 @@  discard block
 block discarded – undo
2843 2843
                                     // appear invalid.) But currently the models expect slashed data, so after wp_kses
2844 2844
                                     // runs we need to re-slash the data. Sheesh. See
2845 2845
                                     // https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
2846
-                                    $set_column_values['MTP_content'][ $key ] = addslashes(
2846
+                                    $set_column_values['MTP_content'][$key] = addslashes(
2847 2847
                                         wp_kses(
2848 2848
                                             stripslashes($value),
2849 2849
                                             wp_kses_allowed_html('post')
@@ -2879,14 +2879,14 @@  discard block
 block discarded – undo
2879 2879
                             }
2880 2880
                         } else {
2881 2881
                             // only do this logic if we don't have a MTP_ID for this field
2882
-                            if (empty($this->_req_data['MTP_template_fields'][ $template_field ]['MTP_ID'])) {
2882
+                            if (empty($this->_req_data['MTP_template_fields'][$template_field]['MTP_ID'])) {
2883 2883
                                 // this has already been through the template field validator and sanitized, so it will be
2884 2884
                                 // safe to insert this field.  Why insert?  This typically happens when we introduce a new
2885 2885
                                 // message template field in a messenger/message type and existing users don't have the
2886 2886
                                 // default setup for it.
2887 2887
                                 // @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2888 2888
                                 $updated = $MTP->insert($message_template_fields);
2889
-                                if (! $updated || is_wp_error($updated)) {
2889
+                                if ( ! $updated || is_wp_error($updated)) {
2890 2890
                                     EE_Error::add_error(
2891 2891
                                         sprintf(
2892 2892
                                             esc_html__('%s field could not be updated.', 'event_espresso'),
@@ -3117,7 +3117,7 @@  discard block
 block discarded – undo
3117 3117
         // incoming GRP_IDs
3118 3118
         if ($all) {
3119 3119
             // Checkboxes
3120
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3120
+            if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3121 3121
                 // if array has more than one element then success message should be plural.
3122 3122
                 // todo: what about nonce?
3123 3123
                 $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
@@ -3125,16 +3125,16 @@  discard block
 block discarded – undo
3125 3125
                 // cycle through checkboxes
3126 3126
                 while (list($GRP_ID, $value) = each($this->_req_data['checkbox'])) {
3127 3127
                     $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3128
-                    if (! $trashed_or_restored) {
3128
+                    if ( ! $trashed_or_restored) {
3129 3129
                         $success = 0;
3130 3130
                     }
3131 3131
                 }
3132 3132
             } else {
3133 3133
                 // grab single GRP_ID and handle
3134 3134
                 $GRP_ID = isset($this->_req_data['id']) ? absint($this->_req_data['id']) : 0;
3135
-                if (! empty($GRP_ID)) {
3135
+                if ( ! empty($GRP_ID)) {
3136 3136
                     $trashed_or_restored = $trash ? $MTP->delete_by_ID($GRP_ID) : $MTP->restore_by_ID($GRP_ID);
3137
-                    if (! $trashed_or_restored) {
3137
+                    if ( ! $trashed_or_restored) {
3138 3138
                         $success = 0;
3139 3139
                     }
3140 3140
                 } else {
@@ -3182,7 +3182,7 @@  discard block
 block discarded – undo
3182 3182
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3183 3183
 
3184 3184
         // checkboxes
3185
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3185
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3186 3186
             // if array has more than one element then success message should be plural
3187 3187
             $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3188 3188
 
@@ -3289,7 +3289,7 @@  discard block
 block discarded – undo
3289 3289
     protected function _set_m_mt_settings()
3290 3290
     {
3291 3291
         // first if this is already set then lets get out no need to regenerate data.
3292
-        if (! empty($this->_m_mt_settings)) {
3292
+        if ( ! empty($this->_m_mt_settings)) {
3293 3293
             return;
3294 3294
         }
3295 3295
 
@@ -3303,7 +3303,7 @@  discard block
 block discarded – undo
3303 3303
         // assemble the array for the _tab_text_links helper
3304 3304
 
3305 3305
         foreach ($messengers as $messenger) {
3306
-            $this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = array(
3306
+            $this->_m_mt_settings['messenger_tabs'][$messenger->name] = array(
3307 3307
                 'label' => ucwords($messenger->label['singular']),
3308 3308
                 'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3309 3309
                     ? 'messenger-active'
@@ -3320,7 +3320,7 @@  discard block
 block discarded – undo
3320 3320
             foreach ($message_types as $message_type) {
3321 3321
                 // first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3322 3322
                 // it shouldn't show in either the inactive OR active metabox.
3323
-                if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3323
+                if ( ! in_array($message_type->name, $message_types_for_messenger, true)) {
3324 3324
                     continue;
3325 3325
                 }
3326 3326
 
@@ -3331,12 +3331,12 @@  discard block
 block discarded – undo
3331 3331
                     ? 'active'
3332 3332
                     : 'inactive';
3333 3333
 
3334
-                $this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = array(
3334
+                $this->_m_mt_settings['message_type_tabs'][$messenger->name][$a_or_i][$message_type->name] = array(
3335 3335
                     'label'    => ucwords($message_type->label['singular']),
3336
-                    'class'    => 'message-type-' . $a_or_i,
3337
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3338
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3339
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3336
+                    'class'    => 'message-type-'.$a_or_i,
3337
+                    'slug_id'  => $message_type->name.'-messagetype-'.$messenger->name,
3338
+                    'mt_nonce' => wp_create_nonce($message_type->name.'_nonce'),
3339
+                    'href'     => 'espresso_'.$message_type->name.'_message_type_settings',
3340 3340
                     'title'    => $a_or_i === 'active'
3341 3341
                         ? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3342 3342
                         : esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
@@ -3367,25 +3367,25 @@  discard block
 block discarded – undo
3367 3367
         $fields = $message_type->get_admin_settings_fields();
3368 3368
         $settings_template_args['template_form_fields'] = '';
3369 3369
 
3370
-        if (! empty($fields) && $active) {
3370
+        if ( ! empty($fields) && $active) {
3371 3371
             $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3372 3372
             foreach ($fields as $fldname => $fldprops) {
3373
-                $field_id = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3374
-                $template_form_field[ $field_id ] = array(
3375
-                    'name'       => 'message_type_settings[' . $fldname . ']',
3373
+                $field_id = $messenger->name.'-'.$message_type->name.'-'.$fldname;
3374
+                $template_form_field[$field_id] = array(
3375
+                    'name'       => 'message_type_settings['.$fldname.']',
3376 3376
                     'label'      => $fldprops['label'],
3377 3377
                     'input'      => $fldprops['field_type'],
3378 3378
                     'type'       => $fldprops['value_type'],
3379 3379
                     'required'   => $fldprops['required'],
3380 3380
                     'validation' => $fldprops['validation'],
3381
-                    'value'      => isset($existing_settings[ $fldname ])
3382
-                        ? $existing_settings[ $fldname ]
3381
+                    'value'      => isset($existing_settings[$fldname])
3382
+                        ? $existing_settings[$fldname]
3383 3383
                         : $fldprops['default'],
3384 3384
                     'options'    => isset($fldprops['options'])
3385 3385
                         ? $fldprops['options']
3386 3386
                         : array(),
3387
-                    'default'    => isset($existing_settings[ $fldname ])
3388
-                        ? $existing_settings[ $fldname ]
3387
+                    'default'    => isset($existing_settings[$fldname])
3388
+                        ? $existing_settings[$fldname]
3389 3389
                         : $fldprops['default'],
3390 3390
                     'css_class'  => 'no-drag',
3391 3391
                     'format'     => $fldprops['format'],
@@ -3428,7 +3428,7 @@  discard block
 block discarded – undo
3428 3428
             : '';
3429 3429
 
3430 3430
 
3431
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3431
+        $template = EE_MSG_TEMPLATE_PATH.'ee_msg_mt_settings_content.template.php';
3432 3432
         $content = EEH_Template::display_template($template, $settings_template_args, true);
3433 3433
 
3434 3434
         return $content;
@@ -3459,20 +3459,20 @@  discard block
 block discarded – undo
3459 3459
                 // messenger meta boxes
3460 3460
                 $active = $selected_messenger === $messenger;
3461 3461
                 $active_mt_tabs = isset(
3462
-                    $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3462
+                    $this->_m_mt_settings['message_type_tabs'][$messenger]['active']
3463 3463
                 )
3464
-                    ? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3464
+                    ? $this->_m_mt_settings['message_type_tabs'][$messenger]['active']
3465 3465
                     : '';
3466
-                $m_boxes[ $messenger . '_a_box' ] = sprintf(
3466
+                $m_boxes[$messenger.'_a_box'] = sprintf(
3467 3467
                     esc_html__('%s Settings', 'event_espresso'),
3468 3468
                     $tab_array['label']
3469 3469
                 );
3470
-                $m_template_args[ $messenger . '_a_box' ] = array(
3470
+                $m_template_args[$messenger.'_a_box'] = array(
3471 3471
                     'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3472 3472
                     'inactive_message_types' => isset(
3473
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3473
+                        $this->_m_mt_settings['message_type_tabs'][$messenger]['inactive']
3474 3474
                     )
3475
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3475
+                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
3476 3476
                         : '',
3477 3477
                     'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3478 3478
                     'hidden'                 => $active ? '' : ' hidden',
@@ -3483,13 +3483,13 @@  discard block
 block discarded – undo
3483 3483
                 // message type meta boxes
3484 3484
                 // (which is really just the inactive container for each messenger
3485 3485
                 // showing inactive message types for that messenger)
3486
-                $mt_boxes[ $messenger . '_i_box' ] = esc_html__('Inactive Message Types', 'event_espresso');
3487
-                $mt_template_args[ $messenger . '_i_box' ] = array(
3486
+                $mt_boxes[$messenger.'_i_box'] = esc_html__('Inactive Message Types', 'event_espresso');
3487
+                $mt_template_args[$messenger.'_i_box'] = array(
3488 3488
                     'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3489 3489
                     'inactive_message_types' => isset(
3490
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3490
+                        $this->_m_mt_settings['message_type_tabs'][$messenger]['inactive']
3491 3491
                     )
3492
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3492
+                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
3493 3493
                         : '',
3494 3494
                     'hidden'                 => $active ? '' : ' hidden',
3495 3495
                     'hide_on_message'        => $hide_on_message,
@@ -3502,14 +3502,14 @@  discard block
 block discarded – undo
3502 3502
 
3503 3503
 
3504 3504
         // register messenger metaboxes
3505
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3505
+        $m_template_path = EE_MSG_TEMPLATE_PATH.'ee_msg_details_messenger_mt_meta_box.template.php';
3506 3506
         foreach ($m_boxes as $box => $label) {
3507
-            $callback_args = array('template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]);
3507
+            $callback_args = array('template_path' => $m_template_path, 'template_args' => $m_template_args[$box]);
3508 3508
             $msgr = str_replace('_a_box', '', $box);
3509 3509
             add_meta_box(
3510
-                'espresso_' . $msgr . '_settings',
3510
+                'espresso_'.$msgr.'_settings',
3511 3511
                 $label,
3512
-                function ($post, $metabox) {
3512
+                function($post, $metabox) {
3513 3513
                     echo EEH_Template::display_template(
3514 3514
                         $metabox["args"]["template_path"],
3515 3515
                         $metabox["args"]["template_args"],
@@ -3524,17 +3524,17 @@  discard block
 block discarded – undo
3524 3524
         }
3525 3525
 
3526 3526
         // register message type metaboxes
3527
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3527
+        $mt_template_path = EE_MSG_TEMPLATE_PATH.'ee_msg_details_messenger_meta_box.template.php';
3528 3528
         foreach ($mt_boxes as $box => $label) {
3529 3529
             $callback_args = array(
3530 3530
                 'template_path' => $mt_template_path,
3531
-                'template_args' => $mt_template_args[ $box ],
3531
+                'template_args' => $mt_template_args[$box],
3532 3532
             );
3533 3533
             $mt = str_replace('_i_box', '', $box);
3534 3534
             add_meta_box(
3535
-                'espresso_' . $mt . '_inactive_mts',
3535
+                'espresso_'.$mt.'_inactive_mts',
3536 3536
                 $label,
3537
-                function ($post, $metabox) {
3537
+                function($post, $metabox) {
3538 3538
                     echo EEH_Template::display_template(
3539 3539
                         $metabox["args"]["template_path"],
3540 3540
                         $metabox["args"]["template_args"],
@@ -3680,7 +3680,7 @@  discard block
 block discarded – undo
3680 3680
             if ($form->is_valid()) {
3681 3681
                 $valid_data = $form->valid_data();
3682 3682
                 foreach ($valid_data as $property => $value) {
3683
-                    $setter = 'set_' . $property;
3683
+                    $setter = 'set_'.$property;
3684 3684
                     if (method_exists($network_config, $setter)) {
3685 3685
                         $network_config->{$setter}($value);
3686 3686
                     } elseif (property_exists($network_config, $property)
@@ -3714,7 +3714,7 @@  discard block
 block discarded – undo
3714 3714
     protected function _get_mt_tabs($tab_array)
3715 3715
     {
3716 3716
         $tab_array = (array) $tab_array;
3717
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3717
+        $template = EE_MSG_TEMPLATE_PATH.'ee_msg_details_mt_settings_tab_item.template.php';
3718 3718
         $tabs = '';
3719 3719
 
3720 3720
         foreach ($tab_array as $tab) {
@@ -3742,20 +3742,20 @@  discard block
 block discarded – undo
3742 3742
         $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3743 3743
 
3744 3744
 
3745
-        if (! empty($fields)) {
3745
+        if ( ! empty($fields)) {
3746 3746
             $existing_settings = $messenger->get_existing_admin_settings();
3747 3747
 
3748 3748
             foreach ($fields as $fldname => $fldprops) {
3749
-                $field_id = $messenger->name . '-' . $fldname;
3750
-                $template_form_field[ $field_id ] = array(
3751
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3749
+                $field_id = $messenger->name.'-'.$fldname;
3750
+                $template_form_field[$field_id] = array(
3751
+                    'name'       => 'messenger_settings['.$field_id.']',
3752 3752
                     'label'      => $fldprops['label'],
3753 3753
                     'input'      => $fldprops['field_type'],
3754 3754
                     'type'       => $fldprops['value_type'],
3755 3755
                     'required'   => $fldprops['required'],
3756 3756
                     'validation' => $fldprops['validation'],
3757
-                    'value'      => isset($existing_settings[ $field_id ])
3758
-                        ? $existing_settings[ $field_id ]
3757
+                    'value'      => isset($existing_settings[$field_id])
3758
+                        ? $existing_settings[$field_id]
3759 3759
                         : $fldprops['default'],
3760 3760
                     'css_class'  => '',
3761 3761
                     'format'     => $fldprops['format'],
@@ -3781,9 +3781,9 @@  discard block
 block discarded – undo
3781 3781
         );
3782 3782
 
3783 3783
         // make sure any active message types that are existing are included in the hidden fields
3784
-        if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3785
-            foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3786
-                $settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = array(
3784
+        if (isset($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'])) {
3785
+            foreach ($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'] as $mt => $values) {
3786
+                $settings_template_args['hidden_fields']['messenger_settings[message_types]['.$mt.']'] = array(
3787 3787
                     'type'  => 'hidden',
3788 3788
                     'value' => $mt,
3789 3789
                 );
@@ -3812,9 +3812,9 @@  discard block
 block discarded – undo
3812 3812
 
3813 3813
 
3814 3814
         $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3815
-        $settings_template_args['nonce'] = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3815
+        $settings_template_args['nonce'] = wp_create_nonce('activate_'.$messenger->name.'_toggle_nonce');
3816 3816
         $settings_template_args['on_off_status'] = $active ? true : false;
3817
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3817
+        $template = EE_MSG_TEMPLATE_PATH.'ee_msg_m_settings_content.template.php';
3818 3818
         $content = EEH_Template::display_template(
3819 3819
             $template,
3820 3820
             $settings_template_args,
@@ -3840,7 +3840,7 @@  discard block
 block discarded – undo
3840 3840
         $success = true;
3841 3841
         $this->_prep_default_response_for_messenger_or_message_type_toggle();
3842 3842
         // let's check that we have required data
3843
-        if (! isset($this->_req_data['messenger'])) {
3843
+        if ( ! isset($this->_req_data['messenger'])) {
3844 3844
             EE_Error::add_error(
3845 3845
                 esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3846 3846
                 __FILE__,
@@ -3854,12 +3854,12 @@  discard block
 block discarded – undo
3854 3854
         $nonce = isset($this->_req_data['activate_nonce'])
3855 3855
             ? sanitize_text_field($this->_req_data['activate_nonce'])
3856 3856
             : '';
3857
-        $nonce_ref = 'activate_' . $this->_req_data['messenger'] . '_toggle_nonce';
3857
+        $nonce_ref = 'activate_'.$this->_req_data['messenger'].'_toggle_nonce';
3858 3858
 
3859 3859
         $this->_verify_nonce($nonce, $nonce_ref);
3860 3860
 
3861 3861
 
3862
-        if (! isset($this->_req_data['status'])) {
3862
+        if ( ! isset($this->_req_data['status'])) {
3863 3863
             EE_Error::add_error(
3864 3864
                 esc_html__(
3865 3865
                     'Messenger status needed to know whether activation or deactivation is happening. No status is given',
@@ -3918,7 +3918,7 @@  discard block
 block discarded – undo
3918 3918
         $this->_prep_default_response_for_messenger_or_message_type_toggle();
3919 3919
 
3920 3920
         // let's make sure we have the necessary data
3921
-        if (! isset($this->_req_data['message_type'])) {
3921
+        if ( ! isset($this->_req_data['message_type'])) {
3922 3922
             EE_Error::add_error(
3923 3923
                 esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3924 3924
                 __FILE__,
@@ -3928,7 +3928,7 @@  discard block
 block discarded – undo
3928 3928
             $success = false;
3929 3929
         }
3930 3930
 
3931
-        if (! isset($this->_req_data['messenger'])) {
3931
+        if ( ! isset($this->_req_data['messenger'])) {
3932 3932
             EE_Error::add_error(
3933 3933
                 esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3934 3934
                 __FILE__,
@@ -3938,7 +3938,7 @@  discard block
 block discarded – undo
3938 3938
             $success = false;
3939 3939
         }
3940 3940
 
3941
-        if (! isset($this->_req_data['status'])) {
3941
+        if ( ! isset($this->_req_data['status'])) {
3942 3942
             EE_Error::add_error(
3943 3943
                 esc_html__(
3944 3944
                     'Messenger status needed to know whether activation or deactivation is happening. No status is given',
@@ -3971,7 +3971,7 @@  discard block
 block discarded – undo
3971 3971
 
3972 3972
         // do a nonce check here since we're not arriving via a normal route
3973 3973
         $nonce = isset($this->_req_data['mt_nonce']) ? sanitize_text_field($this->_req_data['mt_nonce']) : '';
3974
-        $nonce_ref = $this->_req_data['message_type'] . '_nonce';
3974
+        $nonce_ref = $this->_req_data['message_type'].'_nonce';
3975 3975
 
3976 3976
         $this->_verify_nonce($nonce, $nonce_ref);
3977 3977
 
@@ -4158,7 +4158,7 @@  discard block
 block discarded – undo
4158 4158
         EE_Message_Type $message_type = null
4159 4159
     ) {
4160 4160
         // if $messenger isn't a valid messenger object then get out.
4161
-        if (! $messenger instanceof EE_Messenger) {
4161
+        if ( ! $messenger instanceof EE_Messenger) {
4162 4162
             EE_Error::add_error(
4163 4163
                 esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4164 4164
                 __FILE__,
@@ -4213,7 +4213,7 @@  discard block
 block discarded – undo
4213 4213
             // message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4214 4214
             // in which case we just give a success message for the messenger being successfully activated.
4215 4215
         } else {
4216
-            if (! $messenger->get_default_message_types()) {
4216
+            if ( ! $messenger->get_default_message_types()) {
4217 4217
                 // messenger doesn't have any default message types so still a success.
4218 4218
                 EE_Error::add_success(
4219 4219
                     sprintf(
@@ -4269,7 +4269,7 @@  discard block
 block discarded – undo
4269 4269
         EE_Error::overwrite_success();
4270 4270
 
4271 4271
         // if $messenger isn't a valid messenger object then get out.
4272
-        if (! $messenger instanceof EE_Messenger) {
4272
+        if ( ! $messenger instanceof EE_Messenger) {
4273 4273
             EE_Error::add_error(
4274 4274
                 esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4275 4275
                 __FILE__,
@@ -4331,7 +4331,7 @@  discard block
 block discarded – undo
4331 4331
      */
4332 4332
     public function update_mt_form()
4333 4333
     {
4334
-        if (! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4334
+        if ( ! isset($this->_req_data['messenger']) || ! isset($this->_req_data['message_type'])) {
4335 4335
             EE_Error::add_error(
4336 4336
                 esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4337 4337
                 __FILE__,
@@ -4343,7 +4343,7 @@  discard block
 block discarded – undo
4343 4343
 
4344 4344
         $message_types = $this->get_installed_message_types();
4345 4345
 
4346
-        $message_type = $message_types[ $this->_req_data['message_type'] ];
4346
+        $message_type = $message_types[$this->_req_data['message_type']];
4347 4347
         $messenger = $this->_message_resource_manager->get_active_messenger($this->_req_data['messenger']);
4348 4348
 
4349 4349
         $content = $this->_message_type_settings_content(
@@ -4363,7 +4363,7 @@  discard block
 block discarded – undo
4363 4363
      */
4364 4364
     public function save_settings()
4365 4365
     {
4366
-        if (! isset($this->_req_data['type'])) {
4366
+        if ( ! isset($this->_req_data['type'])) {
4367 4367
             EE_Error::add_error(
4368 4368
                 esc_html__(
4369 4369
                     'Cannot save settings because type is unknown (messenger settings or messsage type settings?)',
@@ -4392,7 +4392,7 @@  discard block
 block discarded – undo
4392 4392
                         unset($settings['message_types']);
4393 4393
                         break;
4394 4394
                     default:
4395
-                        $settings[ $key ] = $value;
4395
+                        $settings[$key] = $value;
4396 4396
                         break;
4397 4397
                 }
4398 4398
             }
@@ -4411,7 +4411,7 @@  discard block
 block discarded – undo
4411 4411
                         unset($settings['message_type']);
4412 4412
                         break;
4413 4413
                     default:
4414
-                        $settings[ $key ] = $value;
4414
+                        $settings[$key] = $value;
4415 4415
                         break;
4416 4416
                 }
4417 4417
             }
@@ -4572,7 +4572,7 @@  discard block
 block discarded – undo
4572 4572
      */
4573 4573
     protected function _get_msg_ids_from_request()
4574 4574
     {
4575
-        if (! isset($this->_req_data['MSG_ID'])) {
4575
+        if ( ! isset($this->_req_data['MSG_ID'])) {
4576 4576
             return array();
4577 4577
         }
4578 4578
 
Please login to merge, or discard this patch.
caffeinated/admin/new/pricing/espresso_events_Pricing_Hooks.class.php 2 patches
Indentation   +2141 added lines, -2141 removed lines patch added patch discarded remove patch
@@ -15,2201 +15,2201 @@
 block discarded – undo
15 15
 class espresso_events_Pricing_Hooks extends EE_Admin_Hooks
16 16
 {
17 17
 
18
-    /**
19
-     * This property is just used to hold the status of whether an event is currently being
20
-     * created (true) or edited (false)
21
-     *
22
-     * @access protected
23
-     * @var bool
24
-     */
25
-    protected $_is_creating_event;
18
+	/**
19
+	 * This property is just used to hold the status of whether an event is currently being
20
+	 * created (true) or edited (false)
21
+	 *
22
+	 * @access protected
23
+	 * @var bool
24
+	 */
25
+	protected $_is_creating_event;
26 26
 
27
-    /**
28
-     * Used to contain the format strings for date and time that will be used for php date and
29
-     * time.
30
-     * Is set in the _set_hooks_properties() method.
31
-     *
32
-     * @var array
33
-     */
34
-    protected $_date_format_strings;
27
+	/**
28
+	 * Used to contain the format strings for date and time that will be used for php date and
29
+	 * time.
30
+	 * Is set in the _set_hooks_properties() method.
31
+	 *
32
+	 * @var array
33
+	 */
34
+	protected $_date_format_strings;
35 35
 
36
-    /**
37
-     * @var string $_date_time_format
38
-     */
39
-    protected $_date_time_format;
36
+	/**
37
+	 * @var string $_date_time_format
38
+	 */
39
+	protected $_date_time_format;
40 40
 
41 41
 
42
-    /**
43
-     * @throws InvalidArgumentException
44
-     * @throws InvalidInterfaceException
45
-     * @throws InvalidDataTypeException
46
-     */
47
-    protected function _set_hooks_properties()
48
-    {
49
-        $this->_name = 'pricing';
50
-        // capability check
51
-        if (EE_Registry::instance()->CFG->admin->useAdvancedEditor() ||
52
-            ! EE_Registry::instance()->CAP->current_user_can(
53
-                'ee_read_default_prices',
54
-                'advanced_ticket_datetime_metabox'
55
-            )
56
-        ) {
57
-            return;
58
-        }
59
-        $this->_setup_metaboxes();
60
-        $this->_set_date_time_formats();
61
-        $this->_validate_format_strings();
62
-        $this->_set_scripts_styles();
63
-        // commented out temporarily until logic is implemented in callback
64
-        // add_action(
65
-        //     'AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_Extend_Events_Admin_Page',
66
-        //     array($this, 'autosave_handling')
67
-        // );
68
-        add_filter(
69
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
70
-            array($this, 'caf_updates')
71
-        );
72
-    }
42
+	/**
43
+	 * @throws InvalidArgumentException
44
+	 * @throws InvalidInterfaceException
45
+	 * @throws InvalidDataTypeException
46
+	 */
47
+	protected function _set_hooks_properties()
48
+	{
49
+		$this->_name = 'pricing';
50
+		// capability check
51
+		if (EE_Registry::instance()->CFG->admin->useAdvancedEditor() ||
52
+			! EE_Registry::instance()->CAP->current_user_can(
53
+				'ee_read_default_prices',
54
+				'advanced_ticket_datetime_metabox'
55
+			)
56
+		) {
57
+			return;
58
+		}
59
+		$this->_setup_metaboxes();
60
+		$this->_set_date_time_formats();
61
+		$this->_validate_format_strings();
62
+		$this->_set_scripts_styles();
63
+		// commented out temporarily until logic is implemented in callback
64
+		// add_action(
65
+		//     'AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_Extend_Events_Admin_Page',
66
+		//     array($this, 'autosave_handling')
67
+		// );
68
+		add_filter(
69
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
70
+			array($this, 'caf_updates')
71
+		);
72
+	}
73 73
 
74 74
 
75
-    /**
76
-     * @return void
77
-     */
78
-    protected function _setup_metaboxes()
79
-    {
80
-        // if we were going to add our own metaboxes we'd use the below.
81
-        $this->_metaboxes = array(
82
-            0 => array(
83
-                'page_route' => array('edit', 'create_new'),
84
-                'func'       => 'pricing_metabox',
85
-                'label'      => esc_html__('Event Tickets & Datetimes', 'event_espresso'),
86
-                'priority'   => 'high',
87
-                'context'    => 'normal',
88
-            ),
89
-        );
90
-        $this->_remove_metaboxes = array(
91
-            0 => array(
92
-                'page_route' => array('edit', 'create_new'),
93
-                'id'         => 'espresso_event_editor_tickets',
94
-                'context'    => 'normal',
95
-            ),
96
-        );
97
-    }
75
+	/**
76
+	 * @return void
77
+	 */
78
+	protected function _setup_metaboxes()
79
+	{
80
+		// if we were going to add our own metaboxes we'd use the below.
81
+		$this->_metaboxes = array(
82
+			0 => array(
83
+				'page_route' => array('edit', 'create_new'),
84
+				'func'       => 'pricing_metabox',
85
+				'label'      => esc_html__('Event Tickets & Datetimes', 'event_espresso'),
86
+				'priority'   => 'high',
87
+				'context'    => 'normal',
88
+			),
89
+		);
90
+		$this->_remove_metaboxes = array(
91
+			0 => array(
92
+				'page_route' => array('edit', 'create_new'),
93
+				'id'         => 'espresso_event_editor_tickets',
94
+				'context'    => 'normal',
95
+			),
96
+		);
97
+	}
98 98
 
99 99
 
100
-    /**
101
-     * @return void
102
-     */
103
-    protected function _set_date_time_formats()
104
-    {
105
-        /**
106
-         * Format strings for date and time.  Defaults are existing behaviour from 4.1.
107
-         * Note, that if you return null as the value for 'date', and 'time' in the array, then
108
-         * EE will automatically use the set wp_options, 'date_format', and 'time_format'.
109
-         *
110
-         * @since 4.6.7
111
-         * @var array  Expected an array returned with 'date' and 'time' keys.
112
-         */
113
-        $this->_date_format_strings = apply_filters(
114
-            'FHEE__espresso_events_Pricing_Hooks___set_hooks_properties__date_format_strings',
115
-            array(
116
-                'date' => 'Y-m-d',
117
-                'time' => 'h:i a',
118
-            )
119
-        );
120
-        // validate
121
-        $this->_date_format_strings['date'] = isset($this->_date_format_strings['date'])
122
-            ? $this->_date_format_strings['date']
123
-            : null;
124
-        $this->_date_format_strings['time'] = isset($this->_date_format_strings['time'])
125
-            ? $this->_date_format_strings['time']
126
-            : null;
127
-        $this->_date_time_format = $this->_date_format_strings['date']
128
-                                   . ' '
129
-                                   . $this->_date_format_strings['time'];
130
-    }
100
+	/**
101
+	 * @return void
102
+	 */
103
+	protected function _set_date_time_formats()
104
+	{
105
+		/**
106
+		 * Format strings for date and time.  Defaults are existing behaviour from 4.1.
107
+		 * Note, that if you return null as the value for 'date', and 'time' in the array, then
108
+		 * EE will automatically use the set wp_options, 'date_format', and 'time_format'.
109
+		 *
110
+		 * @since 4.6.7
111
+		 * @var array  Expected an array returned with 'date' and 'time' keys.
112
+		 */
113
+		$this->_date_format_strings = apply_filters(
114
+			'FHEE__espresso_events_Pricing_Hooks___set_hooks_properties__date_format_strings',
115
+			array(
116
+				'date' => 'Y-m-d',
117
+				'time' => 'h:i a',
118
+			)
119
+		);
120
+		// validate
121
+		$this->_date_format_strings['date'] = isset($this->_date_format_strings['date'])
122
+			? $this->_date_format_strings['date']
123
+			: null;
124
+		$this->_date_format_strings['time'] = isset($this->_date_format_strings['time'])
125
+			? $this->_date_format_strings['time']
126
+			: null;
127
+		$this->_date_time_format = $this->_date_format_strings['date']
128
+								   . ' '
129
+								   . $this->_date_format_strings['time'];
130
+	}
131 131
 
132 132
 
133
-    /**
134
-     * @return void
135
-     */
136
-    protected function _validate_format_strings()
137
-    {
138
-        // validate format strings
139
-        $format_validation = EEH_DTT_Helper::validate_format_string(
140
-            $this->_date_time_format
141
-        );
142
-        if (is_array($format_validation)) {
143
-            $msg = '<p>';
144
-            $msg .= sprintf(
145
-                esc_html__(
146
-                    'The format "%s" was likely added via a filter and is invalid for the following reasons:',
147
-                    'event_espresso'
148
-                ),
149
-                $this->_date_time_format
150
-            );
151
-            $msg .= '</p><ul>';
152
-            foreach ($format_validation as $error) {
153
-                $msg .= '<li>' . $error . '</li>';
154
-            }
155
-            $msg .= '</ul><p>';
156
-            $msg .= sprintf(
157
-                esc_html__(
158
-                    '%sPlease note that your date and time formats have been reset to "Y-m-d" and "h:i a" respectively.%s',
159
-                    'event_espresso'
160
-                ),
161
-                '<span style="color:#D54E21;">',
162
-                '</span>'
163
-            );
164
-            $msg .= '</p>';
165
-            EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
166
-            $this->_date_format_strings = array(
167
-                'date' => 'Y-m-d',
168
-                'time' => 'h:i a',
169
-            );
170
-        }
171
-    }
133
+	/**
134
+	 * @return void
135
+	 */
136
+	protected function _validate_format_strings()
137
+	{
138
+		// validate format strings
139
+		$format_validation = EEH_DTT_Helper::validate_format_string(
140
+			$this->_date_time_format
141
+		);
142
+		if (is_array($format_validation)) {
143
+			$msg = '<p>';
144
+			$msg .= sprintf(
145
+				esc_html__(
146
+					'The format "%s" was likely added via a filter and is invalid for the following reasons:',
147
+					'event_espresso'
148
+				),
149
+				$this->_date_time_format
150
+			);
151
+			$msg .= '</p><ul>';
152
+			foreach ($format_validation as $error) {
153
+				$msg .= '<li>' . $error . '</li>';
154
+			}
155
+			$msg .= '</ul><p>';
156
+			$msg .= sprintf(
157
+				esc_html__(
158
+					'%sPlease note that your date and time formats have been reset to "Y-m-d" and "h:i a" respectively.%s',
159
+					'event_espresso'
160
+				),
161
+				'<span style="color:#D54E21;">',
162
+				'</span>'
163
+			);
164
+			$msg .= '</p>';
165
+			EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
166
+			$this->_date_format_strings = array(
167
+				'date' => 'Y-m-d',
168
+				'time' => 'h:i a',
169
+			);
170
+		}
171
+	}
172 172
 
173 173
 
174
-    /**
175
-     * @return void
176
-     */
177
-    protected function _set_scripts_styles()
178
-    {
179
-        $this->_scripts_styles = array(
180
-            'registers'   => array(
181
-                'ee-tickets-datetimes-css' => array(
182
-                    'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
183
-                    'type' => 'css',
184
-                ),
185
-                'ee-dtt-ticket-metabox'    => array(
186
-                    'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
187
-                    'depends' => array('ee-datepicker', 'ee-dialog', 'underscore'),
188
-                ),
189
-            ),
190
-            'deregisters' => array(
191
-                'event-editor-css'       => array('type' => 'css'),
192
-                'event-datetime-metabox' => array('type' => 'js'),
193
-            ),
194
-            'enqueues'    => array(
195
-                'ee-tickets-datetimes-css' => array('edit', 'create_new'),
196
-                'ee-dtt-ticket-metabox'    => array('edit', 'create_new'),
197
-            ),
198
-            'localize'    => array(
199
-                'ee-dtt-ticket-metabox' => array(
200
-                    'DTT_TRASH_BLOCK'       => array(
201
-                        'main_warning'            => esc_html__(
202
-                            'The Datetime you are attempting to trash is the only datetime selected for the following ticket(s):',
203
-                            'event_espresso'
204
-                        ),
205
-                        'after_warning'           => esc_html__(
206
-                            'In order to trash this datetime you must first make sure the above ticket(s) are assigned to other datetimes.',
207
-                            'event_espresso'
208
-                        ),
209
-                        'cancel_button'           => '<button class="button-secondary ee-modal-cancel">'
210
-                                                     . esc_html__('Cancel', 'event_espresso') . '</button>',
211
-                        'close_button'            => '<button class="button-secondary ee-modal-cancel">'
212
-                                                     . esc_html__('Close', 'event_espresso') . '</button>',
213
-                        'single_warning_from_tkt' => esc_html__(
214
-                            'The Datetime you are attempting to unassign from this ticket is the only remaining datetime for this ticket. Tickets must always have at least one datetime assigned to them.',
215
-                            'event_espresso'
216
-                        ),
217
-                        'single_warning_from_dtt' => esc_html__(
218
-                            'The ticket you are attempting to unassign from this datetime cannot be unassigned because the datetime is the only remaining datetime for the ticket.  Tickets must always have at least one datetime assigned to them.',
219
-                            'event_espresso'
220
-                        ),
221
-                        'dismiss_button'          => '<button class="button-secondary ee-modal-cancel">'
222
-                                                     . esc_html__('Dismiss', 'event_espresso') . '</button>',
223
-                    ),
224
-                    'DTT_ERROR_MSG'         => array(
225
-                        'no_ticket_name' => esc_html__('General Admission', 'event_espresso'),
226
-                        'dismiss_button' => '<div class="save-cancel-button-container">'
227
-                                            . '<button class="button-secondary ee-modal-cancel">'
228
-                                            . esc_html__('Dismiss', 'event_espresso')
229
-                                            . '</button></div>',
230
-                    ),
231
-                    'DTT_OVERSELL_WARNING'  => array(
232
-                        'datetime_ticket' => esc_html__(
233
-                            'You cannot add this ticket to this datetime because it has a sold amount that is greater than the amount of spots remaining for this datetime.',
234
-                            'event_espresso'
235
-                        ),
236
-                        'ticket_datetime' => esc_html__(
237
-                            'You cannot add this datetime to this ticket because the ticket has a sold amount that is greater than the amount of spots remaining on the datetime.',
238
-                            'event_espresso'
239
-                        ),
240
-                    ),
241
-                    'DTT_CONVERTED_FORMATS' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats(
242
-                        $this->_date_format_strings['date'],
243
-                        $this->_date_format_strings['time']
244
-                    ),
245
-                    'DTT_START_OF_WEEK'     => array('dayValue' => (int) get_option('start_of_week')),
246
-                ),
247
-            ),
248
-        );
249
-    }
174
+	/**
175
+	 * @return void
176
+	 */
177
+	protected function _set_scripts_styles()
178
+	{
179
+		$this->_scripts_styles = array(
180
+			'registers'   => array(
181
+				'ee-tickets-datetimes-css' => array(
182
+					'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
183
+					'type' => 'css',
184
+				),
185
+				'ee-dtt-ticket-metabox'    => array(
186
+					'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
187
+					'depends' => array('ee-datepicker', 'ee-dialog', 'underscore'),
188
+				),
189
+			),
190
+			'deregisters' => array(
191
+				'event-editor-css'       => array('type' => 'css'),
192
+				'event-datetime-metabox' => array('type' => 'js'),
193
+			),
194
+			'enqueues'    => array(
195
+				'ee-tickets-datetimes-css' => array('edit', 'create_new'),
196
+				'ee-dtt-ticket-metabox'    => array('edit', 'create_new'),
197
+			),
198
+			'localize'    => array(
199
+				'ee-dtt-ticket-metabox' => array(
200
+					'DTT_TRASH_BLOCK'       => array(
201
+						'main_warning'            => esc_html__(
202
+							'The Datetime you are attempting to trash is the only datetime selected for the following ticket(s):',
203
+							'event_espresso'
204
+						),
205
+						'after_warning'           => esc_html__(
206
+							'In order to trash this datetime you must first make sure the above ticket(s) are assigned to other datetimes.',
207
+							'event_espresso'
208
+						),
209
+						'cancel_button'           => '<button class="button-secondary ee-modal-cancel">'
210
+													 . esc_html__('Cancel', 'event_espresso') . '</button>',
211
+						'close_button'            => '<button class="button-secondary ee-modal-cancel">'
212
+													 . esc_html__('Close', 'event_espresso') . '</button>',
213
+						'single_warning_from_tkt' => esc_html__(
214
+							'The Datetime you are attempting to unassign from this ticket is the only remaining datetime for this ticket. Tickets must always have at least one datetime assigned to them.',
215
+							'event_espresso'
216
+						),
217
+						'single_warning_from_dtt' => esc_html__(
218
+							'The ticket you are attempting to unassign from this datetime cannot be unassigned because the datetime is the only remaining datetime for the ticket.  Tickets must always have at least one datetime assigned to them.',
219
+							'event_espresso'
220
+						),
221
+						'dismiss_button'          => '<button class="button-secondary ee-modal-cancel">'
222
+													 . esc_html__('Dismiss', 'event_espresso') . '</button>',
223
+					),
224
+					'DTT_ERROR_MSG'         => array(
225
+						'no_ticket_name' => esc_html__('General Admission', 'event_espresso'),
226
+						'dismiss_button' => '<div class="save-cancel-button-container">'
227
+											. '<button class="button-secondary ee-modal-cancel">'
228
+											. esc_html__('Dismiss', 'event_espresso')
229
+											. '</button></div>',
230
+					),
231
+					'DTT_OVERSELL_WARNING'  => array(
232
+						'datetime_ticket' => esc_html__(
233
+							'You cannot add this ticket to this datetime because it has a sold amount that is greater than the amount of spots remaining for this datetime.',
234
+							'event_espresso'
235
+						),
236
+						'ticket_datetime' => esc_html__(
237
+							'You cannot add this datetime to this ticket because the ticket has a sold amount that is greater than the amount of spots remaining on the datetime.',
238
+							'event_espresso'
239
+						),
240
+					),
241
+					'DTT_CONVERTED_FORMATS' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats(
242
+						$this->_date_format_strings['date'],
243
+						$this->_date_format_strings['time']
244
+					),
245
+					'DTT_START_OF_WEEK'     => array('dayValue' => (int) get_option('start_of_week')),
246
+				),
247
+			),
248
+		);
249
+	}
250 250
 
251 251
 
252
-    /**
253
-     * @param array $update_callbacks
254
-     * @return array
255
-     */
256
-    public function caf_updates(array $update_callbacks)
257
-    {
258
-        foreach ($update_callbacks as $key => $callback) {
259
-            if ($callback[1] === '_default_tickets_update') {
260
-                unset($update_callbacks[ $key ]);
261
-            }
262
-        }
263
-        $update_callbacks[] = array($this, 'datetime_and_tickets_caf_update');
264
-        return $update_callbacks;
265
-    }
252
+	/**
253
+	 * @param array $update_callbacks
254
+	 * @return array
255
+	 */
256
+	public function caf_updates(array $update_callbacks)
257
+	{
258
+		foreach ($update_callbacks as $key => $callback) {
259
+			if ($callback[1] === '_default_tickets_update') {
260
+				unset($update_callbacks[ $key ]);
261
+			}
262
+		}
263
+		$update_callbacks[] = array($this, 'datetime_and_tickets_caf_update');
264
+		return $update_callbacks;
265
+	}
266 266
 
267 267
 
268
-    /**
269
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
270
-     *
271
-     * @param  EE_Event $event The Event object we're attaching data to
272
-     * @param  array    $data  The request data from the form
273
-     * @throws ReflectionException
274
-     * @throws Exception
275
-     * @throws InvalidInterfaceException
276
-     * @throws InvalidDataTypeException
277
-     * @throws EE_Error
278
-     * @throws InvalidArgumentException
279
-     */
280
-    public function datetime_and_tickets_caf_update($event, $data)
281
-    {
282
-        // first we need to start with datetimes cause they are the "root" items attached to events.
283
-        $saved_datetimes = $this->_update_datetimes($event, $data);
284
-        // next tackle the tickets (and prices?)
285
-        $this->_update_tickets($event, $saved_datetimes, $data);
286
-    }
268
+	/**
269
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
270
+	 *
271
+	 * @param  EE_Event $event The Event object we're attaching data to
272
+	 * @param  array    $data  The request data from the form
273
+	 * @throws ReflectionException
274
+	 * @throws Exception
275
+	 * @throws InvalidInterfaceException
276
+	 * @throws InvalidDataTypeException
277
+	 * @throws EE_Error
278
+	 * @throws InvalidArgumentException
279
+	 */
280
+	public function datetime_and_tickets_caf_update($event, $data)
281
+	{
282
+		// first we need to start with datetimes cause they are the "root" items attached to events.
283
+		$saved_datetimes = $this->_update_datetimes($event, $data);
284
+		// next tackle the tickets (and prices?)
285
+		$this->_update_tickets($event, $saved_datetimes, $data);
286
+	}
287 287
 
288 288
 
289
-    /**
290
-     * update event_datetimes
291
-     *
292
-     * @param  EE_Event $event Event being updated
293
-     * @param  array    $data  the request data from the form
294
-     * @return EE_Datetime[]
295
-     * @throws Exception
296
-     * @throws ReflectionException
297
-     * @throws InvalidInterfaceException
298
-     * @throws InvalidDataTypeException
299
-     * @throws InvalidArgumentException
300
-     * @throws EE_Error
301
-     */
302
-    protected function _update_datetimes($event, $data)
303
-    {
304
-        $timezone = isset($data['timezone_string']) ? $data['timezone_string'] : null;
305
-        $saved_dtt_ids = array();
306
-        $saved_dtt_objs = array();
307
-        if (empty($data['edit_event_datetimes']) || ! is_array($data['edit_event_datetimes'])) {
308
-            throw new InvalidArgumentException(
309
-                esc_html__(
310
-                    'The "edit_event_datetimes" array is invalid therefore the event can not be updated.',
311
-                    'event_espresso'
312
-                )
313
-            );
314
-        }
315
-        foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
316
-            // trim all values to ensure any excess whitespace is removed.
317
-            $datetime_data = array_map(
318
-                function ($datetime_data) {
319
-                    return is_array($datetime_data) ? $datetime_data : trim($datetime_data);
320
-                },
321
-                $datetime_data
322
-            );
323
-            $datetime_data['DTT_EVT_end'] = isset($datetime_data['DTT_EVT_end'])
324
-                                            && ! empty($datetime_data['DTT_EVT_end'])
325
-                ? $datetime_data['DTT_EVT_end']
326
-                : $datetime_data['DTT_EVT_start'];
327
-            $datetime_values = array(
328
-                'DTT_ID'          => ! empty($datetime_data['DTT_ID'])
329
-                    ? $datetime_data['DTT_ID']
330
-                    : null,
331
-                'DTT_name'        => ! empty($datetime_data['DTT_name'])
332
-                    ? $datetime_data['DTT_name']
333
-                    : '',
334
-                'DTT_description' => ! empty($datetime_data['DTT_description'])
335
-                    ? $datetime_data['DTT_description']
336
-                    : '',
337
-                'DTT_EVT_start'   => $datetime_data['DTT_EVT_start'],
338
-                'DTT_EVT_end'     => $datetime_data['DTT_EVT_end'],
339
-                'DTT_reg_limit'   => empty($datetime_data['DTT_reg_limit'])
340
-                    ? EE_INF
341
-                    : $datetime_data['DTT_reg_limit'],
342
-                'DTT_order'       => ! isset($datetime_data['DTT_order'])
343
-                    ? $row
344
-                    : $datetime_data['DTT_order'],
345
-            );
346
-            // if we have an id then let's get existing object first and then set the new values.
347
-            // Otherwise we instantiate a new object for save.
348
-            if (! empty($datetime_data['DTT_ID'])) {
349
-                $datetime = EE_Registry::instance()
350
-                                       ->load_model('Datetime', array($timezone))
351
-                                       ->get_one_by_ID($datetime_data['DTT_ID']);
352
-                // set date and time format according to what is set in this class.
353
-                $datetime->set_date_format($this->_date_format_strings['date']);
354
-                $datetime->set_time_format($this->_date_format_strings['time']);
355
-                foreach ($datetime_values as $field => $value) {
356
-                    $datetime->set($field, $value);
357
-                }
358
-                // make sure the $dtt_id here is saved just in case
359
-                // after the add_relation_to() the autosave replaces it.
360
-                // We need to do this so we dont' TRASH the parent DTT.
361
-                // (save the ID for both key and value to avoid duplications)
362
-                $saved_dtt_ids[ $datetime->ID() ] = $datetime->ID();
363
-            } else {
364
-                $datetime = EE_Registry::instance()->load_class(
365
-                    'Datetime',
366
-                    array(
367
-                        $datetime_values,
368
-                        $timezone,
369
-                        array($this->_date_format_strings['date'], $this->_date_format_strings['time']),
370
-                    ),
371
-                    false,
372
-                    false
373
-                );
374
-                foreach ($datetime_values as $field => $value) {
375
-                    $datetime->set($field, $value);
376
-                }
377
-            }
378
-            $datetime->save();
379
-            $datetime = $event->_add_relation_to($datetime, 'Datetime');
380
-            // before going any further make sure our dates are setup correctly
381
-            // so that the end date is always equal or greater than the start date.
382
-            if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
383
-                $datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
384
-                $datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
385
-                $datetime->save();
386
-            }
387
-            // now we have to make sure we add the new DTT_ID to the $saved_dtt_ids array
388
-            // because it is possible there was a new one created for the autosave.
389
-            // (save the ID for both key and value to avoid duplications)
390
-            $DTT_ID = $datetime->ID();
391
-            $saved_dtt_ids[ $DTT_ID ] = $DTT_ID;
392
-            $saved_dtt_objs[ $row ] = $datetime;
393
-            // @todo if ANY of these updates fail then we want the appropriate global error message.
394
-        }
395
-        $event->save();
396
-        // now we need to REMOVE any datetimes that got deleted.
397
-        // Keep in mind that this process will only kick in for datetimes that don't have any DTT_sold on them.
398
-        // So its safe to permanently delete at this point.
399
-        $old_datetimes = explode(',', $data['datetime_IDs']);
400
-        $old_datetimes = $old_datetimes[0] === '' ? array() : $old_datetimes;
401
-        if (is_array($old_datetimes)) {
402
-            $datetimes_to_delete = array_diff($old_datetimes, $saved_dtt_ids);
403
-            foreach ($datetimes_to_delete as $id) {
404
-                $id = absint($id);
405
-                if (empty($id)) {
406
-                    continue;
407
-                }
408
-                $dtt_to_remove = EE_Registry::instance()->load_model('Datetime')->get_one_by_ID($id);
409
-                // remove tkt relationships.
410
-                $related_tickets = $dtt_to_remove->get_many_related('Ticket');
411
-                foreach ($related_tickets as $tkt) {
412
-                    $dtt_to_remove->_remove_relation_to($tkt, 'Ticket');
413
-                }
414
-                $event->_remove_relation_to($id, 'Datetime');
415
-                $dtt_to_remove->refresh_cache_of_related_objects();
416
-            }
417
-        }
418
-        return $saved_dtt_objs;
419
-    }
289
+	/**
290
+	 * update event_datetimes
291
+	 *
292
+	 * @param  EE_Event $event Event being updated
293
+	 * @param  array    $data  the request data from the form
294
+	 * @return EE_Datetime[]
295
+	 * @throws Exception
296
+	 * @throws ReflectionException
297
+	 * @throws InvalidInterfaceException
298
+	 * @throws InvalidDataTypeException
299
+	 * @throws InvalidArgumentException
300
+	 * @throws EE_Error
301
+	 */
302
+	protected function _update_datetimes($event, $data)
303
+	{
304
+		$timezone = isset($data['timezone_string']) ? $data['timezone_string'] : null;
305
+		$saved_dtt_ids = array();
306
+		$saved_dtt_objs = array();
307
+		if (empty($data['edit_event_datetimes']) || ! is_array($data['edit_event_datetimes'])) {
308
+			throw new InvalidArgumentException(
309
+				esc_html__(
310
+					'The "edit_event_datetimes" array is invalid therefore the event can not be updated.',
311
+					'event_espresso'
312
+				)
313
+			);
314
+		}
315
+		foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
316
+			// trim all values to ensure any excess whitespace is removed.
317
+			$datetime_data = array_map(
318
+				function ($datetime_data) {
319
+					return is_array($datetime_data) ? $datetime_data : trim($datetime_data);
320
+				},
321
+				$datetime_data
322
+			);
323
+			$datetime_data['DTT_EVT_end'] = isset($datetime_data['DTT_EVT_end'])
324
+											&& ! empty($datetime_data['DTT_EVT_end'])
325
+				? $datetime_data['DTT_EVT_end']
326
+				: $datetime_data['DTT_EVT_start'];
327
+			$datetime_values = array(
328
+				'DTT_ID'          => ! empty($datetime_data['DTT_ID'])
329
+					? $datetime_data['DTT_ID']
330
+					: null,
331
+				'DTT_name'        => ! empty($datetime_data['DTT_name'])
332
+					? $datetime_data['DTT_name']
333
+					: '',
334
+				'DTT_description' => ! empty($datetime_data['DTT_description'])
335
+					? $datetime_data['DTT_description']
336
+					: '',
337
+				'DTT_EVT_start'   => $datetime_data['DTT_EVT_start'],
338
+				'DTT_EVT_end'     => $datetime_data['DTT_EVT_end'],
339
+				'DTT_reg_limit'   => empty($datetime_data['DTT_reg_limit'])
340
+					? EE_INF
341
+					: $datetime_data['DTT_reg_limit'],
342
+				'DTT_order'       => ! isset($datetime_data['DTT_order'])
343
+					? $row
344
+					: $datetime_data['DTT_order'],
345
+			);
346
+			// if we have an id then let's get existing object first and then set the new values.
347
+			// Otherwise we instantiate a new object for save.
348
+			if (! empty($datetime_data['DTT_ID'])) {
349
+				$datetime = EE_Registry::instance()
350
+									   ->load_model('Datetime', array($timezone))
351
+									   ->get_one_by_ID($datetime_data['DTT_ID']);
352
+				// set date and time format according to what is set in this class.
353
+				$datetime->set_date_format($this->_date_format_strings['date']);
354
+				$datetime->set_time_format($this->_date_format_strings['time']);
355
+				foreach ($datetime_values as $field => $value) {
356
+					$datetime->set($field, $value);
357
+				}
358
+				// make sure the $dtt_id here is saved just in case
359
+				// after the add_relation_to() the autosave replaces it.
360
+				// We need to do this so we dont' TRASH the parent DTT.
361
+				// (save the ID for both key and value to avoid duplications)
362
+				$saved_dtt_ids[ $datetime->ID() ] = $datetime->ID();
363
+			} else {
364
+				$datetime = EE_Registry::instance()->load_class(
365
+					'Datetime',
366
+					array(
367
+						$datetime_values,
368
+						$timezone,
369
+						array($this->_date_format_strings['date'], $this->_date_format_strings['time']),
370
+					),
371
+					false,
372
+					false
373
+				);
374
+				foreach ($datetime_values as $field => $value) {
375
+					$datetime->set($field, $value);
376
+				}
377
+			}
378
+			$datetime->save();
379
+			$datetime = $event->_add_relation_to($datetime, 'Datetime');
380
+			// before going any further make sure our dates are setup correctly
381
+			// so that the end date is always equal or greater than the start date.
382
+			if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
383
+				$datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
384
+				$datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
385
+				$datetime->save();
386
+			}
387
+			// now we have to make sure we add the new DTT_ID to the $saved_dtt_ids array
388
+			// because it is possible there was a new one created for the autosave.
389
+			// (save the ID for both key and value to avoid duplications)
390
+			$DTT_ID = $datetime->ID();
391
+			$saved_dtt_ids[ $DTT_ID ] = $DTT_ID;
392
+			$saved_dtt_objs[ $row ] = $datetime;
393
+			// @todo if ANY of these updates fail then we want the appropriate global error message.
394
+		}
395
+		$event->save();
396
+		// now we need to REMOVE any datetimes that got deleted.
397
+		// Keep in mind that this process will only kick in for datetimes that don't have any DTT_sold on them.
398
+		// So its safe to permanently delete at this point.
399
+		$old_datetimes = explode(',', $data['datetime_IDs']);
400
+		$old_datetimes = $old_datetimes[0] === '' ? array() : $old_datetimes;
401
+		if (is_array($old_datetimes)) {
402
+			$datetimes_to_delete = array_diff($old_datetimes, $saved_dtt_ids);
403
+			foreach ($datetimes_to_delete as $id) {
404
+				$id = absint($id);
405
+				if (empty($id)) {
406
+					continue;
407
+				}
408
+				$dtt_to_remove = EE_Registry::instance()->load_model('Datetime')->get_one_by_ID($id);
409
+				// remove tkt relationships.
410
+				$related_tickets = $dtt_to_remove->get_many_related('Ticket');
411
+				foreach ($related_tickets as $tkt) {
412
+					$dtt_to_remove->_remove_relation_to($tkt, 'Ticket');
413
+				}
414
+				$event->_remove_relation_to($id, 'Datetime');
415
+				$dtt_to_remove->refresh_cache_of_related_objects();
416
+			}
417
+		}
418
+		return $saved_dtt_objs;
419
+	}
420 420
 
421 421
 
422
-    /**
423
-     * update tickets
424
-     *
425
-     * @param  EE_Event      $event           Event object being updated
426
-     * @param  EE_Datetime[] $saved_datetimes an array of datetime ids being updated
427
-     * @param  array         $data            incoming request data
428
-     * @return EE_Ticket[]
429
-     * @throws Exception
430
-     * @throws ReflectionException
431
-     * @throws InvalidInterfaceException
432
-     * @throws InvalidDataTypeException
433
-     * @throws InvalidArgumentException
434
-     * @throws EE_Error
435
-     */
436
-    protected function _update_tickets($event, $saved_datetimes, $data)
437
-    {
438
-        $new_tkt = null;
439
-        $new_default = null;
440
-        // stripslashes because WP filtered the $_POST ($data) array to add slashes
441
-        $data = stripslashes_deep($data);
442
-        $timezone = isset($data['timezone_string']) ? $data['timezone_string'] : null;
443
-        $saved_tickets = $datetimes_on_existing = array();
444
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
445
-        if (empty($data['edit_tickets']) || ! is_array($data['edit_tickets'])) {
446
-            throw new InvalidArgumentException(
447
-                esc_html__(
448
-                    'The "edit_tickets" array is invalid therefore the event can not be updated.',
449
-                    'event_espresso'
450
-                )
451
-            );
452
-        }
453
-        foreach ($data['edit_tickets'] as $row => $tkt) {
454
-            $update_prices = $create_new_TKT = false;
455
-            // figure out what datetimes were added to the ticket
456
-            // and what datetimes were removed from the ticket in the session.
457
-            $starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][ $row ]);
458
-            $tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][ $row ]);
459
-            $datetimes_added = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
460
-            $datetimes_removed = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
461
-            // trim inputs to ensure any excess whitespace is removed.
462
-            $tkt = array_map(
463
-                function ($ticket_data) {
464
-                    return is_array($ticket_data) ? $ticket_data : trim($ticket_data);
465
-                },
466
-                $tkt
467
-            );
468
-            // note we are doing conversions to floats here instead of allowing EE_Money_Field to handle
469
-            // because we're doing calculations prior to using the models.
470
-            // note incoming ['TKT_price'] value is already in standard notation (via js).
471
-            $ticket_price = isset($tkt['TKT_price'])
472
-                ? round((float) $tkt['TKT_price'], 3)
473
-                : 0;
474
-            // note incoming base price needs converted from localized value.
475
-            $base_price = isset($tkt['TKT_base_price'])
476
-                ? EEH_Money::convert_to_float_from_localized_money($tkt['TKT_base_price'])
477
-                : 0;
478
-            // if ticket price == 0 and $base_price != 0 then ticket price == base_price
479
-            $ticket_price = $ticket_price === 0 && $base_price !== 0
480
-                ? $base_price
481
-                : $ticket_price;
482
-            $base_price_id = isset($tkt['TKT_base_price_ID'])
483
-                ? $tkt['TKT_base_price_ID']
484
-                : 0;
485
-            $price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][ $row ])
486
-                ? $data['edit_prices'][ $row ]
487
-                : array();
488
-            $now = null;
489
-            if (empty($tkt['TKT_start_date'])) {
490
-                // lets' use now in the set timezone.
491
-                $now = new DateTime('now', new DateTimeZone($event->get_timezone()));
492
-                $tkt['TKT_start_date'] = $now->format($this->_date_time_format);
493
-            }
494
-            if (empty($tkt['TKT_end_date'])) {
495
-                /**
496
-                 * set the TKT_end_date to the first datetime attached to the ticket.
497
-                 */
498
-                $first_dtt = $saved_datetimes[ reset($tkt_dtt_rows) ];
499
-                $tkt['TKT_end_date'] = $first_dtt->start_date_and_time($this->_date_time_format);
500
-            }
501
-            $TKT_values = array(
502
-                'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
503
-                'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
504
-                'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
505
-                'TKT_description' => ! empty($tkt['TKT_description'])
506
-                                     && $tkt['TKT_description'] !== esc_html__(
507
-                                         'You can modify this description',
508
-                                         'event_espresso'
509
-                                     )
510
-                    ? $tkt['TKT_description']
511
-                    : '',
512
-                'TKT_start_date'  => $tkt['TKT_start_date'],
513
-                'TKT_end_date'    => $tkt['TKT_end_date'],
514
-                'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === ''
515
-                    ? EE_INF
516
-                    : $tkt['TKT_qty'],
517
-                'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === ''
518
-                    ? EE_INF
519
-                    : $tkt['TKT_uses'],
520
-                'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
521
-                'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
522
-                'TKT_row'         => $row,
523
-                'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : 0,
524
-                'TKT_taxable'     => ! empty($tkt['TKT_taxable']) ? 1 : 0,
525
-                'TKT_required'    => ! empty($tkt['TKT_required']) ? 1 : 0,
526
-                'TKT_price'       => $ticket_price,
527
-            );
528
-            // if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly,
529
-            // which means in turn that the prices will become new prices as well.
530
-            if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
531
-                $TKT_values['TKT_ID'] = 0;
532
-                $TKT_values['TKT_is_default'] = 0;
533
-                $update_prices = true;
534
-            }
535
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
536
-            // we actually do our saves ahead of doing any add_relations to
537
-            // because its entirely possible that this ticket wasn't removed or added to any datetime in the session
538
-            // but DID have it's items modified.
539
-            // keep in mind that if the TKT has been sold (and we have changed pricing information),
540
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
541
-            if (absint($TKT_values['TKT_ID'])) {
542
-                $ticket = EE_Registry::instance()
543
-                                     ->load_model('Ticket', array($timezone))
544
-                                     ->get_one_by_ID($tkt['TKT_ID']);
545
-                if ($ticket instanceof EE_Ticket) {
546
-                    $ticket = $this->_update_ticket_datetimes(
547
-                        $ticket,
548
-                        $saved_datetimes,
549
-                        $datetimes_added,
550
-                        $datetimes_removed
551
-                    );
552
-                    // are there any registrations using this ticket ?
553
-                    $tickets_sold = $ticket->count_related(
554
-                        'Registration',
555
-                        array(
556
-                            array(
557
-                                'STS_ID' => array('NOT IN', array(EEM_Registration::status_id_incomplete)),
558
-                            ),
559
-                        )
560
-                    );
561
-                    // set ticket formats
562
-                    $ticket->set_date_format($this->_date_format_strings['date']);
563
-                    $ticket->set_time_format($this->_date_format_strings['time']);
564
-                    // let's just check the total price for the existing ticket
565
-                    // and determine if it matches the new total price.
566
-                    // if they are different then we create a new ticket (if tickets sold)
567
-                    // if they aren't different then we go ahead and modify existing ticket.
568
-                    $create_new_TKT = $tickets_sold > 0 && $ticket_price !== $ticket->price() && ! $ticket->deleted();
569
-                    // set new values
570
-                    foreach ($TKT_values as $field => $value) {
571
-                        if ($field === 'TKT_qty') {
572
-                            $ticket->set_qty($value);
573
-                        } else {
574
-                            $ticket->set($field, $value);
575
-                        }
576
-                    }
577
-                    // if $create_new_TKT is false then we can safely update the existing ticket.
578
-                    // Otherwise we have to create a new ticket.
579
-                    if ($create_new_TKT) {
580
-                        $new_tkt = $this->_duplicate_ticket(
581
-                            $ticket,
582
-                            $price_rows,
583
-                            $ticket_price,
584
-                            $base_price,
585
-                            $base_price_id
586
-                        );
587
-                    }
588
-                }
589
-            } else {
590
-                // no TKT_id so a new TKT
591
-                $ticket = EE_Ticket::new_instance(
592
-                    $TKT_values,
593
-                    $timezone,
594
-                    array($this->_date_format_strings['date'], $this->_date_format_strings['time'])
595
-                );
596
-                if ($ticket instanceof EE_Ticket) {
597
-                    // make sure ticket has an ID of setting relations won't work
598
-                    $ticket->save();
599
-                    $ticket = $this->_update_ticket_datetimes(
600
-                        $ticket,
601
-                        $saved_datetimes,
602
-                        $datetimes_added,
603
-                        $datetimes_removed
604
-                    );
605
-                    $update_prices = true;
606
-                }
607
-            }
608
-            // make sure any current values have been saved.
609
-            // $ticket->save();
610
-            // before going any further make sure our dates are setup correctly
611
-            // so that the end date is always equal or greater than the start date.
612
-            if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
613
-                $ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
614
-                $ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
615
-            }
616
-            // let's make sure the base price is handled
617
-            $ticket = ! $create_new_TKT
618
-                ? $this->_add_prices_to_ticket(
619
-                    array(),
620
-                    $ticket,
621
-                    $update_prices,
622
-                    $base_price,
623
-                    $base_price_id
624
-                )
625
-                : $ticket;
626
-            // add/update price_modifiers
627
-            $ticket = ! $create_new_TKT
628
-                ? $this->_add_prices_to_ticket($price_rows, $ticket, $update_prices)
629
-                : $ticket;
630
-            // need to make sue that the TKT_price is accurate after saving the prices.
631
-            $ticket->ensure_TKT_Price_correct();
632
-            // handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
633
-            if (! defined('DOING_AUTOSAVE') && ! empty($tkt['TKT_is_default_selector'])) {
634
-                $update_prices = true;
635
-                $new_default = clone $ticket;
636
-                $new_default->set('TKT_ID', 0);
637
-                $new_default->set('TKT_is_default', 1);
638
-                $new_default->set('TKT_row', 1);
639
-                $new_default->set('TKT_price', $ticket_price);
640
-                // remove any dtt relations cause we DON'T want dtt relations attached
641
-                // (note this is just removing the cached relations in the object)
642
-                $new_default->_remove_relations('Datetime');
643
-                // @todo we need to add the current attached prices as new prices to the new default ticket.
644
-                $new_default = $this->_add_prices_to_ticket(
645
-                    $price_rows,
646
-                    $new_default,
647
-                    $update_prices
648
-                );
649
-                // don't forget the base price!
650
-                $new_default = $this->_add_prices_to_ticket(
651
-                    array(),
652
-                    $new_default,
653
-                    $update_prices,
654
-                    $base_price,
655
-                    $base_price_id
656
-                );
657
-                $new_default->save();
658
-                do_action(
659
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_default_ticket',
660
-                    $new_default,
661
-                    $row,
662
-                    $ticket,
663
-                    $data
664
-                );
665
-            }
666
-            // DO ALL dtt relationships for both current tickets and any archived tickets
667
-            // for the given dtt that are related to the current ticket.
668
-            // TODO... not sure exactly how we're going to do this considering we don't know
669
-            // what current ticket the archived tickets are related to
670
-            // (and TKT_parent is used for autosaves so that's not a field we can reliably use).
671
-            // let's assign any tickets that have been setup to the saved_tickets tracker
672
-            // save existing TKT
673
-            $ticket->save();
674
-            if ($create_new_TKT && $new_tkt instanceof EE_Ticket) {
675
-                // save new TKT
676
-                $new_tkt->save();
677
-                // add new ticket to array
678
-                $saved_tickets[ $new_tkt->ID() ] = $new_tkt;
679
-                do_action(
680
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket',
681
-                    $new_tkt,
682
-                    $row,
683
-                    $tkt,
684
-                    $data
685
-                );
686
-            } else {
687
-                // add tkt to saved tkts
688
-                $saved_tickets[ $ticket->ID() ] = $ticket;
689
-                do_action(
690
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket',
691
-                    $ticket,
692
-                    $row,
693
-                    $tkt,
694
-                    $data
695
-                );
696
-            }
697
-        }
698
-        // now we need to handle tickets actually "deleted permanently".
699
-        // There are cases where we'd want this to happen
700
-        // (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).
701
-        // Or a draft event was saved and in the process of editing a ticket is trashed.
702
-        // No sense in keeping all the related data in the db!
703
-        $old_tickets = isset($old_tickets[0]) && $old_tickets[0] === '' ? array() : $old_tickets;
704
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
705
-        foreach ($tickets_removed as $id) {
706
-            $id = absint($id);
707
-            // get the ticket for this id
708
-            $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
709
-            // if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
710
-            if ($tkt_to_remove->get('TKT_is_default')) {
711
-                continue;
712
-            }
713
-            // if this tkt has any registrations attached so then we just ARCHIVE
714
-            // because we don't actually permanently delete these tickets.
715
-            if ($tkt_to_remove->count_related('Registration') > 0) {
716
-                $tkt_to_remove->delete();
717
-                continue;
718
-            }
719
-            // need to get all the related datetimes on this ticket and remove from every single one of them
720
-            // (remember this process can ONLY kick off if there are NO tkts_sold)
721
-            $datetimes = $tkt_to_remove->get_many_related('Datetime');
722
-            foreach ($datetimes as $datetime) {
723
-                $tkt_to_remove->_remove_relation_to($datetime, 'Datetime');
724
-            }
725
-            // need to do the same for prices (except these prices can also be deleted because again,
726
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
727
-            $tkt_to_remove->delete_related_permanently('Price');
728
-            do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $tkt_to_remove);
729
-            // finally let's delete this ticket
730
-            // (which should not be blocked at this point b/c we've removed all our relationships)
731
-            $tkt_to_remove->delete_permanently();
732
-        }
733
-        return $saved_tickets;
734
-    }
422
+	/**
423
+	 * update tickets
424
+	 *
425
+	 * @param  EE_Event      $event           Event object being updated
426
+	 * @param  EE_Datetime[] $saved_datetimes an array of datetime ids being updated
427
+	 * @param  array         $data            incoming request data
428
+	 * @return EE_Ticket[]
429
+	 * @throws Exception
430
+	 * @throws ReflectionException
431
+	 * @throws InvalidInterfaceException
432
+	 * @throws InvalidDataTypeException
433
+	 * @throws InvalidArgumentException
434
+	 * @throws EE_Error
435
+	 */
436
+	protected function _update_tickets($event, $saved_datetimes, $data)
437
+	{
438
+		$new_tkt = null;
439
+		$new_default = null;
440
+		// stripslashes because WP filtered the $_POST ($data) array to add slashes
441
+		$data = stripslashes_deep($data);
442
+		$timezone = isset($data['timezone_string']) ? $data['timezone_string'] : null;
443
+		$saved_tickets = $datetimes_on_existing = array();
444
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
445
+		if (empty($data['edit_tickets']) || ! is_array($data['edit_tickets'])) {
446
+			throw new InvalidArgumentException(
447
+				esc_html__(
448
+					'The "edit_tickets" array is invalid therefore the event can not be updated.',
449
+					'event_espresso'
450
+				)
451
+			);
452
+		}
453
+		foreach ($data['edit_tickets'] as $row => $tkt) {
454
+			$update_prices = $create_new_TKT = false;
455
+			// figure out what datetimes were added to the ticket
456
+			// and what datetimes were removed from the ticket in the session.
457
+			$starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][ $row ]);
458
+			$tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][ $row ]);
459
+			$datetimes_added = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
460
+			$datetimes_removed = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
461
+			// trim inputs to ensure any excess whitespace is removed.
462
+			$tkt = array_map(
463
+				function ($ticket_data) {
464
+					return is_array($ticket_data) ? $ticket_data : trim($ticket_data);
465
+				},
466
+				$tkt
467
+			);
468
+			// note we are doing conversions to floats here instead of allowing EE_Money_Field to handle
469
+			// because we're doing calculations prior to using the models.
470
+			// note incoming ['TKT_price'] value is already in standard notation (via js).
471
+			$ticket_price = isset($tkt['TKT_price'])
472
+				? round((float) $tkt['TKT_price'], 3)
473
+				: 0;
474
+			// note incoming base price needs converted from localized value.
475
+			$base_price = isset($tkt['TKT_base_price'])
476
+				? EEH_Money::convert_to_float_from_localized_money($tkt['TKT_base_price'])
477
+				: 0;
478
+			// if ticket price == 0 and $base_price != 0 then ticket price == base_price
479
+			$ticket_price = $ticket_price === 0 && $base_price !== 0
480
+				? $base_price
481
+				: $ticket_price;
482
+			$base_price_id = isset($tkt['TKT_base_price_ID'])
483
+				? $tkt['TKT_base_price_ID']
484
+				: 0;
485
+			$price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][ $row ])
486
+				? $data['edit_prices'][ $row ]
487
+				: array();
488
+			$now = null;
489
+			if (empty($tkt['TKT_start_date'])) {
490
+				// lets' use now in the set timezone.
491
+				$now = new DateTime('now', new DateTimeZone($event->get_timezone()));
492
+				$tkt['TKT_start_date'] = $now->format($this->_date_time_format);
493
+			}
494
+			if (empty($tkt['TKT_end_date'])) {
495
+				/**
496
+				 * set the TKT_end_date to the first datetime attached to the ticket.
497
+				 */
498
+				$first_dtt = $saved_datetimes[ reset($tkt_dtt_rows) ];
499
+				$tkt['TKT_end_date'] = $first_dtt->start_date_and_time($this->_date_time_format);
500
+			}
501
+			$TKT_values = array(
502
+				'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
503
+				'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
504
+				'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
505
+				'TKT_description' => ! empty($tkt['TKT_description'])
506
+									 && $tkt['TKT_description'] !== esc_html__(
507
+										 'You can modify this description',
508
+										 'event_espresso'
509
+									 )
510
+					? $tkt['TKT_description']
511
+					: '',
512
+				'TKT_start_date'  => $tkt['TKT_start_date'],
513
+				'TKT_end_date'    => $tkt['TKT_end_date'],
514
+				'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === ''
515
+					? EE_INF
516
+					: $tkt['TKT_qty'],
517
+				'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === ''
518
+					? EE_INF
519
+					: $tkt['TKT_uses'],
520
+				'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
521
+				'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
522
+				'TKT_row'         => $row,
523
+				'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : 0,
524
+				'TKT_taxable'     => ! empty($tkt['TKT_taxable']) ? 1 : 0,
525
+				'TKT_required'    => ! empty($tkt['TKT_required']) ? 1 : 0,
526
+				'TKT_price'       => $ticket_price,
527
+			);
528
+			// if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly,
529
+			// which means in turn that the prices will become new prices as well.
530
+			if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
531
+				$TKT_values['TKT_ID'] = 0;
532
+				$TKT_values['TKT_is_default'] = 0;
533
+				$update_prices = true;
534
+			}
535
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
536
+			// we actually do our saves ahead of doing any add_relations to
537
+			// because its entirely possible that this ticket wasn't removed or added to any datetime in the session
538
+			// but DID have it's items modified.
539
+			// keep in mind that if the TKT has been sold (and we have changed pricing information),
540
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
541
+			if (absint($TKT_values['TKT_ID'])) {
542
+				$ticket = EE_Registry::instance()
543
+									 ->load_model('Ticket', array($timezone))
544
+									 ->get_one_by_ID($tkt['TKT_ID']);
545
+				if ($ticket instanceof EE_Ticket) {
546
+					$ticket = $this->_update_ticket_datetimes(
547
+						$ticket,
548
+						$saved_datetimes,
549
+						$datetimes_added,
550
+						$datetimes_removed
551
+					);
552
+					// are there any registrations using this ticket ?
553
+					$tickets_sold = $ticket->count_related(
554
+						'Registration',
555
+						array(
556
+							array(
557
+								'STS_ID' => array('NOT IN', array(EEM_Registration::status_id_incomplete)),
558
+							),
559
+						)
560
+					);
561
+					// set ticket formats
562
+					$ticket->set_date_format($this->_date_format_strings['date']);
563
+					$ticket->set_time_format($this->_date_format_strings['time']);
564
+					// let's just check the total price for the existing ticket
565
+					// and determine if it matches the new total price.
566
+					// if they are different then we create a new ticket (if tickets sold)
567
+					// if they aren't different then we go ahead and modify existing ticket.
568
+					$create_new_TKT = $tickets_sold > 0 && $ticket_price !== $ticket->price() && ! $ticket->deleted();
569
+					// set new values
570
+					foreach ($TKT_values as $field => $value) {
571
+						if ($field === 'TKT_qty') {
572
+							$ticket->set_qty($value);
573
+						} else {
574
+							$ticket->set($field, $value);
575
+						}
576
+					}
577
+					// if $create_new_TKT is false then we can safely update the existing ticket.
578
+					// Otherwise we have to create a new ticket.
579
+					if ($create_new_TKT) {
580
+						$new_tkt = $this->_duplicate_ticket(
581
+							$ticket,
582
+							$price_rows,
583
+							$ticket_price,
584
+							$base_price,
585
+							$base_price_id
586
+						);
587
+					}
588
+				}
589
+			} else {
590
+				// no TKT_id so a new TKT
591
+				$ticket = EE_Ticket::new_instance(
592
+					$TKT_values,
593
+					$timezone,
594
+					array($this->_date_format_strings['date'], $this->_date_format_strings['time'])
595
+				);
596
+				if ($ticket instanceof EE_Ticket) {
597
+					// make sure ticket has an ID of setting relations won't work
598
+					$ticket->save();
599
+					$ticket = $this->_update_ticket_datetimes(
600
+						$ticket,
601
+						$saved_datetimes,
602
+						$datetimes_added,
603
+						$datetimes_removed
604
+					);
605
+					$update_prices = true;
606
+				}
607
+			}
608
+			// make sure any current values have been saved.
609
+			// $ticket->save();
610
+			// before going any further make sure our dates are setup correctly
611
+			// so that the end date is always equal or greater than the start date.
612
+			if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
613
+				$ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
614
+				$ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
615
+			}
616
+			// let's make sure the base price is handled
617
+			$ticket = ! $create_new_TKT
618
+				? $this->_add_prices_to_ticket(
619
+					array(),
620
+					$ticket,
621
+					$update_prices,
622
+					$base_price,
623
+					$base_price_id
624
+				)
625
+				: $ticket;
626
+			// add/update price_modifiers
627
+			$ticket = ! $create_new_TKT
628
+				? $this->_add_prices_to_ticket($price_rows, $ticket, $update_prices)
629
+				: $ticket;
630
+			// need to make sue that the TKT_price is accurate after saving the prices.
631
+			$ticket->ensure_TKT_Price_correct();
632
+			// handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
633
+			if (! defined('DOING_AUTOSAVE') && ! empty($tkt['TKT_is_default_selector'])) {
634
+				$update_prices = true;
635
+				$new_default = clone $ticket;
636
+				$new_default->set('TKT_ID', 0);
637
+				$new_default->set('TKT_is_default', 1);
638
+				$new_default->set('TKT_row', 1);
639
+				$new_default->set('TKT_price', $ticket_price);
640
+				// remove any dtt relations cause we DON'T want dtt relations attached
641
+				// (note this is just removing the cached relations in the object)
642
+				$new_default->_remove_relations('Datetime');
643
+				// @todo we need to add the current attached prices as new prices to the new default ticket.
644
+				$new_default = $this->_add_prices_to_ticket(
645
+					$price_rows,
646
+					$new_default,
647
+					$update_prices
648
+				);
649
+				// don't forget the base price!
650
+				$new_default = $this->_add_prices_to_ticket(
651
+					array(),
652
+					$new_default,
653
+					$update_prices,
654
+					$base_price,
655
+					$base_price_id
656
+				);
657
+				$new_default->save();
658
+				do_action(
659
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_default_ticket',
660
+					$new_default,
661
+					$row,
662
+					$ticket,
663
+					$data
664
+				);
665
+			}
666
+			// DO ALL dtt relationships for both current tickets and any archived tickets
667
+			// for the given dtt that are related to the current ticket.
668
+			// TODO... not sure exactly how we're going to do this considering we don't know
669
+			// what current ticket the archived tickets are related to
670
+			// (and TKT_parent is used for autosaves so that's not a field we can reliably use).
671
+			// let's assign any tickets that have been setup to the saved_tickets tracker
672
+			// save existing TKT
673
+			$ticket->save();
674
+			if ($create_new_TKT && $new_tkt instanceof EE_Ticket) {
675
+				// save new TKT
676
+				$new_tkt->save();
677
+				// add new ticket to array
678
+				$saved_tickets[ $new_tkt->ID() ] = $new_tkt;
679
+				do_action(
680
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket',
681
+					$new_tkt,
682
+					$row,
683
+					$tkt,
684
+					$data
685
+				);
686
+			} else {
687
+				// add tkt to saved tkts
688
+				$saved_tickets[ $ticket->ID() ] = $ticket;
689
+				do_action(
690
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket',
691
+					$ticket,
692
+					$row,
693
+					$tkt,
694
+					$data
695
+				);
696
+			}
697
+		}
698
+		// now we need to handle tickets actually "deleted permanently".
699
+		// There are cases where we'd want this to happen
700
+		// (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).
701
+		// Or a draft event was saved and in the process of editing a ticket is trashed.
702
+		// No sense in keeping all the related data in the db!
703
+		$old_tickets = isset($old_tickets[0]) && $old_tickets[0] === '' ? array() : $old_tickets;
704
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
705
+		foreach ($tickets_removed as $id) {
706
+			$id = absint($id);
707
+			// get the ticket for this id
708
+			$tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
709
+			// if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
710
+			if ($tkt_to_remove->get('TKT_is_default')) {
711
+				continue;
712
+			}
713
+			// if this tkt has any registrations attached so then we just ARCHIVE
714
+			// because we don't actually permanently delete these tickets.
715
+			if ($tkt_to_remove->count_related('Registration') > 0) {
716
+				$tkt_to_remove->delete();
717
+				continue;
718
+			}
719
+			// need to get all the related datetimes on this ticket and remove from every single one of them
720
+			// (remember this process can ONLY kick off if there are NO tkts_sold)
721
+			$datetimes = $tkt_to_remove->get_many_related('Datetime');
722
+			foreach ($datetimes as $datetime) {
723
+				$tkt_to_remove->_remove_relation_to($datetime, 'Datetime');
724
+			}
725
+			// need to do the same for prices (except these prices can also be deleted because again,
726
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
727
+			$tkt_to_remove->delete_related_permanently('Price');
728
+			do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $tkt_to_remove);
729
+			// finally let's delete this ticket
730
+			// (which should not be blocked at this point b/c we've removed all our relationships)
731
+			$tkt_to_remove->delete_permanently();
732
+		}
733
+		return $saved_tickets;
734
+	}
735 735
 
736 736
 
737
-    /**
738
-     * @access  protected
739
-     * @param EE_Ticket      $ticket
740
-     * @param \EE_Datetime[] $saved_datetimes
741
-     * @param \EE_Datetime[] $added_datetimes
742
-     * @param \EE_Datetime[] $removed_datetimes
743
-     * @return EE_Ticket
744
-     * @throws EE_Error
745
-     */
746
-    protected function _update_ticket_datetimes(
747
-        EE_Ticket $ticket,
748
-        $saved_datetimes = array(),
749
-        $added_datetimes = array(),
750
-        $removed_datetimes = array()
751
-    ) {
752
-        // to start we have to add the ticket to all the datetimes its supposed to be with,
753
-        // and removing the ticket from datetimes it got removed from.
754
-        // first let's add datetimes
755
-        if (! empty($added_datetimes) && is_array($added_datetimes)) {
756
-            foreach ($added_datetimes as $row_id) {
757
-                $row_id = (int) $row_id;
758
-                if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
759
-                    $ticket->_add_relation_to($saved_datetimes[ $row_id ], 'Datetime');
760
-                    // Is this an existing ticket (has an ID) and does it have any sold?
761
-                    // If so, then we need to add that to the DTT sold because this DTT is getting added.
762
-                    if ($ticket->ID() && $ticket->sold() > 0) {
763
-                        $saved_datetimes[ $row_id ]->increaseSold($ticket->sold(), false);
764
-                    }
765
-                }
766
-            }
767
-        }
768
-        // then remove datetimes
769
-        if (! empty($removed_datetimes) && is_array($removed_datetimes)) {
770
-            foreach ($removed_datetimes as $row_id) {
771
-                $row_id = (int) $row_id;
772
-                // its entirely possible that a datetime got deleted (instead of just removed from relationship.
773
-                // So make sure we skip over this if the dtt isn't in the $saved_datetimes array)
774
-                if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
775
-                    $ticket->_remove_relation_to($saved_datetimes[ $row_id ], 'Datetime');
776
-                    // Is this an existing ticket (has an ID) and does it have any sold?
777
-                    // If so, then we need to remove it's sold from the DTT_sold.
778
-                    if ($ticket->ID() && $ticket->sold() > 0) {
779
-                        $saved_datetimes[ $row_id ]->decreaseSold($ticket->sold());
780
-                    }
781
-                }
782
-            }
783
-        }
784
-        // cap ticket qty by datetime reg limits
785
-        $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
786
-        return $ticket;
787
-    }
737
+	/**
738
+	 * @access  protected
739
+	 * @param EE_Ticket      $ticket
740
+	 * @param \EE_Datetime[] $saved_datetimes
741
+	 * @param \EE_Datetime[] $added_datetimes
742
+	 * @param \EE_Datetime[] $removed_datetimes
743
+	 * @return EE_Ticket
744
+	 * @throws EE_Error
745
+	 */
746
+	protected function _update_ticket_datetimes(
747
+		EE_Ticket $ticket,
748
+		$saved_datetimes = array(),
749
+		$added_datetimes = array(),
750
+		$removed_datetimes = array()
751
+	) {
752
+		// to start we have to add the ticket to all the datetimes its supposed to be with,
753
+		// and removing the ticket from datetimes it got removed from.
754
+		// first let's add datetimes
755
+		if (! empty($added_datetimes) && is_array($added_datetimes)) {
756
+			foreach ($added_datetimes as $row_id) {
757
+				$row_id = (int) $row_id;
758
+				if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
759
+					$ticket->_add_relation_to($saved_datetimes[ $row_id ], 'Datetime');
760
+					// Is this an existing ticket (has an ID) and does it have any sold?
761
+					// If so, then we need to add that to the DTT sold because this DTT is getting added.
762
+					if ($ticket->ID() && $ticket->sold() > 0) {
763
+						$saved_datetimes[ $row_id ]->increaseSold($ticket->sold(), false);
764
+					}
765
+				}
766
+			}
767
+		}
768
+		// then remove datetimes
769
+		if (! empty($removed_datetimes) && is_array($removed_datetimes)) {
770
+			foreach ($removed_datetimes as $row_id) {
771
+				$row_id = (int) $row_id;
772
+				// its entirely possible that a datetime got deleted (instead of just removed from relationship.
773
+				// So make sure we skip over this if the dtt isn't in the $saved_datetimes array)
774
+				if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
775
+					$ticket->_remove_relation_to($saved_datetimes[ $row_id ], 'Datetime');
776
+					// Is this an existing ticket (has an ID) and does it have any sold?
777
+					// If so, then we need to remove it's sold from the DTT_sold.
778
+					if ($ticket->ID() && $ticket->sold() > 0) {
779
+						$saved_datetimes[ $row_id ]->decreaseSold($ticket->sold());
780
+					}
781
+				}
782
+			}
783
+		}
784
+		// cap ticket qty by datetime reg limits
785
+		$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
786
+		return $ticket;
787
+	}
788 788
 
789 789
 
790
-    /**
791
-     * @access  protected
792
-     * @param EE_Ticket $ticket
793
-     * @param array     $price_rows
794
-     * @param int       $ticket_price
795
-     * @param int       $base_price
796
-     * @param int       $base_price_id
797
-     * @return EE_Ticket
798
-     * @throws ReflectionException
799
-     * @throws InvalidArgumentException
800
-     * @throws InvalidInterfaceException
801
-     * @throws InvalidDataTypeException
802
-     * @throws EE_Error
803
-     */
804
-    protected function _duplicate_ticket(
805
-        EE_Ticket $ticket,
806
-        $price_rows = array(),
807
-        $ticket_price = 0,
808
-        $base_price = 0,
809
-        $base_price_id = 0
810
-    ) {
811
-        // create new ticket that's a copy of the existing
812
-        // except a new id of course (and not archived)
813
-        // AND has the new TKT_price associated with it.
814
-        $new_ticket = clone $ticket;
815
-        $new_ticket->set('TKT_ID', 0);
816
-        $new_ticket->set_deleted(0);
817
-        $new_ticket->set_price($ticket_price);
818
-        $new_ticket->set_sold(0);
819
-        // let's get a new ID for this ticket
820
-        $new_ticket->save();
821
-        // we also need to make sure this new ticket gets the same datetime attachments as the archived ticket
822
-        $datetimes_on_existing = $ticket->datetimes();
823
-        $new_ticket = $this->_update_ticket_datetimes(
824
-            $new_ticket,
825
-            $datetimes_on_existing,
826
-            array_keys($datetimes_on_existing)
827
-        );
828
-        // $ticket will get archived later b/c we are NOT adding it to the saved_tickets array.
829
-        // if existing $ticket has sold amount, then we need to adjust the qty for the new TKT to = the remaining
830
-        // available.
831
-        if ($ticket->sold() > 0) {
832
-            $new_qty = $ticket->qty() - $ticket->sold();
833
-            $new_ticket->set_qty($new_qty);
834
-        }
835
-        // now we update the prices just for this ticket
836
-        $new_ticket = $this->_add_prices_to_ticket($price_rows, $new_ticket, true);
837
-        // and we update the base price
838
-        $new_ticket = $this->_add_prices_to_ticket(
839
-            array(),
840
-            $new_ticket,
841
-            true,
842
-            $base_price,
843
-            $base_price_id
844
-        );
845
-        return $new_ticket;
846
-    }
790
+	/**
791
+	 * @access  protected
792
+	 * @param EE_Ticket $ticket
793
+	 * @param array     $price_rows
794
+	 * @param int       $ticket_price
795
+	 * @param int       $base_price
796
+	 * @param int       $base_price_id
797
+	 * @return EE_Ticket
798
+	 * @throws ReflectionException
799
+	 * @throws InvalidArgumentException
800
+	 * @throws InvalidInterfaceException
801
+	 * @throws InvalidDataTypeException
802
+	 * @throws EE_Error
803
+	 */
804
+	protected function _duplicate_ticket(
805
+		EE_Ticket $ticket,
806
+		$price_rows = array(),
807
+		$ticket_price = 0,
808
+		$base_price = 0,
809
+		$base_price_id = 0
810
+	) {
811
+		// create new ticket that's a copy of the existing
812
+		// except a new id of course (and not archived)
813
+		// AND has the new TKT_price associated with it.
814
+		$new_ticket = clone $ticket;
815
+		$new_ticket->set('TKT_ID', 0);
816
+		$new_ticket->set_deleted(0);
817
+		$new_ticket->set_price($ticket_price);
818
+		$new_ticket->set_sold(0);
819
+		// let's get a new ID for this ticket
820
+		$new_ticket->save();
821
+		// we also need to make sure this new ticket gets the same datetime attachments as the archived ticket
822
+		$datetimes_on_existing = $ticket->datetimes();
823
+		$new_ticket = $this->_update_ticket_datetimes(
824
+			$new_ticket,
825
+			$datetimes_on_existing,
826
+			array_keys($datetimes_on_existing)
827
+		);
828
+		// $ticket will get archived later b/c we are NOT adding it to the saved_tickets array.
829
+		// if existing $ticket has sold amount, then we need to adjust the qty for the new TKT to = the remaining
830
+		// available.
831
+		if ($ticket->sold() > 0) {
832
+			$new_qty = $ticket->qty() - $ticket->sold();
833
+			$new_ticket->set_qty($new_qty);
834
+		}
835
+		// now we update the prices just for this ticket
836
+		$new_ticket = $this->_add_prices_to_ticket($price_rows, $new_ticket, true);
837
+		// and we update the base price
838
+		$new_ticket = $this->_add_prices_to_ticket(
839
+			array(),
840
+			$new_ticket,
841
+			true,
842
+			$base_price,
843
+			$base_price_id
844
+		);
845
+		return $new_ticket;
846
+	}
847 847
 
848 848
 
849
-    /**
850
-     * This attaches a list of given prices to a ticket.
851
-     * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
852
-     * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
853
-     * price info and prices are automatically "archived" via the ticket.
854
-     *
855
-     * @access  private
856
-     * @param array     $prices        Array of prices from the form.
857
-     * @param EE_Ticket $ticket        EE_Ticket object that prices are being attached to.
858
-     * @param bool      $new_prices    Whether attach existing incoming prices or create new ones.
859
-     * @param int|bool  $base_price    if FALSE then NOT doing a base price add.
860
-     * @param int|bool  $base_price_id if present then this is the base_price_id being updated.
861
-     * @return EE_Ticket
862
-     * @throws ReflectionException
863
-     * @throws InvalidArgumentException
864
-     * @throws InvalidInterfaceException
865
-     * @throws InvalidDataTypeException
866
-     * @throws EE_Error
867
-     */
868
-    protected function _add_prices_to_ticket(
869
-        $prices = array(),
870
-        EE_Ticket $ticket,
871
-        $new_prices = false,
872
-        $base_price = false,
873
-        $base_price_id = false
874
-    ) {
875
-        // let's just get any current prices that may exist on the given ticket
876
-        // so we can remove any prices that got trashed in this session.
877
-        $current_prices_on_ticket = $base_price !== false
878
-            ? $ticket->base_price(true)
879
-            : $ticket->price_modifiers();
880
-        $updated_prices = array();
881
-        // if $base_price ! FALSE then updating a base price.
882
-        if ($base_price !== false) {
883
-            $prices[1] = array(
884
-                'PRC_ID'     => $new_prices || $base_price_id === 1 ? null : $base_price_id,
885
-                'PRT_ID'     => 1,
886
-                'PRC_amount' => $base_price,
887
-                'PRC_name'   => $ticket->get('TKT_name'),
888
-                'PRC_desc'   => $ticket->get('TKT_description'),
889
-            );
890
-        }
891
-        // possibly need to save tkt
892
-        if (! $ticket->ID()) {
893
-            $ticket->save();
894
-        }
895
-        foreach ($prices as $row => $prc) {
896
-            $prt_id = ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null;
897
-            if (empty($prt_id)) {
898
-                continue;
899
-            } //prices MUST have a price type id.
900
-            $PRC_values = array(
901
-                'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
902
-                'PRT_ID'         => $prt_id,
903
-                'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
904
-                'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
905
-                'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
906
-                'PRC_is_default' => false,
907
-                // make sure we set PRC_is_default to false for all ticket saves from event_editor
908
-                'PRC_order'      => $row,
909
-            );
910
-            if ($new_prices || empty($PRC_values['PRC_ID'])) {
911
-                $PRC_values['PRC_ID'] = 0;
912
-                $price = EE_Registry::instance()->load_class(
913
-                    'Price',
914
-                    array($PRC_values),
915
-                    false,
916
-                    false
917
-                );
918
-            } else {
919
-                $price = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
920
-                // update this price with new values
921
-                foreach ($PRC_values as $field => $value) {
922
-                    $price->set($field, $value);
923
-                }
924
-            }
925
-            $price->save();
926
-            $updated_prices[ $price->ID() ] = $price;
927
-            $ticket->_add_relation_to($price, 'Price');
928
-        }
929
-        // now let's remove any prices that got removed from the ticket
930
-        if (! empty($current_prices_on_ticket)) {
931
-            $current = array_keys($current_prices_on_ticket);
932
-            $updated = array_keys($updated_prices);
933
-            $prices_to_remove = array_diff($current, $updated);
934
-            if (! empty($prices_to_remove)) {
935
-                foreach ($prices_to_remove as $prc_id) {
936
-                    $p = $current_prices_on_ticket[ $prc_id ];
937
-                    $ticket->_remove_relation_to($p, 'Price');
938
-                    // delete permanently the price
939
-                    $p->delete_permanently();
940
-                }
941
-            }
942
-        }
943
-        return $ticket;
944
-    }
849
+	/**
850
+	 * This attaches a list of given prices to a ticket.
851
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
852
+	 * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
853
+	 * price info and prices are automatically "archived" via the ticket.
854
+	 *
855
+	 * @access  private
856
+	 * @param array     $prices        Array of prices from the form.
857
+	 * @param EE_Ticket $ticket        EE_Ticket object that prices are being attached to.
858
+	 * @param bool      $new_prices    Whether attach existing incoming prices or create new ones.
859
+	 * @param int|bool  $base_price    if FALSE then NOT doing a base price add.
860
+	 * @param int|bool  $base_price_id if present then this is the base_price_id being updated.
861
+	 * @return EE_Ticket
862
+	 * @throws ReflectionException
863
+	 * @throws InvalidArgumentException
864
+	 * @throws InvalidInterfaceException
865
+	 * @throws InvalidDataTypeException
866
+	 * @throws EE_Error
867
+	 */
868
+	protected function _add_prices_to_ticket(
869
+		$prices = array(),
870
+		EE_Ticket $ticket,
871
+		$new_prices = false,
872
+		$base_price = false,
873
+		$base_price_id = false
874
+	) {
875
+		// let's just get any current prices that may exist on the given ticket
876
+		// so we can remove any prices that got trashed in this session.
877
+		$current_prices_on_ticket = $base_price !== false
878
+			? $ticket->base_price(true)
879
+			: $ticket->price_modifiers();
880
+		$updated_prices = array();
881
+		// if $base_price ! FALSE then updating a base price.
882
+		if ($base_price !== false) {
883
+			$prices[1] = array(
884
+				'PRC_ID'     => $new_prices || $base_price_id === 1 ? null : $base_price_id,
885
+				'PRT_ID'     => 1,
886
+				'PRC_amount' => $base_price,
887
+				'PRC_name'   => $ticket->get('TKT_name'),
888
+				'PRC_desc'   => $ticket->get('TKT_description'),
889
+			);
890
+		}
891
+		// possibly need to save tkt
892
+		if (! $ticket->ID()) {
893
+			$ticket->save();
894
+		}
895
+		foreach ($prices as $row => $prc) {
896
+			$prt_id = ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null;
897
+			if (empty($prt_id)) {
898
+				continue;
899
+			} //prices MUST have a price type id.
900
+			$PRC_values = array(
901
+				'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
902
+				'PRT_ID'         => $prt_id,
903
+				'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
904
+				'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
905
+				'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
906
+				'PRC_is_default' => false,
907
+				// make sure we set PRC_is_default to false for all ticket saves from event_editor
908
+				'PRC_order'      => $row,
909
+			);
910
+			if ($new_prices || empty($PRC_values['PRC_ID'])) {
911
+				$PRC_values['PRC_ID'] = 0;
912
+				$price = EE_Registry::instance()->load_class(
913
+					'Price',
914
+					array($PRC_values),
915
+					false,
916
+					false
917
+				);
918
+			} else {
919
+				$price = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
920
+				// update this price with new values
921
+				foreach ($PRC_values as $field => $value) {
922
+					$price->set($field, $value);
923
+				}
924
+			}
925
+			$price->save();
926
+			$updated_prices[ $price->ID() ] = $price;
927
+			$ticket->_add_relation_to($price, 'Price');
928
+		}
929
+		// now let's remove any prices that got removed from the ticket
930
+		if (! empty($current_prices_on_ticket)) {
931
+			$current = array_keys($current_prices_on_ticket);
932
+			$updated = array_keys($updated_prices);
933
+			$prices_to_remove = array_diff($current, $updated);
934
+			if (! empty($prices_to_remove)) {
935
+				foreach ($prices_to_remove as $prc_id) {
936
+					$p = $current_prices_on_ticket[ $prc_id ];
937
+					$ticket->_remove_relation_to($p, 'Price');
938
+					// delete permanently the price
939
+					$p->delete_permanently();
940
+				}
941
+			}
942
+		}
943
+		return $ticket;
944
+	}
945 945
 
946 946
 
947
-    /**
948
-     * @param Events_Admin_Page $event_admin_obj
949
-     * @return Events_Admin_Page
950
-     */
951
-    public function autosave_handling(Events_Admin_Page $event_admin_obj)
952
-    {
953
-        return $event_admin_obj;
954
-        // doing nothing for the moment.
955
-        // todo when I get to this remember that I need to set the template args on the $event_admin_obj
956
-        // (use the set_template_args() method)
957
-        /**
958
-         * need to remember to handle TICKET DEFAULT saves correctly:  I've got two input fields in the dom:
959
-         * 1. TKT_is_default_selector (visible)
960
-         * 2. TKT_is_default (hidden)
961
-         * I think we'll use the TKT_is_default for recording whether the ticket displayed IS a default ticket
962
-         * (on new event creations). Whereas the TKT_is_default_selector is for the user to indicate they want
963
-         * this ticket to be saved as a default.
964
-         * The tricky part is, on an initial display on create or edit (or after manually updating),
965
-         * the TKT_is_default_selector will always be unselected and the TKT_is_default will only be true
966
-         * if this is a create.  However, after an autosave, users will want some sort of indicator that
967
-         * the TKT HAS been saved as a default..
968
-         * in other words we don't want to remove the check on TKT_is_default_selector. So here's what I'm thinking.
969
-         * On Autosave:
970
-         * 1. If TKT_is_default is true: we create a new TKT, send back the new id and add id to related elements,
971
-         * then set the TKT_is_default to false.
972
-         * 2. If TKT_is_default_selector is true: we create/edit existing ticket (following conditions above as well).
973
-         *  We do NOT create a new default ticket.  The checkbox stays selected after autosave.
974
-         * 3. only on MANUAL update do we check for the selection and if selected create the new default ticket.
975
-         */
976
-    }
947
+	/**
948
+	 * @param Events_Admin_Page $event_admin_obj
949
+	 * @return Events_Admin_Page
950
+	 */
951
+	public function autosave_handling(Events_Admin_Page $event_admin_obj)
952
+	{
953
+		return $event_admin_obj;
954
+		// doing nothing for the moment.
955
+		// todo when I get to this remember that I need to set the template args on the $event_admin_obj
956
+		// (use the set_template_args() method)
957
+		/**
958
+		 * need to remember to handle TICKET DEFAULT saves correctly:  I've got two input fields in the dom:
959
+		 * 1. TKT_is_default_selector (visible)
960
+		 * 2. TKT_is_default (hidden)
961
+		 * I think we'll use the TKT_is_default for recording whether the ticket displayed IS a default ticket
962
+		 * (on new event creations). Whereas the TKT_is_default_selector is for the user to indicate they want
963
+		 * this ticket to be saved as a default.
964
+		 * The tricky part is, on an initial display on create or edit (or after manually updating),
965
+		 * the TKT_is_default_selector will always be unselected and the TKT_is_default will only be true
966
+		 * if this is a create.  However, after an autosave, users will want some sort of indicator that
967
+		 * the TKT HAS been saved as a default..
968
+		 * in other words we don't want to remove the check on TKT_is_default_selector. So here's what I'm thinking.
969
+		 * On Autosave:
970
+		 * 1. If TKT_is_default is true: we create a new TKT, send back the new id and add id to related elements,
971
+		 * then set the TKT_is_default to false.
972
+		 * 2. If TKT_is_default_selector is true: we create/edit existing ticket (following conditions above as well).
973
+		 *  We do NOT create a new default ticket.  The checkbox stays selected after autosave.
974
+		 * 3. only on MANUAL update do we check for the selection and if selected create the new default ticket.
975
+		 */
976
+	}
977 977
 
978 978
 
979
-    /**
980
-     * @throws ReflectionException
981
-     * @throws InvalidArgumentException
982
-     * @throws InvalidInterfaceException
983
-     * @throws InvalidDataTypeException
984
-     * @throws DomainException
985
-     * @throws EE_Error
986
-     */
987
-    public function pricing_metabox()
988
-    {
989
-        $existing_datetime_ids = $existing_ticket_ids = $datetime_tickets = $ticket_datetimes = array();
990
-        $event = $this->_adminpage_obj->get_cpt_model_obj();
991
-        // set is_creating_event property.
992
-        $EVT_ID = $event->ID();
993
-        $this->_is_creating_event = empty($this->_req_data['post']);
994
-        // default main template args
995
-        $main_template_args = array(
996
-            'event_datetime_help_link' => EEH_Template::get_help_tab_link(
997
-                'event_editor_event_datetimes_help_tab',
998
-                $this->_adminpage_obj->page_slug,
999
-                $this->_adminpage_obj->get_req_action(),
1000
-                false,
1001
-                false
1002
-            ),
1003
-            // todo need to add a filter to the template for the help text
1004
-            // in the Events_Admin_Page core file so we can add further help
1005
-            'existing_datetime_ids'    => '',
1006
-            'total_dtt_rows'           => 1,
1007
-            'add_new_dtt_help_link'    => EEH_Template::get_help_tab_link(
1008
-                'add_new_dtt_info',
1009
-                $this->_adminpage_obj->page_slug,
1010
-                $this->_adminpage_obj->get_req_action(),
1011
-                false,
1012
-                false
1013
-            ),
1014
-            // todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1015
-            'datetime_rows'            => '',
1016
-            'show_tickets_container'   => '',
1017
-            // $this->_adminpage_obj->get_cpt_model_obj()->ID() > 1 ? ' style="display:none;"' : '',
1018
-            'ticket_rows'              => '',
1019
-            'existing_ticket_ids'      => '',
1020
-            'total_ticket_rows'        => 1,
1021
-            'ticket_js_structure'      => '',
1022
-            'ee_collapsible_status'    => ' ee-collapsible-open'
1023
-            // $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' ee-collapsible-closed' : ' ee-collapsible-open'
1024
-        );
1025
-        $timezone = $event instanceof EE_Event ? $event->timezone_string() : null;
1026
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1027
-        /**
1028
-         * 1. Start with retrieving Datetimes
1029
-         * 2. For each datetime get related tickets
1030
-         * 3. For each ticket get related prices
1031
-         */
1032
-        /** @var EEM_Datetime $datetime_model */
1033
-        $datetime_model = EE_Registry::instance()->load_model('Datetime', array($timezone));
1034
-        $datetimes = $datetime_model->get_all_event_dates($EVT_ID);
1035
-        $main_template_args['total_dtt_rows'] = count($datetimes);
1036
-        /**
1037
-         * @see https://events.codebasehq.com/projects/event-espresso/tickets/9486
1038
-         * for why we are counting $datetime_row and then setting that on the Datetime object
1039
-         */
1040
-        $datetime_row = 1;
1041
-        foreach ($datetimes as $datetime) {
1042
-            $DTT_ID = $datetime->get('DTT_ID');
1043
-            $datetime->set('DTT_order', $datetime_row);
1044
-            $existing_datetime_ids[] = $DTT_ID;
1045
-            // tickets attached
1046
-            $related_tickets = $datetime->ID() > 0
1047
-                ? $datetime->get_many_related(
1048
-                    'Ticket',
1049
-                    array(
1050
-                        array(
1051
-                            'OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0),
1052
-                        ),
1053
-                        'default_where_conditions' => 'none',
1054
-                        'order_by'                 => array('TKT_order' => 'ASC'),
1055
-                    )
1056
-                )
1057
-                : array();
1058
-            // if there are no related tickets this is likely a new event OR autodraft
1059
-            // event so we need to generate the default tickets because datetimes
1060
-            // ALWAYS have at least one related ticket!!.  EXCEPT, we dont' do this if there is already more than one
1061
-            // datetime on the event.
1062
-            if (empty($related_tickets) && count($datetimes) < 2) {
1063
-                /** @var EEM_Ticket $ticket_model */
1064
-                $ticket_model = EE_Registry::instance()->load_model('Ticket');
1065
-                $related_tickets = $ticket_model->get_all_default_tickets();
1066
-                // this should be ordered by TKT_ID, so let's grab the first default ticket
1067
-                // (which will be the main default) and ensure it has any default prices added to it (but do NOT save).
1068
-                $default_prices = EEM_Price::instance()->get_all_default_prices();
1069
-                $main_default_ticket = reset($related_tickets);
1070
-                if ($main_default_ticket instanceof EE_Ticket) {
1071
-                    foreach ($default_prices as $default_price) {
1072
-                        if ($default_price instanceof EE_Price && $default_price->is_base_price()) {
1073
-                            continue;
1074
-                        }
1075
-                        $main_default_ticket->cache('Price', $default_price);
1076
-                    }
1077
-                }
1078
-            }
1079
-            // we can't actually setup rows in this loop yet cause we don't know all
1080
-            // the unique tickets for this event yet (tickets are linked through all datetimes).
1081
-            // So we're going to temporarily cache some of that information.
1082
-            // loop through and setup the ticket rows and make sure the order is set.
1083
-            foreach ($related_tickets as $ticket) {
1084
-                $TKT_ID = $ticket->get('TKT_ID');
1085
-                $ticket_row = $ticket->get('TKT_row');
1086
-                // we only want unique tickets in our final display!!
1087
-                if (! in_array($TKT_ID, $existing_ticket_ids, true)) {
1088
-                    $existing_ticket_ids[] = $TKT_ID;
1089
-                    $all_tickets[] = $ticket;
1090
-                }
1091
-                // temporary cache of this ticket info for this datetime for later processing of datetime rows.
1092
-                $datetime_tickets[ $DTT_ID ][] = $ticket_row;
1093
-                // temporary cache of this datetime info for this ticket for later processing of ticket rows.
1094
-                if (! isset($ticket_datetimes[ $TKT_ID ])
1095
-                    || ! in_array($datetime_row, $ticket_datetimes[ $TKT_ID ], true)
1096
-                ) {
1097
-                    $ticket_datetimes[ $TKT_ID ][] = $datetime_row;
1098
-                }
1099
-            }
1100
-            $datetime_row++;
1101
-        }
1102
-        $main_template_args['total_ticket_rows'] = count($existing_ticket_ids);
1103
-        $main_template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1104
-        $main_template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1105
-        // sort $all_tickets by order
1106
-        usort(
1107
-            $all_tickets,
1108
-            function (EE_Ticket $a, EE_Ticket $b) {
1109
-                $a_order = (int) $a->get('TKT_order');
1110
-                $b_order = (int) $b->get('TKT_order');
1111
-                if ($a_order === $b_order) {
1112
-                    return 0;
1113
-                }
1114
-                return ($a_order < $b_order) ? -1 : 1;
1115
-            }
1116
-        );
1117
-        // k NOW we have all the data we need for setting up the dtt rows
1118
-        // and ticket rows so we start our dtt loop again.
1119
-        $datetime_row = 1;
1120
-        foreach ($datetimes as $datetime) {
1121
-            $main_template_args['datetime_rows'] .= $this->_get_datetime_row(
1122
-                $datetime_row,
1123
-                $datetime,
1124
-                $datetime_tickets,
1125
-                $all_tickets,
1126
-                false,
1127
-                $datetimes
1128
-            );
1129
-            $datetime_row++;
1130
-        }
1131
-        // then loop through all tickets for the ticket rows.
1132
-        $ticket_row = 1;
1133
-        foreach ($all_tickets as $ticket) {
1134
-            $main_template_args['ticket_rows'] .= $this->_get_ticket_row(
1135
-                $ticket_row,
1136
-                $ticket,
1137
-                $ticket_datetimes,
1138
-                $datetimes,
1139
-                false,
1140
-                $all_tickets
1141
-            );
1142
-            $ticket_row++;
1143
-        }
1144
-        $main_template_args['ticket_js_structure'] = $this->_get_ticket_js_structure($datetimes, $all_tickets);
1145
-        $main_template_args['status_change_notice'] = EEH_Template::display_template(
1146
-            EE_ADMIN_TEMPLATE . 'status_change_notice.template.php',
1147
-            [ 'context' => '__event-editor' ],
1148
-            true
1149
-        );
1150
-        EEH_Template::display_template(
1151
-            PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php',
1152
-            $main_template_args
1153
-        );
1154
-    }
979
+	/**
980
+	 * @throws ReflectionException
981
+	 * @throws InvalidArgumentException
982
+	 * @throws InvalidInterfaceException
983
+	 * @throws InvalidDataTypeException
984
+	 * @throws DomainException
985
+	 * @throws EE_Error
986
+	 */
987
+	public function pricing_metabox()
988
+	{
989
+		$existing_datetime_ids = $existing_ticket_ids = $datetime_tickets = $ticket_datetimes = array();
990
+		$event = $this->_adminpage_obj->get_cpt_model_obj();
991
+		// set is_creating_event property.
992
+		$EVT_ID = $event->ID();
993
+		$this->_is_creating_event = empty($this->_req_data['post']);
994
+		// default main template args
995
+		$main_template_args = array(
996
+			'event_datetime_help_link' => EEH_Template::get_help_tab_link(
997
+				'event_editor_event_datetimes_help_tab',
998
+				$this->_adminpage_obj->page_slug,
999
+				$this->_adminpage_obj->get_req_action(),
1000
+				false,
1001
+				false
1002
+			),
1003
+			// todo need to add a filter to the template for the help text
1004
+			// in the Events_Admin_Page core file so we can add further help
1005
+			'existing_datetime_ids'    => '',
1006
+			'total_dtt_rows'           => 1,
1007
+			'add_new_dtt_help_link'    => EEH_Template::get_help_tab_link(
1008
+				'add_new_dtt_info',
1009
+				$this->_adminpage_obj->page_slug,
1010
+				$this->_adminpage_obj->get_req_action(),
1011
+				false,
1012
+				false
1013
+			),
1014
+			// todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1015
+			'datetime_rows'            => '',
1016
+			'show_tickets_container'   => '',
1017
+			// $this->_adminpage_obj->get_cpt_model_obj()->ID() > 1 ? ' style="display:none;"' : '',
1018
+			'ticket_rows'              => '',
1019
+			'existing_ticket_ids'      => '',
1020
+			'total_ticket_rows'        => 1,
1021
+			'ticket_js_structure'      => '',
1022
+			'ee_collapsible_status'    => ' ee-collapsible-open'
1023
+			// $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' ee-collapsible-closed' : ' ee-collapsible-open'
1024
+		);
1025
+		$timezone = $event instanceof EE_Event ? $event->timezone_string() : null;
1026
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1027
+		/**
1028
+		 * 1. Start with retrieving Datetimes
1029
+		 * 2. For each datetime get related tickets
1030
+		 * 3. For each ticket get related prices
1031
+		 */
1032
+		/** @var EEM_Datetime $datetime_model */
1033
+		$datetime_model = EE_Registry::instance()->load_model('Datetime', array($timezone));
1034
+		$datetimes = $datetime_model->get_all_event_dates($EVT_ID);
1035
+		$main_template_args['total_dtt_rows'] = count($datetimes);
1036
+		/**
1037
+		 * @see https://events.codebasehq.com/projects/event-espresso/tickets/9486
1038
+		 * for why we are counting $datetime_row and then setting that on the Datetime object
1039
+		 */
1040
+		$datetime_row = 1;
1041
+		foreach ($datetimes as $datetime) {
1042
+			$DTT_ID = $datetime->get('DTT_ID');
1043
+			$datetime->set('DTT_order', $datetime_row);
1044
+			$existing_datetime_ids[] = $DTT_ID;
1045
+			// tickets attached
1046
+			$related_tickets = $datetime->ID() > 0
1047
+				? $datetime->get_many_related(
1048
+					'Ticket',
1049
+					array(
1050
+						array(
1051
+							'OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0),
1052
+						),
1053
+						'default_where_conditions' => 'none',
1054
+						'order_by'                 => array('TKT_order' => 'ASC'),
1055
+					)
1056
+				)
1057
+				: array();
1058
+			// if there are no related tickets this is likely a new event OR autodraft
1059
+			// event so we need to generate the default tickets because datetimes
1060
+			// ALWAYS have at least one related ticket!!.  EXCEPT, we dont' do this if there is already more than one
1061
+			// datetime on the event.
1062
+			if (empty($related_tickets) && count($datetimes) < 2) {
1063
+				/** @var EEM_Ticket $ticket_model */
1064
+				$ticket_model = EE_Registry::instance()->load_model('Ticket');
1065
+				$related_tickets = $ticket_model->get_all_default_tickets();
1066
+				// this should be ordered by TKT_ID, so let's grab the first default ticket
1067
+				// (which will be the main default) and ensure it has any default prices added to it (but do NOT save).
1068
+				$default_prices = EEM_Price::instance()->get_all_default_prices();
1069
+				$main_default_ticket = reset($related_tickets);
1070
+				if ($main_default_ticket instanceof EE_Ticket) {
1071
+					foreach ($default_prices as $default_price) {
1072
+						if ($default_price instanceof EE_Price && $default_price->is_base_price()) {
1073
+							continue;
1074
+						}
1075
+						$main_default_ticket->cache('Price', $default_price);
1076
+					}
1077
+				}
1078
+			}
1079
+			// we can't actually setup rows in this loop yet cause we don't know all
1080
+			// the unique tickets for this event yet (tickets are linked through all datetimes).
1081
+			// So we're going to temporarily cache some of that information.
1082
+			// loop through and setup the ticket rows and make sure the order is set.
1083
+			foreach ($related_tickets as $ticket) {
1084
+				$TKT_ID = $ticket->get('TKT_ID');
1085
+				$ticket_row = $ticket->get('TKT_row');
1086
+				// we only want unique tickets in our final display!!
1087
+				if (! in_array($TKT_ID, $existing_ticket_ids, true)) {
1088
+					$existing_ticket_ids[] = $TKT_ID;
1089
+					$all_tickets[] = $ticket;
1090
+				}
1091
+				// temporary cache of this ticket info for this datetime for later processing of datetime rows.
1092
+				$datetime_tickets[ $DTT_ID ][] = $ticket_row;
1093
+				// temporary cache of this datetime info for this ticket for later processing of ticket rows.
1094
+				if (! isset($ticket_datetimes[ $TKT_ID ])
1095
+					|| ! in_array($datetime_row, $ticket_datetimes[ $TKT_ID ], true)
1096
+				) {
1097
+					$ticket_datetimes[ $TKT_ID ][] = $datetime_row;
1098
+				}
1099
+			}
1100
+			$datetime_row++;
1101
+		}
1102
+		$main_template_args['total_ticket_rows'] = count($existing_ticket_ids);
1103
+		$main_template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1104
+		$main_template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1105
+		// sort $all_tickets by order
1106
+		usort(
1107
+			$all_tickets,
1108
+			function (EE_Ticket $a, EE_Ticket $b) {
1109
+				$a_order = (int) $a->get('TKT_order');
1110
+				$b_order = (int) $b->get('TKT_order');
1111
+				if ($a_order === $b_order) {
1112
+					return 0;
1113
+				}
1114
+				return ($a_order < $b_order) ? -1 : 1;
1115
+			}
1116
+		);
1117
+		// k NOW we have all the data we need for setting up the dtt rows
1118
+		// and ticket rows so we start our dtt loop again.
1119
+		$datetime_row = 1;
1120
+		foreach ($datetimes as $datetime) {
1121
+			$main_template_args['datetime_rows'] .= $this->_get_datetime_row(
1122
+				$datetime_row,
1123
+				$datetime,
1124
+				$datetime_tickets,
1125
+				$all_tickets,
1126
+				false,
1127
+				$datetimes
1128
+			);
1129
+			$datetime_row++;
1130
+		}
1131
+		// then loop through all tickets for the ticket rows.
1132
+		$ticket_row = 1;
1133
+		foreach ($all_tickets as $ticket) {
1134
+			$main_template_args['ticket_rows'] .= $this->_get_ticket_row(
1135
+				$ticket_row,
1136
+				$ticket,
1137
+				$ticket_datetimes,
1138
+				$datetimes,
1139
+				false,
1140
+				$all_tickets
1141
+			);
1142
+			$ticket_row++;
1143
+		}
1144
+		$main_template_args['ticket_js_structure'] = $this->_get_ticket_js_structure($datetimes, $all_tickets);
1145
+		$main_template_args['status_change_notice'] = EEH_Template::display_template(
1146
+			EE_ADMIN_TEMPLATE . 'status_change_notice.template.php',
1147
+			[ 'context' => '__event-editor' ],
1148
+			true
1149
+		);
1150
+		EEH_Template::display_template(
1151
+			PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php',
1152
+			$main_template_args
1153
+		);
1154
+	}
1155 1155
 
1156 1156
 
1157
-    /**
1158
-     * @param int         $datetime_row
1159
-     * @param EE_Datetime $datetime
1160
-     * @param array       $datetime_tickets
1161
-     * @param array       $all_tickets
1162
-     * @param bool        $default
1163
-     * @param array       $all_datetimes
1164
-     * @return mixed
1165
-     * @throws DomainException
1166
-     * @throws EE_Error
1167
-     */
1168
-    protected function _get_datetime_row(
1169
-        $datetime_row,
1170
-        EE_Datetime $datetime,
1171
-        $datetime_tickets = array(),
1172
-        $all_tickets = array(),
1173
-        $default = false,
1174
-        $all_datetimes = array()
1175
-    ) {
1176
-        $dtt_display_template_args = array(
1177
-            'dtt_edit_row'             => $this->_get_dtt_edit_row(
1178
-                $datetime_row,
1179
-                $datetime,
1180
-                $default,
1181
-                $all_datetimes
1182
-            ),
1183
-            'dtt_attached_tickets_row' => $this->_get_dtt_attached_tickets_row(
1184
-                $datetime_row,
1185
-                $datetime,
1186
-                $datetime_tickets,
1187
-                $all_tickets,
1188
-                $default
1189
-            ),
1190
-            'dtt_row'                  => $default ? 'DTTNUM' : $datetime_row,
1191
-        );
1192
-        return EEH_Template::display_template(
1193
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php',
1194
-            $dtt_display_template_args,
1195
-            true
1196
-        );
1197
-    }
1157
+	/**
1158
+	 * @param int         $datetime_row
1159
+	 * @param EE_Datetime $datetime
1160
+	 * @param array       $datetime_tickets
1161
+	 * @param array       $all_tickets
1162
+	 * @param bool        $default
1163
+	 * @param array       $all_datetimes
1164
+	 * @return mixed
1165
+	 * @throws DomainException
1166
+	 * @throws EE_Error
1167
+	 */
1168
+	protected function _get_datetime_row(
1169
+		$datetime_row,
1170
+		EE_Datetime $datetime,
1171
+		$datetime_tickets = array(),
1172
+		$all_tickets = array(),
1173
+		$default = false,
1174
+		$all_datetimes = array()
1175
+	) {
1176
+		$dtt_display_template_args = array(
1177
+			'dtt_edit_row'             => $this->_get_dtt_edit_row(
1178
+				$datetime_row,
1179
+				$datetime,
1180
+				$default,
1181
+				$all_datetimes
1182
+			),
1183
+			'dtt_attached_tickets_row' => $this->_get_dtt_attached_tickets_row(
1184
+				$datetime_row,
1185
+				$datetime,
1186
+				$datetime_tickets,
1187
+				$all_tickets,
1188
+				$default
1189
+			),
1190
+			'dtt_row'                  => $default ? 'DTTNUM' : $datetime_row,
1191
+		);
1192
+		return EEH_Template::display_template(
1193
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php',
1194
+			$dtt_display_template_args,
1195
+			true
1196
+		);
1197
+	}
1198 1198
 
1199 1199
 
1200
-    /**
1201
-     * This method is used to generate a dtt fields  edit row.
1202
-     * The same row is used to generate a row with valid DTT objects
1203
-     * and the default row that is used as the skeleton by the js.
1204
-     *
1205
-     * @param int           $datetime_row  The row number for the row being generated.
1206
-     * @param EE_Datetime   $datetime
1207
-     * @param bool          $default       Whether a default row is being generated or not.
1208
-     * @param EE_Datetime[] $all_datetimes This is the array of all datetimes used in the editor.
1209
-     * @return string
1210
-     * @throws DomainException
1211
-     * @throws EE_Error
1212
-     */
1213
-    protected function _get_dtt_edit_row($datetime_row, $datetime, $default, $all_datetimes)
1214
-    {
1215
-        // if the incoming $datetime object is NOT an instance of EE_Datetime then force default to true.
1216
-        $default = ! $datetime instanceof EE_Datetime ? true : $default;
1217
-        $template_args = array(
1218
-            'dtt_row'              => $default ? 'DTTNUM' : $datetime_row,
1219
-            'event_datetimes_name' => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1220
-            'edit_dtt_expanded'    => '',
1221
-            'DTT_ID'               => $default ? '' : $datetime->ID(),
1222
-            'DTT_name'             => $default ? '' : $datetime->get_f('DTT_name'),
1223
-            'DTT_description'      => $default ? '' : $datetime->get_f('DTT_description'),
1224
-            'DTT_EVT_start'        => $default ? '' : $datetime->start_date($this->_date_time_format),
1225
-            'DTT_EVT_end'          => $default ? '' : $datetime->end_date($this->_date_time_format),
1226
-            'DTT_reg_limit'        => $default
1227
-                ? ''
1228
-                : $datetime->get_pretty(
1229
-                    'DTT_reg_limit',
1230
-                    'input'
1231
-                ),
1232
-            'DTT_order'            => $default ? 'DTTNUM' : $datetime_row,
1233
-            'dtt_sold'             => $default ? '0' : $datetime->get('DTT_sold'),
1234
-            'dtt_reserved'         => $default ? '0' : $datetime->reserved(),
1235
-            'clone_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1236
-                ? ''
1237
-                : 'clone-icon ee-icon ee-icon-clone clickable',
1238
-            'trash_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1239
-                ? 'ee-lock-icon'
1240
-                : 'trash-icon dashicons dashicons-post-trash clickable',
1241
-            'reg_list_url'         => $default || ! $datetime->event() instanceof \EE_Event
1242
-                ? ''
1243
-                : EE_Admin_Page::add_query_args_and_nonce(
1244
-                    array('event_id' => $datetime->event()->ID(), 'datetime_id' => $datetime->ID()),
1245
-                    REG_ADMIN_URL
1246
-                ),
1247
-        );
1248
-        $template_args['show_trash'] = count($all_datetimes) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1249
-            ? ' style="display:none"'
1250
-            : '';
1251
-        // allow filtering of template args at this point.
1252
-        $template_args = apply_filters(
1253
-            'FHEE__espresso_events_Pricing_Hooks___get_dtt_edit_row__template_args',
1254
-            $template_args,
1255
-            $datetime_row,
1256
-            $datetime,
1257
-            $default,
1258
-            $all_datetimes,
1259
-            $this->_is_creating_event
1260
-        );
1261
-        return EEH_Template::display_template(
1262
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php',
1263
-            $template_args,
1264
-            true
1265
-        );
1266
-    }
1200
+	/**
1201
+	 * This method is used to generate a dtt fields  edit row.
1202
+	 * The same row is used to generate a row with valid DTT objects
1203
+	 * and the default row that is used as the skeleton by the js.
1204
+	 *
1205
+	 * @param int           $datetime_row  The row number for the row being generated.
1206
+	 * @param EE_Datetime   $datetime
1207
+	 * @param bool          $default       Whether a default row is being generated or not.
1208
+	 * @param EE_Datetime[] $all_datetimes This is the array of all datetimes used in the editor.
1209
+	 * @return string
1210
+	 * @throws DomainException
1211
+	 * @throws EE_Error
1212
+	 */
1213
+	protected function _get_dtt_edit_row($datetime_row, $datetime, $default, $all_datetimes)
1214
+	{
1215
+		// if the incoming $datetime object is NOT an instance of EE_Datetime then force default to true.
1216
+		$default = ! $datetime instanceof EE_Datetime ? true : $default;
1217
+		$template_args = array(
1218
+			'dtt_row'              => $default ? 'DTTNUM' : $datetime_row,
1219
+			'event_datetimes_name' => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1220
+			'edit_dtt_expanded'    => '',
1221
+			'DTT_ID'               => $default ? '' : $datetime->ID(),
1222
+			'DTT_name'             => $default ? '' : $datetime->get_f('DTT_name'),
1223
+			'DTT_description'      => $default ? '' : $datetime->get_f('DTT_description'),
1224
+			'DTT_EVT_start'        => $default ? '' : $datetime->start_date($this->_date_time_format),
1225
+			'DTT_EVT_end'          => $default ? '' : $datetime->end_date($this->_date_time_format),
1226
+			'DTT_reg_limit'        => $default
1227
+				? ''
1228
+				: $datetime->get_pretty(
1229
+					'DTT_reg_limit',
1230
+					'input'
1231
+				),
1232
+			'DTT_order'            => $default ? 'DTTNUM' : $datetime_row,
1233
+			'dtt_sold'             => $default ? '0' : $datetime->get('DTT_sold'),
1234
+			'dtt_reserved'         => $default ? '0' : $datetime->reserved(),
1235
+			'clone_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1236
+				? ''
1237
+				: 'clone-icon ee-icon ee-icon-clone clickable',
1238
+			'trash_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1239
+				? 'ee-lock-icon'
1240
+				: 'trash-icon dashicons dashicons-post-trash clickable',
1241
+			'reg_list_url'         => $default || ! $datetime->event() instanceof \EE_Event
1242
+				? ''
1243
+				: EE_Admin_Page::add_query_args_and_nonce(
1244
+					array('event_id' => $datetime->event()->ID(), 'datetime_id' => $datetime->ID()),
1245
+					REG_ADMIN_URL
1246
+				),
1247
+		);
1248
+		$template_args['show_trash'] = count($all_datetimes) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1249
+			? ' style="display:none"'
1250
+			: '';
1251
+		// allow filtering of template args at this point.
1252
+		$template_args = apply_filters(
1253
+			'FHEE__espresso_events_Pricing_Hooks___get_dtt_edit_row__template_args',
1254
+			$template_args,
1255
+			$datetime_row,
1256
+			$datetime,
1257
+			$default,
1258
+			$all_datetimes,
1259
+			$this->_is_creating_event
1260
+		);
1261
+		return EEH_Template::display_template(
1262
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php',
1263
+			$template_args,
1264
+			true
1265
+		);
1266
+	}
1267 1267
 
1268 1268
 
1269
-    /**
1270
-     * @param int         $datetime_row
1271
-     * @param EE_Datetime $datetime
1272
-     * @param array       $datetime_tickets
1273
-     * @param array       $all_tickets
1274
-     * @param bool        $default
1275
-     * @return mixed
1276
-     * @throws DomainException
1277
-     * @throws EE_Error
1278
-     */
1279
-    protected function _get_dtt_attached_tickets_row(
1280
-        $datetime_row,
1281
-        $datetime,
1282
-        $datetime_tickets = array(),
1283
-        $all_tickets = array(),
1284
-        $default
1285
-    ) {
1286
-        $template_args = array(
1287
-            'dtt_row'                           => $default ? 'DTTNUM' : $datetime_row,
1288
-            'event_datetimes_name'              => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1289
-            'DTT_description'                   => $default ? '' : $datetime->get_f('DTT_description'),
1290
-            'datetime_tickets_list'             => $default ? '<li class="hidden"></li>' : '',
1291
-            'show_tickets_row'                  => ' style="display:none;"',
1292
-            'add_new_datetime_ticket_help_link' => EEH_Template::get_help_tab_link(
1293
-                'add_new_ticket_via_datetime',
1294
-                $this->_adminpage_obj->page_slug,
1295
-                $this->_adminpage_obj->get_req_action(),
1296
-                false,
1297
-                false
1298
-            ),
1299
-            // todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1300
-            'DTT_ID'                            => $default ? '' : $datetime->ID(),
1301
-        );
1302
-        // need to setup the list items (but only if this isn't a default skeleton setup)
1303
-        if (! $default) {
1304
-            $ticket_row = 1;
1305
-            foreach ($all_tickets as $ticket) {
1306
-                $template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
1307
-                    $datetime_row,
1308
-                    $ticket_row,
1309
-                    $datetime,
1310
-                    $ticket,
1311
-                    $datetime_tickets,
1312
-                    $default
1313
-                );
1314
-                $ticket_row++;
1315
-            }
1316
-        }
1317
-        // filter template args at this point
1318
-        $template_args = apply_filters(
1319
-            'FHEE__espresso_events_Pricing_Hooks___get_dtt_attached_ticket_row__template_args',
1320
-            $template_args,
1321
-            $datetime_row,
1322
-            $datetime,
1323
-            $datetime_tickets,
1324
-            $all_tickets,
1325
-            $default,
1326
-            $this->_is_creating_event
1327
-        );
1328
-        return EEH_Template::display_template(
1329
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php',
1330
-            $template_args,
1331
-            true
1332
-        );
1333
-    }
1269
+	/**
1270
+	 * @param int         $datetime_row
1271
+	 * @param EE_Datetime $datetime
1272
+	 * @param array       $datetime_tickets
1273
+	 * @param array       $all_tickets
1274
+	 * @param bool        $default
1275
+	 * @return mixed
1276
+	 * @throws DomainException
1277
+	 * @throws EE_Error
1278
+	 */
1279
+	protected function _get_dtt_attached_tickets_row(
1280
+		$datetime_row,
1281
+		$datetime,
1282
+		$datetime_tickets = array(),
1283
+		$all_tickets = array(),
1284
+		$default
1285
+	) {
1286
+		$template_args = array(
1287
+			'dtt_row'                           => $default ? 'DTTNUM' : $datetime_row,
1288
+			'event_datetimes_name'              => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1289
+			'DTT_description'                   => $default ? '' : $datetime->get_f('DTT_description'),
1290
+			'datetime_tickets_list'             => $default ? '<li class="hidden"></li>' : '',
1291
+			'show_tickets_row'                  => ' style="display:none;"',
1292
+			'add_new_datetime_ticket_help_link' => EEH_Template::get_help_tab_link(
1293
+				'add_new_ticket_via_datetime',
1294
+				$this->_adminpage_obj->page_slug,
1295
+				$this->_adminpage_obj->get_req_action(),
1296
+				false,
1297
+				false
1298
+			),
1299
+			// todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1300
+			'DTT_ID'                            => $default ? '' : $datetime->ID(),
1301
+		);
1302
+		// need to setup the list items (but only if this isn't a default skeleton setup)
1303
+		if (! $default) {
1304
+			$ticket_row = 1;
1305
+			foreach ($all_tickets as $ticket) {
1306
+				$template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
1307
+					$datetime_row,
1308
+					$ticket_row,
1309
+					$datetime,
1310
+					$ticket,
1311
+					$datetime_tickets,
1312
+					$default
1313
+				);
1314
+				$ticket_row++;
1315
+			}
1316
+		}
1317
+		// filter template args at this point
1318
+		$template_args = apply_filters(
1319
+			'FHEE__espresso_events_Pricing_Hooks___get_dtt_attached_ticket_row__template_args',
1320
+			$template_args,
1321
+			$datetime_row,
1322
+			$datetime,
1323
+			$datetime_tickets,
1324
+			$all_tickets,
1325
+			$default,
1326
+			$this->_is_creating_event
1327
+		);
1328
+		return EEH_Template::display_template(
1329
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php',
1330
+			$template_args,
1331
+			true
1332
+		);
1333
+	}
1334 1334
 
1335 1335
 
1336
-    /**
1337
-     * @param int         $datetime_row
1338
-     * @param int         $ticket_row
1339
-     * @param EE_Datetime $datetime
1340
-     * @param EE_Ticket   $ticket
1341
-     * @param array       $datetime_tickets
1342
-     * @param bool        $default
1343
-     * @return mixed
1344
-     * @throws DomainException
1345
-     * @throws EE_Error
1346
-     */
1347
-    protected function _get_datetime_tickets_list_item(
1348
-        $datetime_row,
1349
-        $ticket_row,
1350
-        $datetime,
1351
-        $ticket,
1352
-        $datetime_tickets = array(),
1353
-        $default
1354
-    ) {
1355
-        $dtt_tkts = $datetime instanceof EE_Datetime && isset($datetime_tickets[ $datetime->ID() ])
1356
-            ? $datetime_tickets[ $datetime->ID() ]
1357
-            : array();
1358
-        $display_row = $ticket instanceof EE_Ticket ? $ticket->get('TKT_row') : 0;
1359
-        $no_ticket = $default && empty($ticket);
1360
-        $template_args = array(
1361
-            'dtt_row'                 => $default
1362
-                ? 'DTTNUM'
1363
-                : $datetime_row,
1364
-            'tkt_row'                 => $no_ticket
1365
-                ? 'TICKETNUM'
1366
-                : $ticket_row,
1367
-            'datetime_ticket_checked' => in_array($display_row, $dtt_tkts, true)
1368
-                ? ' checked="checked"'
1369
-                : '',
1370
-            'ticket_selected'         => in_array($display_row, $dtt_tkts, true)
1371
-                ? ' ticket-selected'
1372
-                : '',
1373
-            'TKT_name'                => $no_ticket
1374
-                ? 'TKTNAME'
1375
-                : $ticket->get('TKT_name'),
1376
-            'tkt_status_class'        => $no_ticket || $this->_is_creating_event
1377
-                ? ' tkt-status-' . EE_Ticket::onsale
1378
-                : ' tkt-status-' . $ticket->ticket_status(),
1379
-        );
1380
-        // filter template args
1381
-        $template_args = apply_filters(
1382
-            'FHEE__espresso_events_Pricing_Hooks___get_datetime_tickets_list_item__template_args',
1383
-            $template_args,
1384
-            $datetime_row,
1385
-            $ticket_row,
1386
-            $datetime,
1387
-            $ticket,
1388
-            $datetime_tickets,
1389
-            $default,
1390
-            $this->_is_creating_event
1391
-        );
1392
-        return EEH_Template::display_template(
1393
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php',
1394
-            $template_args,
1395
-            true
1396
-        );
1397
-    }
1336
+	/**
1337
+	 * @param int         $datetime_row
1338
+	 * @param int         $ticket_row
1339
+	 * @param EE_Datetime $datetime
1340
+	 * @param EE_Ticket   $ticket
1341
+	 * @param array       $datetime_tickets
1342
+	 * @param bool        $default
1343
+	 * @return mixed
1344
+	 * @throws DomainException
1345
+	 * @throws EE_Error
1346
+	 */
1347
+	protected function _get_datetime_tickets_list_item(
1348
+		$datetime_row,
1349
+		$ticket_row,
1350
+		$datetime,
1351
+		$ticket,
1352
+		$datetime_tickets = array(),
1353
+		$default
1354
+	) {
1355
+		$dtt_tkts = $datetime instanceof EE_Datetime && isset($datetime_tickets[ $datetime->ID() ])
1356
+			? $datetime_tickets[ $datetime->ID() ]
1357
+			: array();
1358
+		$display_row = $ticket instanceof EE_Ticket ? $ticket->get('TKT_row') : 0;
1359
+		$no_ticket = $default && empty($ticket);
1360
+		$template_args = array(
1361
+			'dtt_row'                 => $default
1362
+				? 'DTTNUM'
1363
+				: $datetime_row,
1364
+			'tkt_row'                 => $no_ticket
1365
+				? 'TICKETNUM'
1366
+				: $ticket_row,
1367
+			'datetime_ticket_checked' => in_array($display_row, $dtt_tkts, true)
1368
+				? ' checked="checked"'
1369
+				: '',
1370
+			'ticket_selected'         => in_array($display_row, $dtt_tkts, true)
1371
+				? ' ticket-selected'
1372
+				: '',
1373
+			'TKT_name'                => $no_ticket
1374
+				? 'TKTNAME'
1375
+				: $ticket->get('TKT_name'),
1376
+			'tkt_status_class'        => $no_ticket || $this->_is_creating_event
1377
+				? ' tkt-status-' . EE_Ticket::onsale
1378
+				: ' tkt-status-' . $ticket->ticket_status(),
1379
+		);
1380
+		// filter template args
1381
+		$template_args = apply_filters(
1382
+			'FHEE__espresso_events_Pricing_Hooks___get_datetime_tickets_list_item__template_args',
1383
+			$template_args,
1384
+			$datetime_row,
1385
+			$ticket_row,
1386
+			$datetime,
1387
+			$ticket,
1388
+			$datetime_tickets,
1389
+			$default,
1390
+			$this->_is_creating_event
1391
+		);
1392
+		return EEH_Template::display_template(
1393
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php',
1394
+			$template_args,
1395
+			true
1396
+		);
1397
+	}
1398 1398
 
1399 1399
 
1400
-    /**
1401
-     * This generates the ticket row for tickets.
1402
-     * This same method is used to generate both the actual rows and the js skeleton row
1403
-     * (when default === true)
1404
-     *
1405
-     * @param int           $ticket_row       Represents the row number being generated.
1406
-     * @param               $ticket
1407
-     * @param EE_Datetime[] $ticket_datetimes Either an array of all datetimes on all tickets indexed by each ticket
1408
-     *                                        or empty for default
1409
-     * @param EE_Datetime[] $all_datetimes    All Datetimes on the event or empty for default.
1410
-     * @param bool          $default          Whether default row being generated or not.
1411
-     * @param EE_Ticket[]   $all_tickets      This is an array of all tickets attached to the event
1412
-     *                                        (or empty in the case of defaults)
1413
-     * @return mixed
1414
-     * @throws InvalidArgumentException
1415
-     * @throws InvalidInterfaceException
1416
-     * @throws InvalidDataTypeException
1417
-     * @throws DomainException
1418
-     * @throws EE_Error
1419
-     * @throws ReflectionException
1420
-     */
1421
-    protected function _get_ticket_row(
1422
-        $ticket_row,
1423
-        $ticket,
1424
-        $ticket_datetimes,
1425
-        $all_datetimes,
1426
-        $default = false,
1427
-        $all_tickets = array()
1428
-    ) {
1429
-        // if $ticket is not an instance of EE_Ticket then force default to true.
1430
-        $default = ! $ticket instanceof EE_Ticket ? true : $default;
1431
-        $prices = ! empty($ticket) && ! $default
1432
-            ? $ticket->get_many_related(
1433
-                'Price',
1434
-                array('default_where_conditions' => 'none', 'order_by' => array('PRC_order' => 'ASC'))
1435
-            )
1436
-            : array();
1437
-        // if there is only one price (which would be the base price)
1438
-        // or NO prices and this ticket is a default ticket,
1439
-        // let's just make sure there are no cached default prices on the object.
1440
-        // This is done by not including any query_params.
1441
-        if ($ticket instanceof EE_Ticket && $ticket->is_default() && (count($prices) === 1 || empty($prices))) {
1442
-            $prices = $ticket->prices();
1443
-        }
1444
-        // check if we're dealing with a default ticket in which case
1445
-        // we don't want any starting_ticket_datetime_row values set
1446
-        // (otherwise there won't be any new relationships created for tickets based off of the default ticket).
1447
-        // This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1448
-        $default_dtt = $default || ($ticket instanceof EE_Ticket && $ticket->is_default());
1449
-        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
1450
-            ? $ticket_datetimes[ $ticket->ID() ]
1451
-            : array();
1452
-        $ticket_subtotal = $default ? 0 : $ticket->get_ticket_subtotal();
1453
-        $base_price = $default ? null : $ticket->base_price();
1454
-        $count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1455
-        // breaking out complicated condition for ticket_status
1456
-        if ($default) {
1457
-            $ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1458
-        } else {
1459
-            $ticket_status_class = $ticket->is_default()
1460
-                ? ' tkt-status-' . EE_Ticket::onsale
1461
-                : ' tkt-status-' . $ticket->ticket_status();
1462
-        }
1463
-        // breaking out complicated condition for TKT_taxable
1464
-        if ($default) {
1465
-            $TKT_taxable = '';
1466
-        } else {
1467
-            $TKT_taxable = $ticket->taxable()
1468
-                ? ' checked="checked"'
1469
-                : '';
1470
-        }
1471
-        if ($default) {
1472
-            $TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1473
-        } elseif ($ticket->is_default()) {
1474
-            $TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1475
-        } else {
1476
-            $TKT_status = $ticket->ticket_status(true);
1477
-        }
1478
-        if ($default) {
1479
-            $TKT_min = '';
1480
-        } else {
1481
-            $TKT_min = $ticket->min();
1482
-            if ($TKT_min === -1 || $TKT_min === 0) {
1483
-                $TKT_min = '';
1484
-            }
1485
-        }
1486
-        $template_args = array(
1487
-            'tkt_row'                       => $default ? 'TICKETNUM' : $ticket_row,
1488
-            'TKT_order'                     => $default ? 'TICKETNUM' : $ticket_row,
1489
-            // on initial page load this will always be the correct order.
1490
-            'tkt_status_class'              => $ticket_status_class,
1491
-            'display_edit_tkt_row'          => ' style="display:none;"',
1492
-            'edit_tkt_expanded'             => '',
1493
-            'edit_tickets_name'             => $default ? 'TICKETNAMEATTR' : 'edit_tickets',
1494
-            'TKT_name'                      => $default ? '' : $ticket->get_f('TKT_name'),
1495
-            'TKT_start_date'                => $default
1496
-                ? ''
1497
-                : $ticket->get_date('TKT_start_date', $this->_date_time_format),
1498
-            'TKT_end_date'                  => $default
1499
-                ? ''
1500
-                : $ticket->get_date('TKT_end_date', $this->_date_time_format),
1501
-            'TKT_status'                    => $TKT_status,
1502
-            'TKT_price'                     => $default
1503
-                ? ''
1504
-                : EEH_Template::format_currency(
1505
-                    $ticket->get_ticket_total_with_taxes(),
1506
-                    false,
1507
-                    false
1508
-                ),
1509
-            'TKT_price_code'                => EE_Registry::instance()->CFG->currency->code,
1510
-            'TKT_price_amount'              => $default ? 0 : $ticket_subtotal,
1511
-            'TKT_qty'                       => $default
1512
-                ? ''
1513
-                : $ticket->get_pretty('TKT_qty', 'symbol'),
1514
-            'TKT_qty_for_input'             => $default
1515
-                ? ''
1516
-                : $ticket->get_pretty('TKT_qty', 'input'),
1517
-            'TKT_uses'                      => $default
1518
-                ? ''
1519
-                : $ticket->get_pretty('TKT_uses', 'input'),
1520
-            'TKT_min'                       => $TKT_min,
1521
-            'TKT_max'                       => $default
1522
-                ? ''
1523
-                : $ticket->get_pretty('TKT_max', 'input'),
1524
-            'TKT_sold'                      => $default ? 0 : $ticket->tickets_sold('ticket'),
1525
-            'TKT_reserved'                  => $default ? 0 : $ticket->reserved(),
1526
-            'TKT_registrations'             => $default
1527
-                ? 0
1528
-                : $ticket->count_registrations(
1529
-                    array(
1530
-                        array(
1531
-                            'STS_ID' => array(
1532
-                                '!=',
1533
-                                EEM_Registration::status_id_incomplete,
1534
-                            ),
1535
-                        ),
1536
-                    )
1537
-                ),
1538
-            'TKT_ID'                        => $default ? 0 : $ticket->ID(),
1539
-            'TKT_description'               => $default ? '' : $ticket->get_f('TKT_description'),
1540
-            'TKT_is_default'                => $default ? 0 : $ticket->is_default(),
1541
-            'TKT_required'                  => $default ? 0 : $ticket->required(),
1542
-            'TKT_is_default_selector'       => '',
1543
-            'ticket_price_rows'             => '',
1544
-            'TKT_base_price'                => $default || ! $base_price instanceof EE_Price
1545
-                ? ''
1546
-                : $base_price->get_pretty('PRC_amount', 'localized_float'),
1547
-            'TKT_base_price_ID'             => $default || ! $base_price instanceof EE_Price ? 0 : $base_price->ID(),
1548
-            'show_price_modifier'           => count($prices) > 1 || ($default && $count_price_mods > 0)
1549
-                ? ''
1550
-                : ' style="display:none;"',
1551
-            'show_price_mod_button'         => count($prices) > 1
1552
-                                               || ($default && $count_price_mods > 0)
1553
-                                               || (! $default && $ticket->deleted())
1554
-                ? ' style="display:none;"'
1555
-                : '',
1556
-            'total_price_rows'              => count($prices) > 1 ? count($prices) : 1,
1557
-            'ticket_datetimes_list'         => $default ? '<li class="hidden"></li>' : '',
1558
-            'starting_ticket_datetime_rows' => $default || $default_dtt ? '' : implode(',', $tkt_datetimes),
1559
-            'ticket_datetime_rows'          => $default ? '' : implode(',', $tkt_datetimes),
1560
-            'existing_ticket_price_ids'     => $default ? '' : implode(',', array_keys($prices)),
1561
-            'ticket_template_id'            => $default ? 0 : $ticket->get('TTM_ID'),
1562
-            'TKT_taxable'                   => $TKT_taxable,
1563
-            'display_subtotal'              => $ticket instanceof EE_Ticket && $ticket->taxable()
1564
-                ? ''
1565
-                : ' style="display:none"',
1566
-            'price_currency_symbol'         => EE_Registry::instance()->CFG->currency->sign,
1567
-            'TKT_subtotal_amount_display'   => EEH_Template::format_currency(
1568
-                $ticket_subtotal,
1569
-                false,
1570
-                false
1571
-            ),
1572
-            'TKT_subtotal_amount'           => $ticket_subtotal,
1573
-            'tax_rows'                      => $this->_get_tax_rows($ticket_row, $ticket),
1574
-            'disabled'                      => $ticket instanceof EE_Ticket && $ticket->deleted(),
1575
-            'ticket_archive_class'          => $ticket instanceof EE_Ticket && $ticket->deleted()
1576
-                ? ' ticket-archived'
1577
-                : '',
1578
-            'trash_icon'                    => $ticket instanceof EE_Ticket
1579
-                                               && $ticket->deleted()
1580
-                                               && ! $ticket->is_permanently_deleteable()
1581
-                ? 'ee-lock-icon '
1582
-                : 'trash-icon dashicons dashicons-post-trash clickable',
1583
-            'clone_icon'                    => $ticket instanceof EE_Ticket && $ticket->deleted()
1584
-                ? ''
1585
-                : 'clone-icon ee-icon ee-icon-clone clickable',
1586
-        );
1587
-        $template_args['trash_hidden'] = count($all_tickets) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1588
-            ? ' style="display:none"'
1589
-            : '';
1590
-        // handle rows that should NOT be empty
1591
-        if (empty($template_args['TKT_start_date'])) {
1592
-            // if empty then the start date will be now.
1593
-            $template_args['TKT_start_date'] = date(
1594
-                $this->_date_time_format,
1595
-                current_time('timestamp')
1596
-            );
1597
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1598
-        }
1599
-        if (empty($template_args['TKT_end_date'])) {
1600
-            // get the earliest datetime (if present);
1601
-            $earliest_dtt = $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0
1602
-                ? $this->_adminpage_obj->get_cpt_model_obj()->get_first_related(
1603
-                    'Datetime',
1604
-                    array('order_by' => array('DTT_EVT_start' => 'ASC'))
1605
-                )
1606
-                : null;
1607
-            if (! empty($earliest_dtt)) {
1608
-                $template_args['TKT_end_date'] = $earliest_dtt->get_datetime(
1609
-                    'DTT_EVT_start',
1610
-                    $this->_date_time_format
1611
-                );
1612
-            } else {
1613
-                // default so let's just use what's been set for the default date-time which is 30 days from now.
1614
-                $template_args['TKT_end_date'] = date(
1615
-                    $this->_date_time_format,
1616
-                    mktime(
1617
-                        24,
1618
-                        0,
1619
-                        0,
1620
-                        date('m'),
1621
-                        date('d') + 29,
1622
-                        date('Y')
1623
-                    )
1624
-                );
1625
-            }
1626
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1627
-        }
1628
-        // generate ticket_datetime items
1629
-        if (! $default) {
1630
-            $datetime_row = 1;
1631
-            foreach ($all_datetimes as $datetime) {
1632
-                $template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
1633
-                    $datetime_row,
1634
-                    $ticket_row,
1635
-                    $datetime,
1636
-                    $ticket,
1637
-                    $ticket_datetimes,
1638
-                    $default
1639
-                );
1640
-                $datetime_row++;
1641
-            }
1642
-        }
1643
-        $price_row = 1;
1644
-        foreach ($prices as $price) {
1645
-            if (! $price instanceof EE_Price) {
1646
-                continue;
1647
-            }
1648
-            if ($price->is_base_price()) {
1649
-                $price_row++;
1650
-                continue;
1651
-            }
1652
-            $show_trash = ! ((count($prices) > 1 && $price_row === 1) || count($prices) === 1);
1653
-            $show_create = ! (count($prices) > 1 && count($prices) !== $price_row);
1654
-            $template_args['ticket_price_rows'] .= $this->_get_ticket_price_row(
1655
-                $ticket_row,
1656
-                $price_row,
1657
-                $price,
1658
-                $default,
1659
-                $ticket,
1660
-                $show_trash,
1661
-                $show_create
1662
-            );
1663
-            $price_row++;
1664
-        }
1665
-        // filter $template_args
1666
-        $template_args = apply_filters(
1667
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_row__template_args',
1668
-            $template_args,
1669
-            $ticket_row,
1670
-            $ticket,
1671
-            $ticket_datetimes,
1672
-            $all_datetimes,
1673
-            $default,
1674
-            $all_tickets,
1675
-            $this->_is_creating_event
1676
-        );
1677
-        return EEH_Template::display_template(
1678
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php',
1679
-            $template_args,
1680
-            true
1681
-        );
1682
-    }
1400
+	/**
1401
+	 * This generates the ticket row for tickets.
1402
+	 * This same method is used to generate both the actual rows and the js skeleton row
1403
+	 * (when default === true)
1404
+	 *
1405
+	 * @param int           $ticket_row       Represents the row number being generated.
1406
+	 * @param               $ticket
1407
+	 * @param EE_Datetime[] $ticket_datetimes Either an array of all datetimes on all tickets indexed by each ticket
1408
+	 *                                        or empty for default
1409
+	 * @param EE_Datetime[] $all_datetimes    All Datetimes on the event or empty for default.
1410
+	 * @param bool          $default          Whether default row being generated or not.
1411
+	 * @param EE_Ticket[]   $all_tickets      This is an array of all tickets attached to the event
1412
+	 *                                        (or empty in the case of defaults)
1413
+	 * @return mixed
1414
+	 * @throws InvalidArgumentException
1415
+	 * @throws InvalidInterfaceException
1416
+	 * @throws InvalidDataTypeException
1417
+	 * @throws DomainException
1418
+	 * @throws EE_Error
1419
+	 * @throws ReflectionException
1420
+	 */
1421
+	protected function _get_ticket_row(
1422
+		$ticket_row,
1423
+		$ticket,
1424
+		$ticket_datetimes,
1425
+		$all_datetimes,
1426
+		$default = false,
1427
+		$all_tickets = array()
1428
+	) {
1429
+		// if $ticket is not an instance of EE_Ticket then force default to true.
1430
+		$default = ! $ticket instanceof EE_Ticket ? true : $default;
1431
+		$prices = ! empty($ticket) && ! $default
1432
+			? $ticket->get_many_related(
1433
+				'Price',
1434
+				array('default_where_conditions' => 'none', 'order_by' => array('PRC_order' => 'ASC'))
1435
+			)
1436
+			: array();
1437
+		// if there is only one price (which would be the base price)
1438
+		// or NO prices and this ticket is a default ticket,
1439
+		// let's just make sure there are no cached default prices on the object.
1440
+		// This is done by not including any query_params.
1441
+		if ($ticket instanceof EE_Ticket && $ticket->is_default() && (count($prices) === 1 || empty($prices))) {
1442
+			$prices = $ticket->prices();
1443
+		}
1444
+		// check if we're dealing with a default ticket in which case
1445
+		// we don't want any starting_ticket_datetime_row values set
1446
+		// (otherwise there won't be any new relationships created for tickets based off of the default ticket).
1447
+		// This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1448
+		$default_dtt = $default || ($ticket instanceof EE_Ticket && $ticket->is_default());
1449
+		$tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
1450
+			? $ticket_datetimes[ $ticket->ID() ]
1451
+			: array();
1452
+		$ticket_subtotal = $default ? 0 : $ticket->get_ticket_subtotal();
1453
+		$base_price = $default ? null : $ticket->base_price();
1454
+		$count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1455
+		// breaking out complicated condition for ticket_status
1456
+		if ($default) {
1457
+			$ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1458
+		} else {
1459
+			$ticket_status_class = $ticket->is_default()
1460
+				? ' tkt-status-' . EE_Ticket::onsale
1461
+				: ' tkt-status-' . $ticket->ticket_status();
1462
+		}
1463
+		// breaking out complicated condition for TKT_taxable
1464
+		if ($default) {
1465
+			$TKT_taxable = '';
1466
+		} else {
1467
+			$TKT_taxable = $ticket->taxable()
1468
+				? ' checked="checked"'
1469
+				: '';
1470
+		}
1471
+		if ($default) {
1472
+			$TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1473
+		} elseif ($ticket->is_default()) {
1474
+			$TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1475
+		} else {
1476
+			$TKT_status = $ticket->ticket_status(true);
1477
+		}
1478
+		if ($default) {
1479
+			$TKT_min = '';
1480
+		} else {
1481
+			$TKT_min = $ticket->min();
1482
+			if ($TKT_min === -1 || $TKT_min === 0) {
1483
+				$TKT_min = '';
1484
+			}
1485
+		}
1486
+		$template_args = array(
1487
+			'tkt_row'                       => $default ? 'TICKETNUM' : $ticket_row,
1488
+			'TKT_order'                     => $default ? 'TICKETNUM' : $ticket_row,
1489
+			// on initial page load this will always be the correct order.
1490
+			'tkt_status_class'              => $ticket_status_class,
1491
+			'display_edit_tkt_row'          => ' style="display:none;"',
1492
+			'edit_tkt_expanded'             => '',
1493
+			'edit_tickets_name'             => $default ? 'TICKETNAMEATTR' : 'edit_tickets',
1494
+			'TKT_name'                      => $default ? '' : $ticket->get_f('TKT_name'),
1495
+			'TKT_start_date'                => $default
1496
+				? ''
1497
+				: $ticket->get_date('TKT_start_date', $this->_date_time_format),
1498
+			'TKT_end_date'                  => $default
1499
+				? ''
1500
+				: $ticket->get_date('TKT_end_date', $this->_date_time_format),
1501
+			'TKT_status'                    => $TKT_status,
1502
+			'TKT_price'                     => $default
1503
+				? ''
1504
+				: EEH_Template::format_currency(
1505
+					$ticket->get_ticket_total_with_taxes(),
1506
+					false,
1507
+					false
1508
+				),
1509
+			'TKT_price_code'                => EE_Registry::instance()->CFG->currency->code,
1510
+			'TKT_price_amount'              => $default ? 0 : $ticket_subtotal,
1511
+			'TKT_qty'                       => $default
1512
+				? ''
1513
+				: $ticket->get_pretty('TKT_qty', 'symbol'),
1514
+			'TKT_qty_for_input'             => $default
1515
+				? ''
1516
+				: $ticket->get_pretty('TKT_qty', 'input'),
1517
+			'TKT_uses'                      => $default
1518
+				? ''
1519
+				: $ticket->get_pretty('TKT_uses', 'input'),
1520
+			'TKT_min'                       => $TKT_min,
1521
+			'TKT_max'                       => $default
1522
+				? ''
1523
+				: $ticket->get_pretty('TKT_max', 'input'),
1524
+			'TKT_sold'                      => $default ? 0 : $ticket->tickets_sold('ticket'),
1525
+			'TKT_reserved'                  => $default ? 0 : $ticket->reserved(),
1526
+			'TKT_registrations'             => $default
1527
+				? 0
1528
+				: $ticket->count_registrations(
1529
+					array(
1530
+						array(
1531
+							'STS_ID' => array(
1532
+								'!=',
1533
+								EEM_Registration::status_id_incomplete,
1534
+							),
1535
+						),
1536
+					)
1537
+				),
1538
+			'TKT_ID'                        => $default ? 0 : $ticket->ID(),
1539
+			'TKT_description'               => $default ? '' : $ticket->get_f('TKT_description'),
1540
+			'TKT_is_default'                => $default ? 0 : $ticket->is_default(),
1541
+			'TKT_required'                  => $default ? 0 : $ticket->required(),
1542
+			'TKT_is_default_selector'       => '',
1543
+			'ticket_price_rows'             => '',
1544
+			'TKT_base_price'                => $default || ! $base_price instanceof EE_Price
1545
+				? ''
1546
+				: $base_price->get_pretty('PRC_amount', 'localized_float'),
1547
+			'TKT_base_price_ID'             => $default || ! $base_price instanceof EE_Price ? 0 : $base_price->ID(),
1548
+			'show_price_modifier'           => count($prices) > 1 || ($default && $count_price_mods > 0)
1549
+				? ''
1550
+				: ' style="display:none;"',
1551
+			'show_price_mod_button'         => count($prices) > 1
1552
+											   || ($default && $count_price_mods > 0)
1553
+											   || (! $default && $ticket->deleted())
1554
+				? ' style="display:none;"'
1555
+				: '',
1556
+			'total_price_rows'              => count($prices) > 1 ? count($prices) : 1,
1557
+			'ticket_datetimes_list'         => $default ? '<li class="hidden"></li>' : '',
1558
+			'starting_ticket_datetime_rows' => $default || $default_dtt ? '' : implode(',', $tkt_datetimes),
1559
+			'ticket_datetime_rows'          => $default ? '' : implode(',', $tkt_datetimes),
1560
+			'existing_ticket_price_ids'     => $default ? '' : implode(',', array_keys($prices)),
1561
+			'ticket_template_id'            => $default ? 0 : $ticket->get('TTM_ID'),
1562
+			'TKT_taxable'                   => $TKT_taxable,
1563
+			'display_subtotal'              => $ticket instanceof EE_Ticket && $ticket->taxable()
1564
+				? ''
1565
+				: ' style="display:none"',
1566
+			'price_currency_symbol'         => EE_Registry::instance()->CFG->currency->sign,
1567
+			'TKT_subtotal_amount_display'   => EEH_Template::format_currency(
1568
+				$ticket_subtotal,
1569
+				false,
1570
+				false
1571
+			),
1572
+			'TKT_subtotal_amount'           => $ticket_subtotal,
1573
+			'tax_rows'                      => $this->_get_tax_rows($ticket_row, $ticket),
1574
+			'disabled'                      => $ticket instanceof EE_Ticket && $ticket->deleted(),
1575
+			'ticket_archive_class'          => $ticket instanceof EE_Ticket && $ticket->deleted()
1576
+				? ' ticket-archived'
1577
+				: '',
1578
+			'trash_icon'                    => $ticket instanceof EE_Ticket
1579
+											   && $ticket->deleted()
1580
+											   && ! $ticket->is_permanently_deleteable()
1581
+				? 'ee-lock-icon '
1582
+				: 'trash-icon dashicons dashicons-post-trash clickable',
1583
+			'clone_icon'                    => $ticket instanceof EE_Ticket && $ticket->deleted()
1584
+				? ''
1585
+				: 'clone-icon ee-icon ee-icon-clone clickable',
1586
+		);
1587
+		$template_args['trash_hidden'] = count($all_tickets) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1588
+			? ' style="display:none"'
1589
+			: '';
1590
+		// handle rows that should NOT be empty
1591
+		if (empty($template_args['TKT_start_date'])) {
1592
+			// if empty then the start date will be now.
1593
+			$template_args['TKT_start_date'] = date(
1594
+				$this->_date_time_format,
1595
+				current_time('timestamp')
1596
+			);
1597
+			$template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1598
+		}
1599
+		if (empty($template_args['TKT_end_date'])) {
1600
+			// get the earliest datetime (if present);
1601
+			$earliest_dtt = $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0
1602
+				? $this->_adminpage_obj->get_cpt_model_obj()->get_first_related(
1603
+					'Datetime',
1604
+					array('order_by' => array('DTT_EVT_start' => 'ASC'))
1605
+				)
1606
+				: null;
1607
+			if (! empty($earliest_dtt)) {
1608
+				$template_args['TKT_end_date'] = $earliest_dtt->get_datetime(
1609
+					'DTT_EVT_start',
1610
+					$this->_date_time_format
1611
+				);
1612
+			} else {
1613
+				// default so let's just use what's been set for the default date-time which is 30 days from now.
1614
+				$template_args['TKT_end_date'] = date(
1615
+					$this->_date_time_format,
1616
+					mktime(
1617
+						24,
1618
+						0,
1619
+						0,
1620
+						date('m'),
1621
+						date('d') + 29,
1622
+						date('Y')
1623
+					)
1624
+				);
1625
+			}
1626
+			$template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1627
+		}
1628
+		// generate ticket_datetime items
1629
+		if (! $default) {
1630
+			$datetime_row = 1;
1631
+			foreach ($all_datetimes as $datetime) {
1632
+				$template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
1633
+					$datetime_row,
1634
+					$ticket_row,
1635
+					$datetime,
1636
+					$ticket,
1637
+					$ticket_datetimes,
1638
+					$default
1639
+				);
1640
+				$datetime_row++;
1641
+			}
1642
+		}
1643
+		$price_row = 1;
1644
+		foreach ($prices as $price) {
1645
+			if (! $price instanceof EE_Price) {
1646
+				continue;
1647
+			}
1648
+			if ($price->is_base_price()) {
1649
+				$price_row++;
1650
+				continue;
1651
+			}
1652
+			$show_trash = ! ((count($prices) > 1 && $price_row === 1) || count($prices) === 1);
1653
+			$show_create = ! (count($prices) > 1 && count($prices) !== $price_row);
1654
+			$template_args['ticket_price_rows'] .= $this->_get_ticket_price_row(
1655
+				$ticket_row,
1656
+				$price_row,
1657
+				$price,
1658
+				$default,
1659
+				$ticket,
1660
+				$show_trash,
1661
+				$show_create
1662
+			);
1663
+			$price_row++;
1664
+		}
1665
+		// filter $template_args
1666
+		$template_args = apply_filters(
1667
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_row__template_args',
1668
+			$template_args,
1669
+			$ticket_row,
1670
+			$ticket,
1671
+			$ticket_datetimes,
1672
+			$all_datetimes,
1673
+			$default,
1674
+			$all_tickets,
1675
+			$this->_is_creating_event
1676
+		);
1677
+		return EEH_Template::display_template(
1678
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php',
1679
+			$template_args,
1680
+			true
1681
+		);
1682
+	}
1683 1683
 
1684 1684
 
1685
-    /**
1686
-     * @param int            $ticket_row
1687
-     * @param EE_Ticket|null $ticket
1688
-     * @return string
1689
-     * @throws DomainException
1690
-     * @throws EE_Error
1691
-     */
1692
-    protected function _get_tax_rows($ticket_row, $ticket)
1693
-    {
1694
-        $tax_rows = '';
1695
-        /** @var EE_Price[] $taxes */
1696
-        $taxes = empty($ticket) ? EE_Taxes::get_taxes_for_admin() : $ticket->get_ticket_taxes_for_admin();
1697
-        foreach ($taxes as $tax) {
1698
-            $tax_added = $this->_get_tax_added($tax, $ticket);
1699
-            $template_args = array(
1700
-                'display_tax'       => ! empty($ticket) && $ticket->get('TKT_taxable')
1701
-                    ? ''
1702
-                    : ' style="display:none;"',
1703
-                'tax_id'            => $tax->ID(),
1704
-                'tkt_row'           => $ticket_row,
1705
-                'tax_label'         => $tax->get('PRC_name'),
1706
-                'tax_added'         => $tax_added,
1707
-                'tax_added_display' => EEH_Template::format_currency($tax_added, false, false),
1708
-                'tax_amount'        => $tax->get('PRC_amount'),
1709
-            );
1710
-            $template_args = apply_filters(
1711
-                'FHEE__espresso_events_Pricing_Hooks___get_tax_rows__template_args',
1712
-                $template_args,
1713
-                $ticket_row,
1714
-                $ticket,
1715
-                $this->_is_creating_event
1716
-            );
1717
-            $tax_rows .= EEH_Template::display_template(
1718
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php',
1719
-                $template_args,
1720
-                true
1721
-            );
1722
-        }
1723
-        return $tax_rows;
1724
-    }
1685
+	/**
1686
+	 * @param int            $ticket_row
1687
+	 * @param EE_Ticket|null $ticket
1688
+	 * @return string
1689
+	 * @throws DomainException
1690
+	 * @throws EE_Error
1691
+	 */
1692
+	protected function _get_tax_rows($ticket_row, $ticket)
1693
+	{
1694
+		$tax_rows = '';
1695
+		/** @var EE_Price[] $taxes */
1696
+		$taxes = empty($ticket) ? EE_Taxes::get_taxes_for_admin() : $ticket->get_ticket_taxes_for_admin();
1697
+		foreach ($taxes as $tax) {
1698
+			$tax_added = $this->_get_tax_added($tax, $ticket);
1699
+			$template_args = array(
1700
+				'display_tax'       => ! empty($ticket) && $ticket->get('TKT_taxable')
1701
+					? ''
1702
+					: ' style="display:none;"',
1703
+				'tax_id'            => $tax->ID(),
1704
+				'tkt_row'           => $ticket_row,
1705
+				'tax_label'         => $tax->get('PRC_name'),
1706
+				'tax_added'         => $tax_added,
1707
+				'tax_added_display' => EEH_Template::format_currency($tax_added, false, false),
1708
+				'tax_amount'        => $tax->get('PRC_amount'),
1709
+			);
1710
+			$template_args = apply_filters(
1711
+				'FHEE__espresso_events_Pricing_Hooks___get_tax_rows__template_args',
1712
+				$template_args,
1713
+				$ticket_row,
1714
+				$ticket,
1715
+				$this->_is_creating_event
1716
+			);
1717
+			$tax_rows .= EEH_Template::display_template(
1718
+				PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php',
1719
+				$template_args,
1720
+				true
1721
+			);
1722
+		}
1723
+		return $tax_rows;
1724
+	}
1725 1725
 
1726 1726
 
1727
-    /**
1728
-     * @param EE_Price       $tax
1729
-     * @param EE_Ticket|null $ticket
1730
-     * @return float|int
1731
-     * @throws EE_Error
1732
-     */
1733
-    protected function _get_tax_added(EE_Price $tax, $ticket)
1734
-    {
1735
-        $subtotal = empty($ticket) ? 0 : $ticket->get_ticket_subtotal();
1736
-        return $subtotal * $tax->get('PRC_amount') / 100;
1737
-    }
1727
+	/**
1728
+	 * @param EE_Price       $tax
1729
+	 * @param EE_Ticket|null $ticket
1730
+	 * @return float|int
1731
+	 * @throws EE_Error
1732
+	 */
1733
+	protected function _get_tax_added(EE_Price $tax, $ticket)
1734
+	{
1735
+		$subtotal = empty($ticket) ? 0 : $ticket->get_ticket_subtotal();
1736
+		return $subtotal * $tax->get('PRC_amount') / 100;
1737
+	}
1738 1738
 
1739 1739
 
1740
-    /**
1741
-     * @param int            $ticket_row
1742
-     * @param int            $price_row
1743
-     * @param EE_Price|null  $price
1744
-     * @param bool           $default
1745
-     * @param EE_Ticket|null $ticket
1746
-     * @param bool           $show_trash
1747
-     * @param bool           $show_create
1748
-     * @return mixed
1749
-     * @throws InvalidArgumentException
1750
-     * @throws InvalidInterfaceException
1751
-     * @throws InvalidDataTypeException
1752
-     * @throws DomainException
1753
-     * @throws EE_Error
1754
-     * @throws ReflectionException
1755
-     */
1756
-    protected function _get_ticket_price_row(
1757
-        $ticket_row,
1758
-        $price_row,
1759
-        $price,
1760
-        $default,
1761
-        $ticket,
1762
-        $show_trash = true,
1763
-        $show_create = true
1764
-    ) {
1765
-        $send_disabled = ! empty($ticket) && $ticket->get('TKT_deleted');
1766
-        $template_args = array(
1767
-            'tkt_row'               => $default && empty($ticket)
1768
-                ? 'TICKETNUM'
1769
-                : $ticket_row,
1770
-            'PRC_order'             => $default && empty($price)
1771
-                ? 'PRICENUM'
1772
-                : $price_row,
1773
-            'edit_prices_name'      => $default && empty($price)
1774
-                ? 'PRICENAMEATTR'
1775
-                : 'edit_prices',
1776
-            'price_type_selector'   => $default && empty($price)
1777
-                ? $this->_get_base_price_template($ticket_row, $price_row, $price, $default)
1778
-                : $this->_get_price_type_selector(
1779
-                    $ticket_row,
1780
-                    $price_row,
1781
-                    $price,
1782
-                    $default,
1783
-                    $send_disabled
1784
-                ),
1785
-            'PRC_ID'                => $default && empty($price)
1786
-                ? 0
1787
-                : $price->ID(),
1788
-            'PRC_is_default'        => $default && empty($price)
1789
-                ? 0
1790
-                : $price->get('PRC_is_default'),
1791
-            'PRC_name'              => $default && empty($price)
1792
-                ? ''
1793
-                : $price->get('PRC_name'),
1794
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1795
-            'show_plus_or_minus'    => $default && empty($price)
1796
-                ? ''
1797
-                : ' style="display:none;"',
1798
-            'show_plus'             => ($default && empty($price)) || ($price->is_discount() || $price->is_base_price())
1799
-                ? ' style="display:none;"'
1800
-                : '',
1801
-            'show_minus'            => ($default && empty($price)) || ! $price->is_discount()
1802
-                ? ' style="display:none;"'
1803
-                : '',
1804
-            'show_currency_symbol'  => ($default && empty($price)) || $price->is_percent()
1805
-                ? ' style="display:none"'
1806
-                : '',
1807
-            'PRC_amount'            => $default && empty($price)
1808
-                ? 0
1809
-                : $price->get_pretty('PRC_amount', 'localized_float'),
1810
-            'show_percentage'       => ($default && empty($price)) || ! $price->is_percent()
1811
-                ? ' style="display:none;"'
1812
-                : '',
1813
-            'show_trash_icon'       => $show_trash
1814
-                ? ''
1815
-                : ' style="display:none;"',
1816
-            'show_create_button'    => $show_create
1817
-                ? ''
1818
-                : ' style="display:none;"',
1819
-            'PRC_desc'              => $default && empty($price)
1820
-                ? ''
1821
-                : $price->get('PRC_desc'),
1822
-            'disabled'              => ! empty($ticket) && $ticket->get('TKT_deleted'),
1823
-        );
1824
-        $template_args = apply_filters(
1825
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_price_row__template_args',
1826
-            $template_args,
1827
-            $ticket_row,
1828
-            $price_row,
1829
-            $price,
1830
-            $default,
1831
-            $ticket,
1832
-            $show_trash,
1833
-            $show_create,
1834
-            $this->_is_creating_event
1835
-        );
1836
-        return EEH_Template::display_template(
1837
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php',
1838
-            $template_args,
1839
-            true
1840
-        );
1841
-    }
1740
+	/**
1741
+	 * @param int            $ticket_row
1742
+	 * @param int            $price_row
1743
+	 * @param EE_Price|null  $price
1744
+	 * @param bool           $default
1745
+	 * @param EE_Ticket|null $ticket
1746
+	 * @param bool           $show_trash
1747
+	 * @param bool           $show_create
1748
+	 * @return mixed
1749
+	 * @throws InvalidArgumentException
1750
+	 * @throws InvalidInterfaceException
1751
+	 * @throws InvalidDataTypeException
1752
+	 * @throws DomainException
1753
+	 * @throws EE_Error
1754
+	 * @throws ReflectionException
1755
+	 */
1756
+	protected function _get_ticket_price_row(
1757
+		$ticket_row,
1758
+		$price_row,
1759
+		$price,
1760
+		$default,
1761
+		$ticket,
1762
+		$show_trash = true,
1763
+		$show_create = true
1764
+	) {
1765
+		$send_disabled = ! empty($ticket) && $ticket->get('TKT_deleted');
1766
+		$template_args = array(
1767
+			'tkt_row'               => $default && empty($ticket)
1768
+				? 'TICKETNUM'
1769
+				: $ticket_row,
1770
+			'PRC_order'             => $default && empty($price)
1771
+				? 'PRICENUM'
1772
+				: $price_row,
1773
+			'edit_prices_name'      => $default && empty($price)
1774
+				? 'PRICENAMEATTR'
1775
+				: 'edit_prices',
1776
+			'price_type_selector'   => $default && empty($price)
1777
+				? $this->_get_base_price_template($ticket_row, $price_row, $price, $default)
1778
+				: $this->_get_price_type_selector(
1779
+					$ticket_row,
1780
+					$price_row,
1781
+					$price,
1782
+					$default,
1783
+					$send_disabled
1784
+				),
1785
+			'PRC_ID'                => $default && empty($price)
1786
+				? 0
1787
+				: $price->ID(),
1788
+			'PRC_is_default'        => $default && empty($price)
1789
+				? 0
1790
+				: $price->get('PRC_is_default'),
1791
+			'PRC_name'              => $default && empty($price)
1792
+				? ''
1793
+				: $price->get('PRC_name'),
1794
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1795
+			'show_plus_or_minus'    => $default && empty($price)
1796
+				? ''
1797
+				: ' style="display:none;"',
1798
+			'show_plus'             => ($default && empty($price)) || ($price->is_discount() || $price->is_base_price())
1799
+				? ' style="display:none;"'
1800
+				: '',
1801
+			'show_minus'            => ($default && empty($price)) || ! $price->is_discount()
1802
+				? ' style="display:none;"'
1803
+				: '',
1804
+			'show_currency_symbol'  => ($default && empty($price)) || $price->is_percent()
1805
+				? ' style="display:none"'
1806
+				: '',
1807
+			'PRC_amount'            => $default && empty($price)
1808
+				? 0
1809
+				: $price->get_pretty('PRC_amount', 'localized_float'),
1810
+			'show_percentage'       => ($default && empty($price)) || ! $price->is_percent()
1811
+				? ' style="display:none;"'
1812
+				: '',
1813
+			'show_trash_icon'       => $show_trash
1814
+				? ''
1815
+				: ' style="display:none;"',
1816
+			'show_create_button'    => $show_create
1817
+				? ''
1818
+				: ' style="display:none;"',
1819
+			'PRC_desc'              => $default && empty($price)
1820
+				? ''
1821
+				: $price->get('PRC_desc'),
1822
+			'disabled'              => ! empty($ticket) && $ticket->get('TKT_deleted'),
1823
+		);
1824
+		$template_args = apply_filters(
1825
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_price_row__template_args',
1826
+			$template_args,
1827
+			$ticket_row,
1828
+			$price_row,
1829
+			$price,
1830
+			$default,
1831
+			$ticket,
1832
+			$show_trash,
1833
+			$show_create,
1834
+			$this->_is_creating_event
1835
+		);
1836
+		return EEH_Template::display_template(
1837
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php',
1838
+			$template_args,
1839
+			true
1840
+		);
1841
+	}
1842 1842
 
1843 1843
 
1844
-    /**
1845
-     * @param int      $ticket_row
1846
-     * @param int      $price_row
1847
-     * @param EE_Price $price
1848
-     * @param bool     $default
1849
-     * @param bool     $disabled
1850
-     * @return mixed
1851
-     * @throws ReflectionException
1852
-     * @throws InvalidArgumentException
1853
-     * @throws InvalidInterfaceException
1854
-     * @throws InvalidDataTypeException
1855
-     * @throws DomainException
1856
-     * @throws EE_Error
1857
-     */
1858
-    protected function _get_price_type_selector($ticket_row, $price_row, $price, $default, $disabled = false)
1859
-    {
1860
-        if ($price->is_base_price()) {
1861
-            return $this->_get_base_price_template(
1862
-                $ticket_row,
1863
-                $price_row,
1864
-                $price,
1865
-                $default
1866
-            );
1867
-        }
1868
-        return $this->_get_price_modifier_template(
1869
-            $ticket_row,
1870
-            $price_row,
1871
-            $price,
1872
-            $default,
1873
-            $disabled
1874
-        );
1875
-    }
1844
+	/**
1845
+	 * @param int      $ticket_row
1846
+	 * @param int      $price_row
1847
+	 * @param EE_Price $price
1848
+	 * @param bool     $default
1849
+	 * @param bool     $disabled
1850
+	 * @return mixed
1851
+	 * @throws ReflectionException
1852
+	 * @throws InvalidArgumentException
1853
+	 * @throws InvalidInterfaceException
1854
+	 * @throws InvalidDataTypeException
1855
+	 * @throws DomainException
1856
+	 * @throws EE_Error
1857
+	 */
1858
+	protected function _get_price_type_selector($ticket_row, $price_row, $price, $default, $disabled = false)
1859
+	{
1860
+		if ($price->is_base_price()) {
1861
+			return $this->_get_base_price_template(
1862
+				$ticket_row,
1863
+				$price_row,
1864
+				$price,
1865
+				$default
1866
+			);
1867
+		}
1868
+		return $this->_get_price_modifier_template(
1869
+			$ticket_row,
1870
+			$price_row,
1871
+			$price,
1872
+			$default,
1873
+			$disabled
1874
+		);
1875
+	}
1876 1876
 
1877 1877
 
1878
-    /**
1879
-     * @param int      $ticket_row
1880
-     * @param int      $price_row
1881
-     * @param EE_Price $price
1882
-     * @param bool     $default
1883
-     * @return mixed
1884
-     * @throws DomainException
1885
-     * @throws EE_Error
1886
-     */
1887
-    protected function _get_base_price_template($ticket_row, $price_row, $price, $default)
1888
-    {
1889
-        $template_args = array(
1890
-            'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1891
-            'PRC_order'                 => $default && empty($price) ? 'PRICENUM' : $price_row,
1892
-            'PRT_ID'                    => $default && empty($price) ? 1 : $price->get('PRT_ID'),
1893
-            'PRT_name'                  => esc_html__('Price', 'event_espresso'),
1894
-            'price_selected_operator'   => '+',
1895
-            'price_selected_is_percent' => 0,
1896
-        );
1897
-        $template_args = apply_filters(
1898
-            'FHEE__espresso_events_Pricing_Hooks___get_base_price_template__template_args',
1899
-            $template_args,
1900
-            $ticket_row,
1901
-            $price_row,
1902
-            $price,
1903
-            $default,
1904
-            $this->_is_creating_event
1905
-        );
1906
-        return EEH_Template::display_template(
1907
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php',
1908
-            $template_args,
1909
-            true
1910
-        );
1911
-    }
1878
+	/**
1879
+	 * @param int      $ticket_row
1880
+	 * @param int      $price_row
1881
+	 * @param EE_Price $price
1882
+	 * @param bool     $default
1883
+	 * @return mixed
1884
+	 * @throws DomainException
1885
+	 * @throws EE_Error
1886
+	 */
1887
+	protected function _get_base_price_template($ticket_row, $price_row, $price, $default)
1888
+	{
1889
+		$template_args = array(
1890
+			'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1891
+			'PRC_order'                 => $default && empty($price) ? 'PRICENUM' : $price_row,
1892
+			'PRT_ID'                    => $default && empty($price) ? 1 : $price->get('PRT_ID'),
1893
+			'PRT_name'                  => esc_html__('Price', 'event_espresso'),
1894
+			'price_selected_operator'   => '+',
1895
+			'price_selected_is_percent' => 0,
1896
+		);
1897
+		$template_args = apply_filters(
1898
+			'FHEE__espresso_events_Pricing_Hooks___get_base_price_template__template_args',
1899
+			$template_args,
1900
+			$ticket_row,
1901
+			$price_row,
1902
+			$price,
1903
+			$default,
1904
+			$this->_is_creating_event
1905
+		);
1906
+		return EEH_Template::display_template(
1907
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php',
1908
+			$template_args,
1909
+			true
1910
+		);
1911
+	}
1912 1912
 
1913 1913
 
1914
-    /**
1915
-     * @param int      $ticket_row
1916
-     * @param int      $price_row
1917
-     * @param EE_Price $price
1918
-     * @param bool     $default
1919
-     * @param bool     $disabled
1920
-     * @return mixed
1921
-     * @throws ReflectionException
1922
-     * @throws InvalidArgumentException
1923
-     * @throws InvalidInterfaceException
1924
-     * @throws InvalidDataTypeException
1925
-     * @throws DomainException
1926
-     * @throws EE_Error
1927
-     */
1928
-    protected function _get_price_modifier_template(
1929
-        $ticket_row,
1930
-        $price_row,
1931
-        $price,
1932
-        $default,
1933
-        $disabled = false
1934
-    ) {
1935
-        $select_name = $default && ! $price instanceof EE_Price
1936
-            ? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]'
1937
-            : 'edit_prices[' . $ticket_row . '][' . $price_row . '][PRT_ID]';
1938
-        /** @var EEM_Price_Type $price_type_model */
1939
-        $price_type_model = EE_Registry::instance()->load_model('Price_Type');
1940
-        $price_types = $price_type_model->get_all(array(
1941
-            array(
1942
-                'OR' => array(
1943
-                    'PBT_ID'  => '2',
1944
-                    'PBT_ID*' => '3',
1945
-                ),
1946
-            ),
1947
-        ));
1948
-        $all_price_types = $default && ! $price instanceof EE_Price
1949
-            ? array(esc_html__('Select Modifier', 'event_espresso'))
1950
-            : array();
1951
-        $selected_price_type_id = $default && ! $price instanceof EE_Price ? 0 : $price->type();
1952
-        $price_option_spans = '';
1953
-        // setup price types for selector
1954
-        foreach ($price_types as $price_type) {
1955
-            if (! $price_type instanceof EE_Price_Type) {
1956
-                continue;
1957
-            }
1958
-            $all_price_types[ $price_type->ID() ] = $price_type->get('PRT_name');
1959
-            // while we're in the loop let's setup the option spans used by js
1960
-            $span_args = array(
1961
-                'PRT_ID'         => $price_type->ID(),
1962
-                'PRT_operator'   => $price_type->is_discount() ? '-' : '+',
1963
-                'PRT_is_percent' => $price_type->get('PRT_is_percent') ? 1 : 0,
1964
-            );
1965
-            $price_option_spans .= EEH_Template::display_template(
1966
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php',
1967
-                $span_args,
1968
-                true
1969
-            );
1970
-        }
1971
-        $select_name = $disabled ? 'archive_price[' . $ticket_row . '][' . $price_row . '][PRT_ID]'
1972
-            : $select_name;
1973
-        $select_input = new EE_Select_Input(
1974
-            $all_price_types,
1975
-            array(
1976
-                'default'               => $selected_price_type_id,
1977
-                'html_name'             => $select_name,
1978
-                'html_class'            => 'edit-price-PRT_ID',
1979
-                'other_html_attributes' => $disabled ? 'style="width:auto;" disabled' : 'style="width:auto;"',
1980
-            )
1981
-        );
1982
-        $price_selected_operator = $price instanceof EE_Price && $price->is_discount() ? '-' : '+';
1983
-        $price_selected_operator = $default && ! $price instanceof EE_Price ? '' : $price_selected_operator;
1984
-        $price_selected_is_percent = $price instanceof EE_Price && $price->is_percent() ? 1 : 0;
1985
-        $price_selected_is_percent = $default && ! $price instanceof EE_Price ? '' : $price_selected_is_percent;
1986
-        $template_args = array(
1987
-            'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1988
-            'PRC_order'                 => $default && ! $price instanceof EE_Price ? 'PRICENUM' : $price_row,
1989
-            'price_modifier_selector'   => $select_input->get_html_for_input(),
1990
-            'main_name'                 => $select_name,
1991
-            'selected_price_type_id'    => $selected_price_type_id,
1992
-            'price_option_spans'        => $price_option_spans,
1993
-            'price_selected_operator'   => $price_selected_operator,
1994
-            'price_selected_is_percent' => $price_selected_is_percent,
1995
-            'disabled'                  => $disabled,
1996
-        );
1997
-        $template_args = apply_filters(
1998
-            'FHEE__espresso_events_Pricing_Hooks___get_price_modifier_template__template_args',
1999
-            $template_args,
2000
-            $ticket_row,
2001
-            $price_row,
2002
-            $price,
2003
-            $default,
2004
-            $disabled,
2005
-            $this->_is_creating_event
2006
-        );
2007
-        return EEH_Template::display_template(
2008
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php',
2009
-            $template_args,
2010
-            true
2011
-        );
2012
-    }
1914
+	/**
1915
+	 * @param int      $ticket_row
1916
+	 * @param int      $price_row
1917
+	 * @param EE_Price $price
1918
+	 * @param bool     $default
1919
+	 * @param bool     $disabled
1920
+	 * @return mixed
1921
+	 * @throws ReflectionException
1922
+	 * @throws InvalidArgumentException
1923
+	 * @throws InvalidInterfaceException
1924
+	 * @throws InvalidDataTypeException
1925
+	 * @throws DomainException
1926
+	 * @throws EE_Error
1927
+	 */
1928
+	protected function _get_price_modifier_template(
1929
+		$ticket_row,
1930
+		$price_row,
1931
+		$price,
1932
+		$default,
1933
+		$disabled = false
1934
+	) {
1935
+		$select_name = $default && ! $price instanceof EE_Price
1936
+			? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]'
1937
+			: 'edit_prices[' . $ticket_row . '][' . $price_row . '][PRT_ID]';
1938
+		/** @var EEM_Price_Type $price_type_model */
1939
+		$price_type_model = EE_Registry::instance()->load_model('Price_Type');
1940
+		$price_types = $price_type_model->get_all(array(
1941
+			array(
1942
+				'OR' => array(
1943
+					'PBT_ID'  => '2',
1944
+					'PBT_ID*' => '3',
1945
+				),
1946
+			),
1947
+		));
1948
+		$all_price_types = $default && ! $price instanceof EE_Price
1949
+			? array(esc_html__('Select Modifier', 'event_espresso'))
1950
+			: array();
1951
+		$selected_price_type_id = $default && ! $price instanceof EE_Price ? 0 : $price->type();
1952
+		$price_option_spans = '';
1953
+		// setup price types for selector
1954
+		foreach ($price_types as $price_type) {
1955
+			if (! $price_type instanceof EE_Price_Type) {
1956
+				continue;
1957
+			}
1958
+			$all_price_types[ $price_type->ID() ] = $price_type->get('PRT_name');
1959
+			// while we're in the loop let's setup the option spans used by js
1960
+			$span_args = array(
1961
+				'PRT_ID'         => $price_type->ID(),
1962
+				'PRT_operator'   => $price_type->is_discount() ? '-' : '+',
1963
+				'PRT_is_percent' => $price_type->get('PRT_is_percent') ? 1 : 0,
1964
+			);
1965
+			$price_option_spans .= EEH_Template::display_template(
1966
+				PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php',
1967
+				$span_args,
1968
+				true
1969
+			);
1970
+		}
1971
+		$select_name = $disabled ? 'archive_price[' . $ticket_row . '][' . $price_row . '][PRT_ID]'
1972
+			: $select_name;
1973
+		$select_input = new EE_Select_Input(
1974
+			$all_price_types,
1975
+			array(
1976
+				'default'               => $selected_price_type_id,
1977
+				'html_name'             => $select_name,
1978
+				'html_class'            => 'edit-price-PRT_ID',
1979
+				'other_html_attributes' => $disabled ? 'style="width:auto;" disabled' : 'style="width:auto;"',
1980
+			)
1981
+		);
1982
+		$price_selected_operator = $price instanceof EE_Price && $price->is_discount() ? '-' : '+';
1983
+		$price_selected_operator = $default && ! $price instanceof EE_Price ? '' : $price_selected_operator;
1984
+		$price_selected_is_percent = $price instanceof EE_Price && $price->is_percent() ? 1 : 0;
1985
+		$price_selected_is_percent = $default && ! $price instanceof EE_Price ? '' : $price_selected_is_percent;
1986
+		$template_args = array(
1987
+			'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1988
+			'PRC_order'                 => $default && ! $price instanceof EE_Price ? 'PRICENUM' : $price_row,
1989
+			'price_modifier_selector'   => $select_input->get_html_for_input(),
1990
+			'main_name'                 => $select_name,
1991
+			'selected_price_type_id'    => $selected_price_type_id,
1992
+			'price_option_spans'        => $price_option_spans,
1993
+			'price_selected_operator'   => $price_selected_operator,
1994
+			'price_selected_is_percent' => $price_selected_is_percent,
1995
+			'disabled'                  => $disabled,
1996
+		);
1997
+		$template_args = apply_filters(
1998
+			'FHEE__espresso_events_Pricing_Hooks___get_price_modifier_template__template_args',
1999
+			$template_args,
2000
+			$ticket_row,
2001
+			$price_row,
2002
+			$price,
2003
+			$default,
2004
+			$disabled,
2005
+			$this->_is_creating_event
2006
+		);
2007
+		return EEH_Template::display_template(
2008
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php',
2009
+			$template_args,
2010
+			true
2011
+		);
2012
+	}
2013 2013
 
2014 2014
 
2015
-    /**
2016
-     * @param int              $datetime_row
2017
-     * @param int              $ticket_row
2018
-     * @param EE_Datetime|null $datetime
2019
-     * @param EE_Ticket|null   $ticket
2020
-     * @param array            $ticket_datetimes
2021
-     * @param bool             $default
2022
-     * @return mixed
2023
-     * @throws DomainException
2024
-     * @throws EE_Error
2025
-     */
2026
-    protected function _get_ticket_datetime_list_item(
2027
-        $datetime_row,
2028
-        $ticket_row,
2029
-        $datetime,
2030
-        $ticket,
2031
-        $ticket_datetimes = array(),
2032
-        $default
2033
-    ) {
2034
-        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
2035
-            ? $ticket_datetimes[ $ticket->ID() ]
2036
-            : array();
2037
-        $template_args = array(
2038
-            'dtt_row'                  => $default && ! $datetime instanceof EE_Datetime
2039
-                ? 'DTTNUM'
2040
-                : $datetime_row,
2041
-            'tkt_row'                  => $default
2042
-                ? 'TICKETNUM'
2043
-                : $ticket_row,
2044
-            'ticket_datetime_selected' => in_array($datetime_row, $tkt_datetimes, true)
2045
-                ? ' ticket-selected'
2046
-                : '',
2047
-            'ticket_datetime_checked'  => in_array($datetime_row, $tkt_datetimes, true)
2048
-                ? ' checked="checked"'
2049
-                : '',
2050
-            'DTT_name'                 => $default && empty($datetime)
2051
-                ? 'DTTNAME'
2052
-                : $datetime->get_dtt_display_name(true),
2053
-            'tkt_status_class'         => '',
2054
-        );
2055
-        $template_args = apply_filters(
2056
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_datetime_list_item__template_args',
2057
-            $template_args,
2058
-            $datetime_row,
2059
-            $ticket_row,
2060
-            $datetime,
2061
-            $ticket,
2062
-            $ticket_datetimes,
2063
-            $default,
2064
-            $this->_is_creating_event
2065
-        );
2066
-        return EEH_Template::display_template(
2067
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php',
2068
-            $template_args,
2069
-            true
2070
-        );
2071
-    }
2015
+	/**
2016
+	 * @param int              $datetime_row
2017
+	 * @param int              $ticket_row
2018
+	 * @param EE_Datetime|null $datetime
2019
+	 * @param EE_Ticket|null   $ticket
2020
+	 * @param array            $ticket_datetimes
2021
+	 * @param bool             $default
2022
+	 * @return mixed
2023
+	 * @throws DomainException
2024
+	 * @throws EE_Error
2025
+	 */
2026
+	protected function _get_ticket_datetime_list_item(
2027
+		$datetime_row,
2028
+		$ticket_row,
2029
+		$datetime,
2030
+		$ticket,
2031
+		$ticket_datetimes = array(),
2032
+		$default
2033
+	) {
2034
+		$tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
2035
+			? $ticket_datetimes[ $ticket->ID() ]
2036
+			: array();
2037
+		$template_args = array(
2038
+			'dtt_row'                  => $default && ! $datetime instanceof EE_Datetime
2039
+				? 'DTTNUM'
2040
+				: $datetime_row,
2041
+			'tkt_row'                  => $default
2042
+				? 'TICKETNUM'
2043
+				: $ticket_row,
2044
+			'ticket_datetime_selected' => in_array($datetime_row, $tkt_datetimes, true)
2045
+				? ' ticket-selected'
2046
+				: '',
2047
+			'ticket_datetime_checked'  => in_array($datetime_row, $tkt_datetimes, true)
2048
+				? ' checked="checked"'
2049
+				: '',
2050
+			'DTT_name'                 => $default && empty($datetime)
2051
+				? 'DTTNAME'
2052
+				: $datetime->get_dtt_display_name(true),
2053
+			'tkt_status_class'         => '',
2054
+		);
2055
+		$template_args = apply_filters(
2056
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_datetime_list_item__template_args',
2057
+			$template_args,
2058
+			$datetime_row,
2059
+			$ticket_row,
2060
+			$datetime,
2061
+			$ticket,
2062
+			$ticket_datetimes,
2063
+			$default,
2064
+			$this->_is_creating_event
2065
+		);
2066
+		return EEH_Template::display_template(
2067
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php',
2068
+			$template_args,
2069
+			true
2070
+		);
2071
+	}
2072 2072
 
2073 2073
 
2074
-    /**
2075
-     * @param array $all_datetimes
2076
-     * @param array $all_tickets
2077
-     * @return mixed
2078
-     * @throws ReflectionException
2079
-     * @throws InvalidArgumentException
2080
-     * @throws InvalidInterfaceException
2081
-     * @throws InvalidDataTypeException
2082
-     * @throws DomainException
2083
-     * @throws EE_Error
2084
-     */
2085
-    protected function _get_ticket_js_structure($all_datetimes = array(), $all_tickets = array())
2086
-    {
2087
-        $template_args = array(
2088
-            'default_datetime_edit_row'                => $this->_get_dtt_edit_row(
2089
-                'DTTNUM',
2090
-                null,
2091
-                true,
2092
-                $all_datetimes
2093
-            ),
2094
-            'default_ticket_row'                       => $this->_get_ticket_row(
2095
-                'TICKETNUM',
2096
-                null,
2097
-                array(),
2098
-                array(),
2099
-                true
2100
-            ),
2101
-            'default_price_row'                        => $this->_get_ticket_price_row(
2102
-                'TICKETNUM',
2103
-                'PRICENUM',
2104
-                null,
2105
-                true,
2106
-                null
2107
-            ),
2108
-            'default_price_rows'                       => '',
2109
-            'default_base_price_amount'                => 0,
2110
-            'default_base_price_name'                  => '',
2111
-            'default_base_price_description'           => '',
2112
-            'default_price_modifier_selector_row'      => $this->_get_price_modifier_template(
2113
-                'TICKETNUM',
2114
-                'PRICENUM',
2115
-                null,
2116
-                true
2117
-            ),
2118
-            'default_available_tickets_for_datetime'   => $this->_get_dtt_attached_tickets_row(
2119
-                'DTTNUM',
2120
-                null,
2121
-                array(),
2122
-                array(),
2123
-                true
2124
-            ),
2125
-            'existing_available_datetime_tickets_list' => '',
2126
-            'existing_available_ticket_datetimes_list' => '',
2127
-            'new_available_datetime_ticket_list_item'  => $this->_get_datetime_tickets_list_item(
2128
-                'DTTNUM',
2129
-                'TICKETNUM',
2130
-                null,
2131
-                null,
2132
-                array(),
2133
-                true
2134
-            ),
2135
-            'new_available_ticket_datetime_list_item'  => $this->_get_ticket_datetime_list_item(
2136
-                'DTTNUM',
2137
-                'TICKETNUM',
2138
-                null,
2139
-                null,
2140
-                array(),
2141
-                true
2142
-            ),
2143
-        );
2144
-        $ticket_row = 1;
2145
-        foreach ($all_tickets as $ticket) {
2146
-            $template_args['existing_available_datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
2147
-                'DTTNUM',
2148
-                $ticket_row,
2149
-                null,
2150
-                $ticket,
2151
-                array(),
2152
-                true
2153
-            );
2154
-            $ticket_row++;
2155
-        }
2156
-        $datetime_row = 1;
2157
-        foreach ($all_datetimes as $datetime) {
2158
-            $template_args['existing_available_ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
2159
-                $datetime_row,
2160
-                'TICKETNUM',
2161
-                $datetime,
2162
-                null,
2163
-                array(),
2164
-                true
2165
-            );
2166
-            $datetime_row++;
2167
-        }
2168
-        /** @var EEM_Price $price_model */
2169
-        $price_model = EE_Registry::instance()->load_model('Price');
2170
-        $default_prices = $price_model->get_all_default_prices();
2171
-        $price_row = 1;
2172
-        foreach ($default_prices as $price) {
2173
-            if (! $price instanceof EE_Price) {
2174
-                continue;
2175
-            }
2176
-            if ($price->is_base_price()) {
2177
-                $template_args['default_base_price_amount'] = $price->get_pretty(
2178
-                    'PRC_amount',
2179
-                    'localized_float'
2180
-                );
2181
-                $template_args['default_base_price_name'] = $price->get('PRC_name');
2182
-                $template_args['default_base_price_description'] = $price->get('PRC_desc');
2183
-                $price_row++;
2184
-                continue;
2185
-            }
2186
-            $show_trash = ! ((count($default_prices) > 1 && $price_row === 1)
2187
-                             || count($default_prices) === 1);
2188
-            $show_create = ! (count($default_prices) > 1
2189
-                              && count($default_prices)
2190
-                                 !== $price_row);
2191
-            $template_args['default_price_rows'] .= $this->_get_ticket_price_row(
2192
-                'TICKETNUM',
2193
-                $price_row,
2194
-                $price,
2195
-                true,
2196
-                null,
2197
-                $show_trash,
2198
-                $show_create
2199
-            );
2200
-            $price_row++;
2201
-        }
2202
-        $template_args = apply_filters(
2203
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_js_structure__template_args',
2204
-            $template_args,
2205
-            $all_datetimes,
2206
-            $all_tickets,
2207
-            $this->_is_creating_event
2208
-        );
2209
-        return EEH_Template::display_template(
2210
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php',
2211
-            $template_args,
2212
-            true
2213
-        );
2214
-    }
2074
+	/**
2075
+	 * @param array $all_datetimes
2076
+	 * @param array $all_tickets
2077
+	 * @return mixed
2078
+	 * @throws ReflectionException
2079
+	 * @throws InvalidArgumentException
2080
+	 * @throws InvalidInterfaceException
2081
+	 * @throws InvalidDataTypeException
2082
+	 * @throws DomainException
2083
+	 * @throws EE_Error
2084
+	 */
2085
+	protected function _get_ticket_js_structure($all_datetimes = array(), $all_tickets = array())
2086
+	{
2087
+		$template_args = array(
2088
+			'default_datetime_edit_row'                => $this->_get_dtt_edit_row(
2089
+				'DTTNUM',
2090
+				null,
2091
+				true,
2092
+				$all_datetimes
2093
+			),
2094
+			'default_ticket_row'                       => $this->_get_ticket_row(
2095
+				'TICKETNUM',
2096
+				null,
2097
+				array(),
2098
+				array(),
2099
+				true
2100
+			),
2101
+			'default_price_row'                        => $this->_get_ticket_price_row(
2102
+				'TICKETNUM',
2103
+				'PRICENUM',
2104
+				null,
2105
+				true,
2106
+				null
2107
+			),
2108
+			'default_price_rows'                       => '',
2109
+			'default_base_price_amount'                => 0,
2110
+			'default_base_price_name'                  => '',
2111
+			'default_base_price_description'           => '',
2112
+			'default_price_modifier_selector_row'      => $this->_get_price_modifier_template(
2113
+				'TICKETNUM',
2114
+				'PRICENUM',
2115
+				null,
2116
+				true
2117
+			),
2118
+			'default_available_tickets_for_datetime'   => $this->_get_dtt_attached_tickets_row(
2119
+				'DTTNUM',
2120
+				null,
2121
+				array(),
2122
+				array(),
2123
+				true
2124
+			),
2125
+			'existing_available_datetime_tickets_list' => '',
2126
+			'existing_available_ticket_datetimes_list' => '',
2127
+			'new_available_datetime_ticket_list_item'  => $this->_get_datetime_tickets_list_item(
2128
+				'DTTNUM',
2129
+				'TICKETNUM',
2130
+				null,
2131
+				null,
2132
+				array(),
2133
+				true
2134
+			),
2135
+			'new_available_ticket_datetime_list_item'  => $this->_get_ticket_datetime_list_item(
2136
+				'DTTNUM',
2137
+				'TICKETNUM',
2138
+				null,
2139
+				null,
2140
+				array(),
2141
+				true
2142
+			),
2143
+		);
2144
+		$ticket_row = 1;
2145
+		foreach ($all_tickets as $ticket) {
2146
+			$template_args['existing_available_datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
2147
+				'DTTNUM',
2148
+				$ticket_row,
2149
+				null,
2150
+				$ticket,
2151
+				array(),
2152
+				true
2153
+			);
2154
+			$ticket_row++;
2155
+		}
2156
+		$datetime_row = 1;
2157
+		foreach ($all_datetimes as $datetime) {
2158
+			$template_args['existing_available_ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
2159
+				$datetime_row,
2160
+				'TICKETNUM',
2161
+				$datetime,
2162
+				null,
2163
+				array(),
2164
+				true
2165
+			);
2166
+			$datetime_row++;
2167
+		}
2168
+		/** @var EEM_Price $price_model */
2169
+		$price_model = EE_Registry::instance()->load_model('Price');
2170
+		$default_prices = $price_model->get_all_default_prices();
2171
+		$price_row = 1;
2172
+		foreach ($default_prices as $price) {
2173
+			if (! $price instanceof EE_Price) {
2174
+				continue;
2175
+			}
2176
+			if ($price->is_base_price()) {
2177
+				$template_args['default_base_price_amount'] = $price->get_pretty(
2178
+					'PRC_amount',
2179
+					'localized_float'
2180
+				);
2181
+				$template_args['default_base_price_name'] = $price->get('PRC_name');
2182
+				$template_args['default_base_price_description'] = $price->get('PRC_desc');
2183
+				$price_row++;
2184
+				continue;
2185
+			}
2186
+			$show_trash = ! ((count($default_prices) > 1 && $price_row === 1)
2187
+							 || count($default_prices) === 1);
2188
+			$show_create = ! (count($default_prices) > 1
2189
+							  && count($default_prices)
2190
+								 !== $price_row);
2191
+			$template_args['default_price_rows'] .= $this->_get_ticket_price_row(
2192
+				'TICKETNUM',
2193
+				$price_row,
2194
+				$price,
2195
+				true,
2196
+				null,
2197
+				$show_trash,
2198
+				$show_create
2199
+			);
2200
+			$price_row++;
2201
+		}
2202
+		$template_args = apply_filters(
2203
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_js_structure__template_args',
2204
+			$template_args,
2205
+			$all_datetimes,
2206
+			$all_tickets,
2207
+			$this->_is_creating_event
2208
+		);
2209
+		return EEH_Template::display_template(
2210
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php',
2211
+			$template_args,
2212
+			true
2213
+		);
2214
+	}
2215 2215
 }
Please login to merge, or discard this patch.
Spacing   +78 added lines, -78 removed lines patch added patch discarded remove patch
@@ -150,7 +150,7 @@  discard block
 block discarded – undo
150 150
             );
151 151
             $msg .= '</p><ul>';
152 152
             foreach ($format_validation as $error) {
153
-                $msg .= '<li>' . $error . '</li>';
153
+                $msg .= '<li>'.$error.'</li>';
154 154
             }
155 155
             $msg .= '</ul><p>';
156 156
             $msg .= sprintf(
@@ -179,11 +179,11 @@  discard block
 block discarded – undo
179 179
         $this->_scripts_styles = array(
180 180
             'registers'   => array(
181 181
                 'ee-tickets-datetimes-css' => array(
182
-                    'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
182
+                    'url'  => PRICING_ASSETS_URL.'event-tickets-datetimes.css',
183 183
                     'type' => 'css',
184 184
                 ),
185 185
                 'ee-dtt-ticket-metabox'    => array(
186
-                    'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
186
+                    'url'     => PRICING_ASSETS_URL.'ee-datetime-ticket-metabox.js',
187 187
                     'depends' => array('ee-datepicker', 'ee-dialog', 'underscore'),
188 188
                 ),
189 189
             ),
@@ -207,9 +207,9 @@  discard block
 block discarded – undo
207 207
                             'event_espresso'
208 208
                         ),
209 209
                         'cancel_button'           => '<button class="button-secondary ee-modal-cancel">'
210
-                                                     . esc_html__('Cancel', 'event_espresso') . '</button>',
210
+                                                     . esc_html__('Cancel', 'event_espresso').'</button>',
211 211
                         'close_button'            => '<button class="button-secondary ee-modal-cancel">'
212
-                                                     . esc_html__('Close', 'event_espresso') . '</button>',
212
+                                                     . esc_html__('Close', 'event_espresso').'</button>',
213 213
                         'single_warning_from_tkt' => esc_html__(
214 214
                             'The Datetime you are attempting to unassign from this ticket is the only remaining datetime for this ticket. Tickets must always have at least one datetime assigned to them.',
215 215
                             'event_espresso'
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
                             'event_espresso'
220 220
                         ),
221 221
                         'dismiss_button'          => '<button class="button-secondary ee-modal-cancel">'
222
-                                                     . esc_html__('Dismiss', 'event_espresso') . '</button>',
222
+                                                     . esc_html__('Dismiss', 'event_espresso').'</button>',
223 223
                     ),
224 224
                     'DTT_ERROR_MSG'         => array(
225 225
                         'no_ticket_name' => esc_html__('General Admission', 'event_espresso'),
@@ -257,7 +257,7 @@  discard block
 block discarded – undo
257 257
     {
258 258
         foreach ($update_callbacks as $key => $callback) {
259 259
             if ($callback[1] === '_default_tickets_update') {
260
-                unset($update_callbacks[ $key ]);
260
+                unset($update_callbacks[$key]);
261 261
             }
262 262
         }
263 263
         $update_callbacks[] = array($this, 'datetime_and_tickets_caf_update');
@@ -315,7 +315,7 @@  discard block
 block discarded – undo
315 315
         foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
316 316
             // trim all values to ensure any excess whitespace is removed.
317 317
             $datetime_data = array_map(
318
-                function ($datetime_data) {
318
+                function($datetime_data) {
319 319
                     return is_array($datetime_data) ? $datetime_data : trim($datetime_data);
320 320
                 },
321 321
                 $datetime_data
@@ -345,7 +345,7 @@  discard block
 block discarded – undo
345 345
             );
346 346
             // if we have an id then let's get existing object first and then set the new values.
347 347
             // Otherwise we instantiate a new object for save.
348
-            if (! empty($datetime_data['DTT_ID'])) {
348
+            if ( ! empty($datetime_data['DTT_ID'])) {
349 349
                 $datetime = EE_Registry::instance()
350 350
                                        ->load_model('Datetime', array($timezone))
351 351
                                        ->get_one_by_ID($datetime_data['DTT_ID']);
@@ -359,7 +359,7 @@  discard block
 block discarded – undo
359 359
                 // after the add_relation_to() the autosave replaces it.
360 360
                 // We need to do this so we dont' TRASH the parent DTT.
361 361
                 // (save the ID for both key and value to avoid duplications)
362
-                $saved_dtt_ids[ $datetime->ID() ] = $datetime->ID();
362
+                $saved_dtt_ids[$datetime->ID()] = $datetime->ID();
363 363
             } else {
364 364
                 $datetime = EE_Registry::instance()->load_class(
365 365
                     'Datetime',
@@ -388,8 +388,8 @@  discard block
 block discarded – undo
388 388
             // because it is possible there was a new one created for the autosave.
389 389
             // (save the ID for both key and value to avoid duplications)
390 390
             $DTT_ID = $datetime->ID();
391
-            $saved_dtt_ids[ $DTT_ID ] = $DTT_ID;
392
-            $saved_dtt_objs[ $row ] = $datetime;
391
+            $saved_dtt_ids[$DTT_ID] = $DTT_ID;
392
+            $saved_dtt_objs[$row] = $datetime;
393 393
             // @todo if ANY of these updates fail then we want the appropriate global error message.
394 394
         }
395 395
         $event->save();
@@ -454,13 +454,13 @@  discard block
 block discarded – undo
454 454
             $update_prices = $create_new_TKT = false;
455 455
             // figure out what datetimes were added to the ticket
456 456
             // and what datetimes were removed from the ticket in the session.
457
-            $starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][ $row ]);
458
-            $tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][ $row ]);
457
+            $starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][$row]);
458
+            $tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][$row]);
459 459
             $datetimes_added = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
460 460
             $datetimes_removed = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
461 461
             // trim inputs to ensure any excess whitespace is removed.
462 462
             $tkt = array_map(
463
-                function ($ticket_data) {
463
+                function($ticket_data) {
464 464
                     return is_array($ticket_data) ? $ticket_data : trim($ticket_data);
465 465
                 },
466 466
                 $tkt
@@ -482,8 +482,8 @@  discard block
 block discarded – undo
482 482
             $base_price_id = isset($tkt['TKT_base_price_ID'])
483 483
                 ? $tkt['TKT_base_price_ID']
484 484
                 : 0;
485
-            $price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][ $row ])
486
-                ? $data['edit_prices'][ $row ]
485
+            $price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][$row])
486
+                ? $data['edit_prices'][$row]
487 487
                 : array();
488 488
             $now = null;
489 489
             if (empty($tkt['TKT_start_date'])) {
@@ -495,7 +495,7 @@  discard block
 block discarded – undo
495 495
                 /**
496 496
                  * set the TKT_end_date to the first datetime attached to the ticket.
497 497
                  */
498
-                $first_dtt = $saved_datetimes[ reset($tkt_dtt_rows) ];
498
+                $first_dtt = $saved_datetimes[reset($tkt_dtt_rows)];
499 499
                 $tkt['TKT_end_date'] = $first_dtt->start_date_and_time($this->_date_time_format);
500 500
             }
501 501
             $TKT_values = array(
@@ -630,7 +630,7 @@  discard block
 block discarded – undo
630 630
             // need to make sue that the TKT_price is accurate after saving the prices.
631 631
             $ticket->ensure_TKT_Price_correct();
632 632
             // handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
633
-            if (! defined('DOING_AUTOSAVE') && ! empty($tkt['TKT_is_default_selector'])) {
633
+            if ( ! defined('DOING_AUTOSAVE') && ! empty($tkt['TKT_is_default_selector'])) {
634 634
                 $update_prices = true;
635 635
                 $new_default = clone $ticket;
636 636
                 $new_default->set('TKT_ID', 0);
@@ -675,7 +675,7 @@  discard block
 block discarded – undo
675 675
                 // save new TKT
676 676
                 $new_tkt->save();
677 677
                 // add new ticket to array
678
-                $saved_tickets[ $new_tkt->ID() ] = $new_tkt;
678
+                $saved_tickets[$new_tkt->ID()] = $new_tkt;
679 679
                 do_action(
680 680
                     'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket',
681 681
                     $new_tkt,
@@ -685,7 +685,7 @@  discard block
 block discarded – undo
685 685
                 );
686 686
             } else {
687 687
                 // add tkt to saved tkts
688
-                $saved_tickets[ $ticket->ID() ] = $ticket;
688
+                $saved_tickets[$ticket->ID()] = $ticket;
689 689
                 do_action(
690 690
                     'AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket',
691 691
                     $ticket,
@@ -752,31 +752,31 @@  discard block
 block discarded – undo
752 752
         // to start we have to add the ticket to all the datetimes its supposed to be with,
753 753
         // and removing the ticket from datetimes it got removed from.
754 754
         // first let's add datetimes
755
-        if (! empty($added_datetimes) && is_array($added_datetimes)) {
755
+        if ( ! empty($added_datetimes) && is_array($added_datetimes)) {
756 756
             foreach ($added_datetimes as $row_id) {
757 757
                 $row_id = (int) $row_id;
758
-                if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
759
-                    $ticket->_add_relation_to($saved_datetimes[ $row_id ], 'Datetime');
758
+                if (isset($saved_datetimes[$row_id]) && $saved_datetimes[$row_id] instanceof EE_Datetime) {
759
+                    $ticket->_add_relation_to($saved_datetimes[$row_id], 'Datetime');
760 760
                     // Is this an existing ticket (has an ID) and does it have any sold?
761 761
                     // If so, then we need to add that to the DTT sold because this DTT is getting added.
762 762
                     if ($ticket->ID() && $ticket->sold() > 0) {
763
-                        $saved_datetimes[ $row_id ]->increaseSold($ticket->sold(), false);
763
+                        $saved_datetimes[$row_id]->increaseSold($ticket->sold(), false);
764 764
                     }
765 765
                 }
766 766
             }
767 767
         }
768 768
         // then remove datetimes
769
-        if (! empty($removed_datetimes) && is_array($removed_datetimes)) {
769
+        if ( ! empty($removed_datetimes) && is_array($removed_datetimes)) {
770 770
             foreach ($removed_datetimes as $row_id) {
771 771
                 $row_id = (int) $row_id;
772 772
                 // its entirely possible that a datetime got deleted (instead of just removed from relationship.
773 773
                 // So make sure we skip over this if the dtt isn't in the $saved_datetimes array)
774
-                if (isset($saved_datetimes[ $row_id ]) && $saved_datetimes[ $row_id ] instanceof EE_Datetime) {
775
-                    $ticket->_remove_relation_to($saved_datetimes[ $row_id ], 'Datetime');
774
+                if (isset($saved_datetimes[$row_id]) && $saved_datetimes[$row_id] instanceof EE_Datetime) {
775
+                    $ticket->_remove_relation_to($saved_datetimes[$row_id], 'Datetime');
776 776
                     // Is this an existing ticket (has an ID) and does it have any sold?
777 777
                     // If so, then we need to remove it's sold from the DTT_sold.
778 778
                     if ($ticket->ID() && $ticket->sold() > 0) {
779
-                        $saved_datetimes[ $row_id ]->decreaseSold($ticket->sold());
779
+                        $saved_datetimes[$row_id]->decreaseSold($ticket->sold());
780 780
                     }
781 781
                 }
782 782
             }
@@ -889,7 +889,7 @@  discard block
 block discarded – undo
889 889
             );
890 890
         }
891 891
         // possibly need to save tkt
892
-        if (! $ticket->ID()) {
892
+        if ( ! $ticket->ID()) {
893 893
             $ticket->save();
894 894
         }
895 895
         foreach ($prices as $row => $prc) {
@@ -923,17 +923,17 @@  discard block
 block discarded – undo
923 923
                 }
924 924
             }
925 925
             $price->save();
926
-            $updated_prices[ $price->ID() ] = $price;
926
+            $updated_prices[$price->ID()] = $price;
927 927
             $ticket->_add_relation_to($price, 'Price');
928 928
         }
929 929
         // now let's remove any prices that got removed from the ticket
930
-        if (! empty($current_prices_on_ticket)) {
930
+        if ( ! empty($current_prices_on_ticket)) {
931 931
             $current = array_keys($current_prices_on_ticket);
932 932
             $updated = array_keys($updated_prices);
933 933
             $prices_to_remove = array_diff($current, $updated);
934
-            if (! empty($prices_to_remove)) {
934
+            if ( ! empty($prices_to_remove)) {
935 935
                 foreach ($prices_to_remove as $prc_id) {
936
-                    $p = $current_prices_on_ticket[ $prc_id ];
936
+                    $p = $current_prices_on_ticket[$prc_id];
937 937
                     $ticket->_remove_relation_to($p, 'Price');
938 938
                     // delete permanently the price
939 939
                     $p->delete_permanently();
@@ -1084,17 +1084,17 @@  discard block
 block discarded – undo
1084 1084
                 $TKT_ID = $ticket->get('TKT_ID');
1085 1085
                 $ticket_row = $ticket->get('TKT_row');
1086 1086
                 // we only want unique tickets in our final display!!
1087
-                if (! in_array($TKT_ID, $existing_ticket_ids, true)) {
1087
+                if ( ! in_array($TKT_ID, $existing_ticket_ids, true)) {
1088 1088
                     $existing_ticket_ids[] = $TKT_ID;
1089 1089
                     $all_tickets[] = $ticket;
1090 1090
                 }
1091 1091
                 // temporary cache of this ticket info for this datetime for later processing of datetime rows.
1092
-                $datetime_tickets[ $DTT_ID ][] = $ticket_row;
1092
+                $datetime_tickets[$DTT_ID][] = $ticket_row;
1093 1093
                 // temporary cache of this datetime info for this ticket for later processing of ticket rows.
1094
-                if (! isset($ticket_datetimes[ $TKT_ID ])
1095
-                    || ! in_array($datetime_row, $ticket_datetimes[ $TKT_ID ], true)
1094
+                if ( ! isset($ticket_datetimes[$TKT_ID])
1095
+                    || ! in_array($datetime_row, $ticket_datetimes[$TKT_ID], true)
1096 1096
                 ) {
1097
-                    $ticket_datetimes[ $TKT_ID ][] = $datetime_row;
1097
+                    $ticket_datetimes[$TKT_ID][] = $datetime_row;
1098 1098
                 }
1099 1099
             }
1100 1100
             $datetime_row++;
@@ -1105,7 +1105,7 @@  discard block
 block discarded – undo
1105 1105
         // sort $all_tickets by order
1106 1106
         usort(
1107 1107
             $all_tickets,
1108
-            function (EE_Ticket $a, EE_Ticket $b) {
1108
+            function(EE_Ticket $a, EE_Ticket $b) {
1109 1109
                 $a_order = (int) $a->get('TKT_order');
1110 1110
                 $b_order = (int) $b->get('TKT_order');
1111 1111
                 if ($a_order === $b_order) {
@@ -1143,12 +1143,12 @@  discard block
 block discarded – undo
1143 1143
         }
1144 1144
         $main_template_args['ticket_js_structure'] = $this->_get_ticket_js_structure($datetimes, $all_tickets);
1145 1145
         $main_template_args['status_change_notice'] = EEH_Template::display_template(
1146
-            EE_ADMIN_TEMPLATE . 'status_change_notice.template.php',
1147
-            [ 'context' => '__event-editor' ],
1146
+            EE_ADMIN_TEMPLATE.'status_change_notice.template.php',
1147
+            ['context' => '__event-editor'],
1148 1148
             true
1149 1149
         );
1150 1150
         EEH_Template::display_template(
1151
-            PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php',
1151
+            PRICING_TEMPLATE_PATH.'event_tickets_metabox_main.template.php',
1152 1152
             $main_template_args
1153 1153
         );
1154 1154
     }
@@ -1190,7 +1190,7 @@  discard block
 block discarded – undo
1190 1190
             'dtt_row'                  => $default ? 'DTTNUM' : $datetime_row,
1191 1191
         );
1192 1192
         return EEH_Template::display_template(
1193
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php',
1193
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_row_wrapper.template.php',
1194 1194
             $dtt_display_template_args,
1195 1195
             true
1196 1196
         );
@@ -1259,7 +1259,7 @@  discard block
 block discarded – undo
1259 1259
             $this->_is_creating_event
1260 1260
         );
1261 1261
         return EEH_Template::display_template(
1262
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php',
1262
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_edit_row.template.php',
1263 1263
             $template_args,
1264 1264
             true
1265 1265
         );
@@ -1300,7 +1300,7 @@  discard block
 block discarded – undo
1300 1300
             'DTT_ID'                            => $default ? '' : $datetime->ID(),
1301 1301
         );
1302 1302
         // need to setup the list items (but only if this isn't a default skeleton setup)
1303
-        if (! $default) {
1303
+        if ( ! $default) {
1304 1304
             $ticket_row = 1;
1305 1305
             foreach ($all_tickets as $ticket) {
1306 1306
                 $template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
@@ -1326,7 +1326,7 @@  discard block
 block discarded – undo
1326 1326
             $this->_is_creating_event
1327 1327
         );
1328 1328
         return EEH_Template::display_template(
1329
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php',
1329
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_attached_tickets_row.template.php',
1330 1330
             $template_args,
1331 1331
             true
1332 1332
         );
@@ -1352,8 +1352,8 @@  discard block
 block discarded – undo
1352 1352
         $datetime_tickets = array(),
1353 1353
         $default
1354 1354
     ) {
1355
-        $dtt_tkts = $datetime instanceof EE_Datetime && isset($datetime_tickets[ $datetime->ID() ])
1356
-            ? $datetime_tickets[ $datetime->ID() ]
1355
+        $dtt_tkts = $datetime instanceof EE_Datetime && isset($datetime_tickets[$datetime->ID()])
1356
+            ? $datetime_tickets[$datetime->ID()]
1357 1357
             : array();
1358 1358
         $display_row = $ticket instanceof EE_Ticket ? $ticket->get('TKT_row') : 0;
1359 1359
         $no_ticket = $default && empty($ticket);
@@ -1374,8 +1374,8 @@  discard block
 block discarded – undo
1374 1374
                 ? 'TKTNAME'
1375 1375
                 : $ticket->get('TKT_name'),
1376 1376
             'tkt_status_class'        => $no_ticket || $this->_is_creating_event
1377
-                ? ' tkt-status-' . EE_Ticket::onsale
1378
-                : ' tkt-status-' . $ticket->ticket_status(),
1377
+                ? ' tkt-status-'.EE_Ticket::onsale
1378
+                : ' tkt-status-'.$ticket->ticket_status(),
1379 1379
         );
1380 1380
         // filter template args
1381 1381
         $template_args = apply_filters(
@@ -1390,7 +1390,7 @@  discard block
 block discarded – undo
1390 1390
             $this->_is_creating_event
1391 1391
         );
1392 1392
         return EEH_Template::display_template(
1393
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php',
1393
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_dtt_tickets_list.template.php',
1394 1394
             $template_args,
1395 1395
             true
1396 1396
         );
@@ -1446,19 +1446,19 @@  discard block
 block discarded – undo
1446 1446
         // (otherwise there won't be any new relationships created for tickets based off of the default ticket).
1447 1447
         // This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1448 1448
         $default_dtt = $default || ($ticket instanceof EE_Ticket && $ticket->is_default());
1449
-        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
1450
-            ? $ticket_datetimes[ $ticket->ID() ]
1449
+        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[$ticket->ID()])
1450
+            ? $ticket_datetimes[$ticket->ID()]
1451 1451
             : array();
1452 1452
         $ticket_subtotal = $default ? 0 : $ticket->get_ticket_subtotal();
1453 1453
         $base_price = $default ? null : $ticket->base_price();
1454 1454
         $count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1455 1455
         // breaking out complicated condition for ticket_status
1456 1456
         if ($default) {
1457
-            $ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1457
+            $ticket_status_class = ' tkt-status-'.EE_Ticket::onsale;
1458 1458
         } else {
1459 1459
             $ticket_status_class = $ticket->is_default()
1460
-                ? ' tkt-status-' . EE_Ticket::onsale
1461
-                : ' tkt-status-' . $ticket->ticket_status();
1460
+                ? ' tkt-status-'.EE_Ticket::onsale
1461
+                : ' tkt-status-'.$ticket->ticket_status();
1462 1462
         }
1463 1463
         // breaking out complicated condition for TKT_taxable
1464 1464
         if ($default) {
@@ -1550,7 +1550,7 @@  discard block
 block discarded – undo
1550 1550
                 : ' style="display:none;"',
1551 1551
             'show_price_mod_button'         => count($prices) > 1
1552 1552
                                                || ($default && $count_price_mods > 0)
1553
-                                               || (! $default && $ticket->deleted())
1553
+                                               || ( ! $default && $ticket->deleted())
1554 1554
                 ? ' style="display:none;"'
1555 1555
                 : '',
1556 1556
             'total_price_rows'              => count($prices) > 1 ? count($prices) : 1,
@@ -1594,7 +1594,7 @@  discard block
 block discarded – undo
1594 1594
                 $this->_date_time_format,
1595 1595
                 current_time('timestamp')
1596 1596
             );
1597
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1597
+            $template_args['tkt_status_class'] = ' tkt-status-'.EE_Ticket::onsale;
1598 1598
         }
1599 1599
         if (empty($template_args['TKT_end_date'])) {
1600 1600
             // get the earliest datetime (if present);
@@ -1604,7 +1604,7 @@  discard block
 block discarded – undo
1604 1604
                     array('order_by' => array('DTT_EVT_start' => 'ASC'))
1605 1605
                 )
1606 1606
                 : null;
1607
-            if (! empty($earliest_dtt)) {
1607
+            if ( ! empty($earliest_dtt)) {
1608 1608
                 $template_args['TKT_end_date'] = $earliest_dtt->get_datetime(
1609 1609
                     'DTT_EVT_start',
1610 1610
                     $this->_date_time_format
@@ -1623,10 +1623,10 @@  discard block
 block discarded – undo
1623 1623
                     )
1624 1624
                 );
1625 1625
             }
1626
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1626
+            $template_args['tkt_status_class'] = ' tkt-status-'.EE_Ticket::onsale;
1627 1627
         }
1628 1628
         // generate ticket_datetime items
1629
-        if (! $default) {
1629
+        if ( ! $default) {
1630 1630
             $datetime_row = 1;
1631 1631
             foreach ($all_datetimes as $datetime) {
1632 1632
                 $template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
@@ -1642,7 +1642,7 @@  discard block
 block discarded – undo
1642 1642
         }
1643 1643
         $price_row = 1;
1644 1644
         foreach ($prices as $price) {
1645
-            if (! $price instanceof EE_Price) {
1645
+            if ( ! $price instanceof EE_Price) {
1646 1646
                 continue;
1647 1647
             }
1648 1648
             if ($price->is_base_price()) {
@@ -1675,7 +1675,7 @@  discard block
 block discarded – undo
1675 1675
             $this->_is_creating_event
1676 1676
         );
1677 1677
         return EEH_Template::display_template(
1678
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php',
1678
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_ticket_row.template.php',
1679 1679
             $template_args,
1680 1680
             true
1681 1681
         );
@@ -1715,7 +1715,7 @@  discard block
 block discarded – undo
1715 1715
                 $this->_is_creating_event
1716 1716
             );
1717 1717
             $tax_rows .= EEH_Template::display_template(
1718
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php',
1718
+                PRICING_TEMPLATE_PATH.'event_tickets_datetime_ticket_tax_row.template.php',
1719 1719
                 $template_args,
1720 1720
                 true
1721 1721
             );
@@ -1834,7 +1834,7 @@  discard block
 block discarded – undo
1834 1834
             $this->_is_creating_event
1835 1835
         );
1836 1836
         return EEH_Template::display_template(
1837
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php',
1837
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_ticket_price_row.template.php',
1838 1838
             $template_args,
1839 1839
             true
1840 1840
         );
@@ -1904,7 +1904,7 @@  discard block
 block discarded – undo
1904 1904
             $this->_is_creating_event
1905 1905
         );
1906 1906
         return EEH_Template::display_template(
1907
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php',
1907
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_price_type_base.template.php',
1908 1908
             $template_args,
1909 1909
             true
1910 1910
         );
@@ -1934,7 +1934,7 @@  discard block
 block discarded – undo
1934 1934
     ) {
1935 1935
         $select_name = $default && ! $price instanceof EE_Price
1936 1936
             ? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]'
1937
-            : 'edit_prices[' . $ticket_row . '][' . $price_row . '][PRT_ID]';
1937
+            : 'edit_prices['.$ticket_row.']['.$price_row.'][PRT_ID]';
1938 1938
         /** @var EEM_Price_Type $price_type_model */
1939 1939
         $price_type_model = EE_Registry::instance()->load_model('Price_Type');
1940 1940
         $price_types = $price_type_model->get_all(array(
@@ -1952,10 +1952,10 @@  discard block
 block discarded – undo
1952 1952
         $price_option_spans = '';
1953 1953
         // setup price types for selector
1954 1954
         foreach ($price_types as $price_type) {
1955
-            if (! $price_type instanceof EE_Price_Type) {
1955
+            if ( ! $price_type instanceof EE_Price_Type) {
1956 1956
                 continue;
1957 1957
             }
1958
-            $all_price_types[ $price_type->ID() ] = $price_type->get('PRT_name');
1958
+            $all_price_types[$price_type->ID()] = $price_type->get('PRT_name');
1959 1959
             // while we're in the loop let's setup the option spans used by js
1960 1960
             $span_args = array(
1961 1961
                 'PRT_ID'         => $price_type->ID(),
@@ -1963,12 +1963,12 @@  discard block
 block discarded – undo
1963 1963
                 'PRT_is_percent' => $price_type->get('PRT_is_percent') ? 1 : 0,
1964 1964
             );
1965 1965
             $price_option_spans .= EEH_Template::display_template(
1966
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php',
1966
+                PRICING_TEMPLATE_PATH.'event_tickets_datetime_price_option_span.template.php',
1967 1967
                 $span_args,
1968 1968
                 true
1969 1969
             );
1970 1970
         }
1971
-        $select_name = $disabled ? 'archive_price[' . $ticket_row . '][' . $price_row . '][PRT_ID]'
1971
+        $select_name = $disabled ? 'archive_price['.$ticket_row.']['.$price_row.'][PRT_ID]'
1972 1972
             : $select_name;
1973 1973
         $select_input = new EE_Select_Input(
1974 1974
             $all_price_types,
@@ -2005,7 +2005,7 @@  discard block
 block discarded – undo
2005 2005
             $this->_is_creating_event
2006 2006
         );
2007 2007
         return EEH_Template::display_template(
2008
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php',
2008
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_price_modifier_selector.template.php',
2009 2009
             $template_args,
2010 2010
             true
2011 2011
         );
@@ -2031,8 +2031,8 @@  discard block
 block discarded – undo
2031 2031
         $ticket_datetimes = array(),
2032 2032
         $default
2033 2033
     ) {
2034
-        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[ $ticket->ID() ])
2035
-            ? $ticket_datetimes[ $ticket->ID() ]
2034
+        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[$ticket->ID()])
2035
+            ? $ticket_datetimes[$ticket->ID()]
2036 2036
             : array();
2037 2037
         $template_args = array(
2038 2038
             'dtt_row'                  => $default && ! $datetime instanceof EE_Datetime
@@ -2064,7 +2064,7 @@  discard block
 block discarded – undo
2064 2064
             $this->_is_creating_event
2065 2065
         );
2066 2066
         return EEH_Template::display_template(
2067
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php',
2067
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_ticket_datetimes_list_item.template.php',
2068 2068
             $template_args,
2069 2069
             true
2070 2070
         );
@@ -2170,7 +2170,7 @@  discard block
 block discarded – undo
2170 2170
         $default_prices = $price_model->get_all_default_prices();
2171 2171
         $price_row = 1;
2172 2172
         foreach ($default_prices as $price) {
2173
-            if (! $price instanceof EE_Price) {
2173
+            if ( ! $price instanceof EE_Price) {
2174 2174
                 continue;
2175 2175
             }
2176 2176
             if ($price->is_base_price()) {
@@ -2207,7 +2207,7 @@  discard block
 block discarded – undo
2207 2207
             $this->_is_creating_event
2208 2208
         );
2209 2209
         return EEH_Template::display_template(
2210
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php',
2210
+            PRICING_TEMPLATE_PATH.'event_tickets_datetime_ticket_js_structure.template.php',
2211 2211
             $template_args,
2212 2212
             true
2213 2213
         );
Please login to merge, or discard this patch.
admin/new/pricing/templates/event_tickets_metabox_main.template.php 1 patch
Indentation   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -2,10 +2,10 @@  discard block
 block discarded – undo
2 2
     <h3 class="event-tickets-datetimes-title"><span data-target=".event-datetimes-container"
3 3
                                                     class="clickable ee-collapsible<?php echo $ee_collapsible_status; ?>"><span
4 4
                 class="dashicons dashicons-clock ee-icon-size-20"></span><?php
5
-                _e(
6
-                    'Event Datetimes',
7
-                    'event_espresso'
8
-                ); ?></span></h3><?php echo $event_datetime_help_link; ?>
5
+				_e(
6
+					'Event Datetimes',
7
+					'event_espresso'
8
+				); ?></span></h3><?php echo $event_datetime_help_link; ?>
9 9
     <div class="event-datetimes-container">
10 10
         <div class="save-cancel-button-container">
11 11
             <button class="button-secondary ee-create-button datetime-create-button" data-context="datetime">
@@ -39,10 +39,10 @@  discard block
 block discarded – undo
39 39
     </div> <!-- end .event-datetimes-container -->
40 40
     <div id="add-event-datetime" class="event-datetime-row add-dtt-row" style="display:none;">
41 41
         <h4 class="datetime-tickets-heading"><?php
42
-            _e(
43
-                'Add New Datetime',
44
-                'event_espresso'
45
-            ); ?></h4><?php echo $add_new_dtt_help_link; ?>
42
+			_e(
43
+				'Add New Datetime',
44
+				'event_espresso'
45
+			); ?></h4><?php echo $add_new_dtt_help_link; ?>
46 46
         <div>
47 47
             <table id="add-new-event-datetime-table" class="datetime-edit-table">
48 48
                 <tr>
@@ -56,10 +56,10 @@  discard block
 block discarded – undo
56 56
                     <td class="event-datetime-column date-column">
57 57
                         <label class="add-new-event-datetime-DTT_EVT_start_label"
58 58
                                for="add-new-event-datetime-DTT_EVT_start"><?php
59
-                                _e(
60
-                                    'Event Start',
61
-                                    'event_espresso'
62
-                                ); ?></label>
59
+								_e(
60
+									'Event Start',
61
+									'event_espresso'
62
+								); ?></label>
63 63
                         <input type="text" name="add_new_datetime[DTT_EVT_start]"
64 64
                                id="add-new-event-datetime-DTT_EVT_start" class="ee-text-inp ee-datepicker"
65 65
                                data-context="start-dtt" data-date-field-context="#add-event-datetime"
@@ -69,10 +69,10 @@  discard block
 block discarded – undo
69 69
                     <td class="event-datetime-column date-column">
70 70
                         <label class="add-new-event-datetime-DTT_EVT_end_label"
71 71
                                for="add-new-event-datetime-DTT_EVT_end"><?php
72
-                                _e(
73
-                                    'Event End',
74
-                                    'event_espresso'
75
-                                ); ?></label>
72
+								_e(
73
+									'Event End',
74
+									'event_espresso'
75
+								); ?></label>
76 76
                         <input type="text" name="add_new_datetime[DTT_EVT_end]" id="add-new-event-datetime-DTT_EVT_end"
77 77
                                class="ee-text-inp ee-datepicker" data-context="end-dtt"
78 78
                                data-date-field-context="#add-event-datetime"
@@ -82,10 +82,10 @@  discard block
 block discarded – undo
82 82
                     <td class="event-datetime-column reg-limit-column">
83 83
                         <label class="add-new-event-datetime-DTT_EVT_end_label"
84 84
                                for="add-new-event-datetime-DTT_reg_limit"><?php
85
-                                _e(
86
-                                    'Limit',
87
-                                    'event_espresso'
88
-                                ); ?></label>
85
+								_e(
86
+									'Limit',
87
+									'event_espresso'
88
+								); ?></label>
89 89
                         <input type="text" name="add_new_datetime[DTT_reg_limit]"
90 90
                                id="add-new-event-datetime-DTT_reg_limit" class="ee-numeric ee-small-text-inp">
91 91
                     </td>
@@ -106,7 +106,7 @@  discard block
 block discarded – undo
106 106
 
107 107
 <?php
108 108
 if (isset($status_change_notice)) {
109
-    echo $status_change_notice;
109
+	echo $status_change_notice;
110 110
 }
111 111
 ?>
112 112
 
@@ -114,16 +114,16 @@  discard block
 block discarded – undo
114 114
         <h3 class="event-tickets-datetimes-title"><span data-target=".event-tickets-container"
115 115
                                                         class="clickable ee-collapsible<?php echo $ee_collapsible_status; ?>"><span
116 116
                     class="ee-icon ee-icon-tickets ee-icon-size-20"></span><?php
117
-                    _e(
118
-                        'Available Tickets',
119
-                        'event_espresso'
120
-                    ); ?></span></h3>
117
+					_e(
118
+						'Available Tickets',
119
+						'event_espresso'
120
+					); ?></span></h3>
121 121
         <div class="event-tickets-container ee-create-ticket-button"<?php echo $show_tickets_container; ?>>
122 122
             <button class="ee-create-ticket-button button-secondary ee-create-button" data-context="ticket"><?php
123
-                _e(
124
-                    'Create Ticket',
125
-                    'event_espresso'
126
-                ); ?></button>
123
+				_e(
124
+					'Create Ticket',
125
+					'event_espresso'
126
+				); ?></button>
127 127
         </div>
128 128
         <div style="clear:both"></div>
129 129
         <div class="event-tickets-container"<?php echo $show_tickets_container; ?>>
Please login to merge, or discard this patch.