Completed
Branch dev (c6b783)
by
unknown
16:40 queued 09:04
created
core/helpers/EEH_Template.helper.php 2 patches
Indentation   +910 added lines, -910 removed lines patch added patch discarded remove patch
@@ -7,36 +7,36 @@  discard block
 block discarded – undo
7 7
 use EventEspresso\core\services\request\sanitizers\AllowedTags;
8 8
 
9 9
 if (! function_exists('espresso_get_template_part')) {
10
-    /**
11
-     * espresso_get_template_part
12
-     * 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
13
-     * so not a very useful function at all except that it adds familiarity PLUS filtering based off of the entire template part name
14
-     *
15
-     * @param string $slug The slug name for the generic template.
16
-     * @param string $name The name of the specialised template.
17
-     */
18
-    function espresso_get_template_part($slug = null, $name = null)
19
-    {
20
-        EEH_Template::get_template_part($slug, $name);
21
-    }
10
+	/**
11
+	 * espresso_get_template_part
12
+	 * 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
13
+	 * so not a very useful function at all except that it adds familiarity PLUS filtering based off of the entire template part name
14
+	 *
15
+	 * @param string $slug The slug name for the generic template.
16
+	 * @param string $name The name of the specialised template.
17
+	 */
18
+	function espresso_get_template_part($slug = null, $name = null)
19
+	{
20
+		EEH_Template::get_template_part($slug, $name);
21
+	}
22 22
 }
23 23
 
24 24
 
25 25
 if (! function_exists('espresso_get_object_css_class')) {
26
-    /**
27
-     * espresso_get_object_css_class - attempts to generate a css class based on the type of EE object passed
28
-     *
29
-     * @param EE_Base_Class $object the EE object the css class is being generated for
30
-     * @param string        $prefix added to the beginning of the generated class
31
-     * @param string        $suffix added to the end of the generated class
32
-     * @return string
33
-     * @throws EE_Error
34
-     * @throws ReflectionException
35
-     */
36
-    function espresso_get_object_css_class($object = null, $prefix = '', $suffix = '')
37
-    {
38
-        return EEH_Template::get_object_css_class($object, $prefix, $suffix);
39
-    }
26
+	/**
27
+	 * espresso_get_object_css_class - attempts to generate a css class based on the type of EE object passed
28
+	 *
29
+	 * @param EE_Base_Class $object the EE object the css class is being generated for
30
+	 * @param string        $prefix added to the beginning of the generated class
31
+	 * @param string        $suffix added to the end of the generated class
32
+	 * @return string
33
+	 * @throws EE_Error
34
+	 * @throws ReflectionException
35
+	 */
36
+	function espresso_get_object_css_class($object = null, $prefix = '', $suffix = '')
37
+	{
38
+		return EEH_Template::get_object_css_class($object, $prefix, $suffix);
39
+	}
40 40
 }
41 41
 
42 42
 
@@ -50,639 +50,639 @@  discard block
 block discarded – undo
50 50
  */
51 51
 class EEH_Template
52 52
 {
53
-    private static $_espresso_themes = [];
54
-
55
-
56
-    /**
57
-     *    is_espresso_theme - returns TRUE or FALSE on whether the currently active WP theme is an espresso theme
58
-     *
59
-     * @return boolean
60
-     */
61
-    public static function is_espresso_theme()
62
-    {
63
-        return wp_get_theme()->get('TextDomain') === 'event_espresso';
64
-    }
65
-
66
-
67
-    /**
68
-     *    load_espresso_theme_functions - if current theme is an espresso theme, or uses ee theme template parts, then
69
-     *    load its functions.php file ( if not already loaded )
70
-     *
71
-     * @return void
72
-     */
73
-    public static function load_espresso_theme_functions()
74
-    {
75
-        if (! defined('EE_THEME_FUNCTIONS_LOADED')) {
76
-            if (is_readable(EE_PUBLIC . EE_Config::get_current_theme() . '/functions.php')) {
77
-                require_once(EE_PUBLIC . EE_Config::get_current_theme() . '/functions.php');
78
-            }
79
-        }
80
-    }
81
-
82
-
83
-    /**
84
-     *    get_espresso_themes - returns an array of Espresso Child themes located in the /templates/ directory
85
-     *
86
-     * @return array
87
-     */
88
-    public static function get_espresso_themes()
89
-    {
90
-        if (empty(EEH_Template::$_espresso_themes)) {
91
-            $espresso_themes = glob(EE_PUBLIC . '*', GLOB_ONLYDIR);
92
-            if (empty($espresso_themes)) {
93
-                return [];
94
-            }
95
-            if (($key = array_search('global_assets', $espresso_themes)) !== false) {
96
-                unset($espresso_themes[ $key ]);
97
-            }
98
-            EEH_Template::$_espresso_themes = [];
99
-            foreach ($espresso_themes as $espresso_theme) {
100
-                EEH_Template::$_espresso_themes[ basename($espresso_theme) ] = $espresso_theme;
101
-            }
102
-        }
103
-        return EEH_Template::$_espresso_themes;
104
-    }
105
-
106
-
107
-    /**
108
-     * EEH_Template::get_template_part
109
-     * basically a copy of the WordPress get_template_part() function but uses EEH_Template::locate_template() instead,
110
-     * and doesn't add base versions of files so not a very useful function at all except that it adds familiarity PLUS
111
-     * filtering based off of the entire template part name
112
-     *
113
-     * @param string $slug The slug name for the generic template.
114
-     * @param string $name The name of the specialised template.
115
-     * @param array  $template_args
116
-     * @param bool   $return_string
117
-     * @return string        the html output for the formatted money value
118
-     */
119
-    public static function get_template_part(
120
-        $slug = null,
121
-        $name = null,
122
-        $template_args = [],
123
-        $return_string = false
124
-    ) {
125
-        do_action("get_template_part_{$slug}-{$name}", $slug, $name);
126
-        $templates = [];
127
-        $name      = (string) $name;
128
-        if ($name != '') {
129
-            $templates[] = "{$slug}-{$name}.php";
130
-        }
131
-        // allow template parts to be turned off via something like:
132
-        // add_filter( 'FHEE__content_espresso_events_tickets_template__display_datetimes', '__return_false' );
133
-        if (apply_filters("FHEE__EEH_Template__get_template_part__display__{$slug}_{$name}", true)) {
134
-            return EEH_Template::locate_template($templates, $template_args, true, $return_string);
135
-        }
136
-        return '';
137
-    }
138
-
139
-
140
-    /**
141
-     *    locate_template
142
-     *    locate a template file by looking in the following places, in the following order:
143
-     *        <server path up to>/wp-content/themes/<current active WordPress theme>/
144
-     *        <assumed full absolute server path>
145
-     *        <server path up to>/wp-content/uploads/espresso/templates/<current EE theme>/
146
-     *        <server path up to>/wp-content/uploads/espresso/templates/
147
-     *        <server path up to>/wp-content/plugins/<EE4 folder>/public/<current EE theme>/
148
-     *        <server path up to>/wp-content/plugins/<EE4 folder>/core/templates/<current EE theme>/
149
-     *        <server path up to>/wp-content/plugins/<EE4 folder>/
150
-     *    as soon as the template is found in one of these locations, it will be returned or loaded
151
-     *        Example:
152
-     *          You are using the WordPress Twenty Sixteen theme,
153
-     *        and you want to customize the "some-event.template.php" template,
154
-     *          which is located in the "/relative/path/to/" folder relative to the main EE plugin folder.
155
-     *          Assuming WP is installed on your server in the "/home/public_html/" folder,
156
-     *        EEH_Template::locate_template() will look at the following paths in order until the template is found:
157
-     *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
158
-     *        /relative/path/to/some-event.template.php
159
-     *        /home/public_html/wp-content/uploads/espresso/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
160
-     *        /home/public_html/wp-content/uploads/espresso/templates/relative/path/to/some-event.template.php
161
-     *        /home/public_html/wp-content/plugins/event-espresso-core-reg/public/Espresso_Arabica_2014/relative/path/to/some-event.template.php
162
-     *        /home/public_html/wp-content/plugins/event-espresso-core-reg/core/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
163
-     *        /home/public_html/wp-content/plugins/event-espresso-core-reg/relative/path/to/some-event.template.php
164
-     *          Had you passed an absolute path to your template that was in some other location,
165
-     *        ie: "/absolute/path/to/some-event.template.php"
166
-     *          then the search would have been :
167
-     *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
168
-     *        /absolute/path/to/some-event.template.php
169
-     *          and stopped there upon finding it in the second location
170
-     *
171
-     * @param array|string $templates       array of template file names including extension (or just a single string)
172
-     * @param array        $template_args   an array of arguments to be extracted for use in the template
173
-     * @param boolean      $load            whether to pass the located template path on to the
174
-     *                                      EEH_Template::display_template() method or simply return it
175
-     * @param boolean      $return_string   whether to send output immediately to screen, or capture and return as a
176
-     *                                      string
177
-     * @param boolean      $check_if_custom If TRUE, this flags this method to return boolean for whether this will
178
-     *                                      generate a custom template or not. Used in places where you don't actually
179
-     *                                      load the template, you just want to know if there's a custom version of it.
180
-     * @return mixed
181
-     * @throws DomainException
182
-     * @throws InvalidArgumentException
183
-     * @throws InvalidDataTypeException
184
-     * @throws InvalidInterfaceException
185
-     */
186
-    public static function locate_template(
187
-        $templates = [],
188
-        $template_args = [],
189
-        $load = true,
190
-        $return_string = true,
191
-        $check_if_custom = false
192
-    ) {
193
-        // first use WP locate_template to check for template in the current theme folder
194
-        $template_path = locate_template($templates);
195
-
196
-        if ($check_if_custom && ! empty($template_path)) {
197
-            return true;
198
-        }
199
-
200
-        // not in the theme
201
-        if (empty($template_path)) {
202
-            // not even a template to look for ?
203
-            if (empty($templates)) {
204
-                $loader = LoaderFactory::getLoader();
205
-                /** @var RequestInterface $request */
206
-                $request = $loader->getShared(RequestInterface::class);
207
-                // get post_type
208
-                $post_type = $request->getRequestParam('post_type');
209
-                /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
210
-                $custom_post_types = $loader->getShared(
211
-                    'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
212
-                );
213
-                // get array of EE Custom Post Types
214
-                $EE_CPTs = $custom_post_types->getDefinitions();
215
-                // build template name based on request
216
-                if (isset($EE_CPTs[ $post_type ])) {
217
-                    $archive_or_single = is_archive() ? 'archive' : '';
218
-                    $archive_or_single = is_single() ? 'single' : $archive_or_single;
219
-                    $templates         = $archive_or_single . '-' . $post_type . '.php';
220
-                }
221
-            }
222
-            // currently active EE template theme
223
-            $current_theme = EE_Config::get_current_theme();
224
-
225
-            // array of paths to folders that may contain templates
226
-            $template_folder_paths = [
227
-                // first check the /wp-content/uploads/espresso/templates/(current EE theme)/  folder for an EE theme template file
228
-                EVENT_ESPRESSO_TEMPLATE_DIR . $current_theme,
229
-                // then in the root of the /wp-content/uploads/espresso/templates/ folder
230
-                EVENT_ESPRESSO_TEMPLATE_DIR,
231
-            ];
232
-
233
-            // add core plugin folders for checking only if we're not $check_if_custom
234
-            if (! $check_if_custom) {
235
-                $core_paths            = [
236
-                    // in the  /wp-content/plugins/(EE4 folder)/public/(current EE theme)/ folder within the plugin
237
-                    EE_PUBLIC . $current_theme,
238
-                    // in the  /wp-content/plugins/(EE4 folder)/core/templates/(current EE theme)/ folder within the plugin
239
-                    EE_TEMPLATES . $current_theme,
240
-                    // or maybe relative from the plugin root: /wp-content/plugins/(EE4 folder)/
241
-                    EE_PLUGIN_DIR_PATH,
242
-                ];
243
-                $template_folder_paths = array_merge($template_folder_paths, $core_paths);
244
-            }
245
-
246
-            // now filter that array
247
-            $template_folder_paths = apply_filters(
248
-                'FHEE__EEH_Template__locate_template__template_folder_paths',
249
-                $template_folder_paths
250
-            );
251
-            $templates             = is_array($templates) ? $templates : [$templates];
252
-            $template_folder_paths =
253
-                is_array($template_folder_paths) ? $template_folder_paths : [$template_folder_paths];
254
-            // array to hold all possible template paths
255
-            $full_template_paths = [];
256
-            $file_name           = '';
257
-
258
-            // loop through $templates
259
-            foreach ($templates as $template) {
260
-                // normalize directory separators
261
-                $template                      = EEH_File::standardise_directory_separators($template);
262
-                $file_name                     = basename($template);
263
-                $template_path_minus_file_name = substr($template, 0, (strlen($file_name) * -1));
264
-                // while looping through all template folder paths
265
-                foreach ($template_folder_paths as $template_folder_path) {
266
-                    // normalize directory separators
267
-                    $template_folder_path = EEH_File::standardise_directory_separators($template_folder_path);
268
-                    // determine if any common base path exists between the two paths
269
-                    $common_base_path = EEH_Template::_find_common_base_path(
270
-                        [$template_folder_path, $template_path_minus_file_name]
271
-                    );
272
-                    if ($common_base_path !== '') {
273
-                        // both paths have a common base, so just tack the filename onto our search path
274
-                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $file_name;
275
-                    } else {
276
-                        // no common base path, so let's just concatenate
277
-                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $template;
278
-                    }
279
-                    // build up our template locations array by adding our resolved paths
280
-                    $full_template_paths[] = $resolved_path;
281
-                }
282
-                // if $template is an absolute path, then we'll tack it onto the start of our array so that it gets searched first
283
-                array_unshift($full_template_paths, $template);
284
-                // path to the directory of the current theme: /wp-content/themes/(current WP theme)/
285
-                array_unshift($full_template_paths, get_stylesheet_directory() . '/' . $file_name);
286
-            }
287
-            // filter final array of full template paths
288
-            $full_template_paths = apply_filters(
289
-                'FHEE__EEH_Template__locate_template__full_template_paths',
290
-                $full_template_paths,
291
-                $file_name
292
-            );
293
-            // now loop through our final array of template location paths and check each location
294
-            foreach ((array) $full_template_paths as $full_template_path) {
295
-                if (is_readable($full_template_path)) {
296
-                    $template_path = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $full_template_path);
297
-                    break;
298
-                }
299
-            }
300
-        }
301
-
302
-        // hook that can be used to display the full template path that will be used
303
-        do_action('AHEE__EEH_Template__locate_template__full_template_path', $template_path);
304
-
305
-        // if we got it and you want to see it...
306
-        if ($template_path && $load && ! $check_if_custom) {
307
-            if ($return_string) {
308
-                return EEH_Template::display_template($template_path, $template_args, true);
309
-            }
310
-            EEH_Template::display_template($template_path, $template_args);
311
-        }
312
-        return $check_if_custom && ! empty($template_path) ? true : $template_path;
313
-    }
314
-
315
-
316
-    /**
317
-     * _find_common_base_path
318
-     * given two paths, this determines if there is a common base path between the two
319
-     *
320
-     * @param array $paths
321
-     * @return string
322
-     */
323
-    protected static function _find_common_base_path($paths)
324
-    {
325
-        $last_offset      = 0;
326
-        $common_base_path = '';
327
-        while (($index = strpos($paths[0], '/', $last_offset)) !== false) {
328
-            $dir_length = $index - $last_offset + 1;
329
-            $directory  = substr($paths[0], $last_offset, $dir_length);
330
-            foreach ($paths as $path) {
331
-                if (substr($path, $last_offset, $dir_length) != $directory) {
332
-                    return $common_base_path;
333
-                }
334
-            }
335
-            $common_base_path .= $directory;
336
-            $last_offset      = $index + 1;
337
-        }
338
-        return substr($common_base_path, 0, -1);
339
-    }
340
-
341
-
342
-    /**
343
-     * load and display a template
344
-     *
345
-     * @param bool|string $template_path    server path to the file to be loaded, including file name and extension
346
-     * @param array       $template_args    an array of arguments to be extracted for use in the template
347
-     * @param boolean     $return_string    whether to send output immediately to screen, or capture and return as a
348
-     *                                      string
349
-     * @param bool        $throw_exceptions if set to true, will throw an exception if the template is either
350
-     *                                      not found or is not readable
351
-     * @return string
352
-     * @throws DomainException
353
-     */
354
-    public static function display_template(
355
-        $template_path = false,
356
-        $template_args = [],
357
-        $return_string = false,
358
-        $throw_exceptions = false
359
-    ) {
360
-        /**
361
-         * These two filters are intended for last minute changes to templates being loaded and/or template arg
362
-         * modifications.  NOTE... modifying these things can cause breakage as most templates running through
363
-         * the display_template method are templates we DON'T want modified (usually because of js
364
-         * dependencies etc).  So unless you know what you are doing, do NOT filter templates or template args
365
-         * using this.
366
-         *
367
-         * @since 4.6.0
368
-         */
369
-        $template_path = (string) apply_filters('FHEE__EEH_Template__display_template__template_path', $template_path);
370
-        $template_args = (array) apply_filters('FHEE__EEH_Template__display_template__template_args', $template_args);
371
-
372
-        // you gimme nuttin - YOU GET NUTTIN !!
373
-        if (! $template_path || ! is_readable($template_path)) {
374
-            // ignore whether template is accessible ?
375
-            if ($throw_exceptions) {
376
-                throw new DomainException(
377
-                    esc_html__('Invalid, unreadable, or missing file.', 'event_espresso')
378
-                );
379
-            }
380
-            return '';
381
-        }
382
-        // if $template_args are not in an array, then make it so
383
-        if (! is_array($template_args) && ! is_object($template_args)) {
384
-            $template_args = [$template_args];
385
-        }
386
-        extract($template_args, EXTR_SKIP);
387
-
388
-        if ($return_string) {
389
-            // because we want to return a string, we are going to capture the output
390
-            ob_start();
391
-            include($template_path);
392
-            return ob_get_clean();
393
-        }
394
-        include($template_path);
395
-        return '';
396
-    }
397
-
398
-
399
-    /**
400
-     * get_object_css_class - attempts to generate a css class based on the type of EE object passed
401
-     *
402
-     * @param EE_Base_Class $object the EE object the css class is being generated for
403
-     * @param string        $prefix added to the beginning of the generated class
404
-     * @param string        $suffix added to the end of the generated class
405
-     * @return string
406
-     * @throws EE_Error
407
-     * @throws ReflectionException
408
-     */
409
-    public static function get_object_css_class($object = null, $prefix = '', $suffix = '')
410
-    {
411
-        // in the beginning...
412
-        $prefix = ! empty($prefix) ? rtrim($prefix, '-') . '-' : '';
413
-        // da muddle
414
-        $class = '';
415
-        // the end
416
-        $suffix = ! empty($suffix) ? '-' . ltrim($suffix, '-') : '';
417
-        // is the passed object an EE object ?
418
-        if ($object instanceof EE_Base_Class) {
419
-            // grab the exact type of object
420
-            $obj_class = get_class($object);
421
-            // depending on the type of object...
422
-            switch ($obj_class) {
423
-                // no specifics just yet...
424
-                default:
425
-                    $class = strtolower(str_replace('_', '-', $obj_class));
426
-                    $class .= method_exists($obj_class, 'name') ? '-' . sanitize_title($object->name()) : '';
427
-            }
428
-        }
429
-        return $prefix . $class . $suffix;
430
-    }
431
-
432
-
433
-    /**
434
-     * EEH_Template::format_currency
435
-     * This helper takes a raw float value and formats it according to the default config country currency settings, or
436
-     * the country currency settings from the supplied country ISO code
437
-     *
438
-     * @param float   $amount       raw money value
439
-     * @param boolean $return_raw   whether to return the formatted float value only with no currency sign or code
440
-     * @param boolean $display_code whether to display the country code (USD). Default = TRUE
441
-     * @param string  $CNT_ISO      2 letter ISO code for a country
442
-     * @param string  $cur_code_span_class
443
-     * @return string        the html output for the formatted money value
444
-     */
445
-    public static function format_currency(
446
-        $amount = null,
447
-        $return_raw = false,
448
-        $display_code = true,
449
-        $CNT_ISO = '',
450
-        $cur_code_span_class = 'currency-code'
451
-    ) {
452
-        // ensure amount was received
453
-        if ($amount === null) {
454
-            $msg = esc_html__('In order to format currency, an amount needs to be passed.', 'event_espresso');
455
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
456
-            return '';
457
-        }
458
-        // ensure amount is float
459
-        $amount  = (float) apply_filters('FHEE__EEH_Template__format_currency__raw_amount', (float) $amount);
460
-        $CNT_ISO = apply_filters('FHEE__EEH_Template__format_currency__CNT_ISO', $CNT_ISO, $amount);
461
-        // filter raw amount (allows 0.00 to be changed to "free" for example)
462
-        $amount_formatted = apply_filters('FHEE__EEH_Template__format_currency__amount', $amount, $return_raw);
463
-        // still a number, or was amount converted to a string like "free" ?
464
-        if (! is_float($amount_formatted)) {
465
-            return esc_html($amount_formatted);
466
-        }
467
-        try {
468
-            // was a country ISO code passed ? if so generate currency config object for that country
469
-            $mny = $CNT_ISO !== '' ? new EE_Currency_Config($CNT_ISO) : null;
470
-        } catch (Exception $e) {
471
-            // eat exception
472
-            $mny = null;
473
-        }
474
-        // verify results
475
-        if (! $mny instanceof EE_Currency_Config) {
476
-            // set default config country currency settings
477
-            $mny = EE_Registry::instance()->CFG->currency instanceof EE_Currency_Config
478
-                ? EE_Registry::instance()->CFG->currency
479
-                : new EE_Currency_Config();
480
-        }
481
-        // format float
482
-        $amount_formatted = number_format($amount, $mny->dec_plc, $mny->dec_mrk, $mny->thsnds);
483
-        // add formatting ?
484
-        if (! $return_raw) {
485
-            // add currency sign
486
-            if ($mny->sign_b4) {
487
-                if ($amount >= 0) {
488
-                    $amount_formatted = $mny->sign . $amount_formatted;
489
-                } else {
490
-                    $amount_formatted = '-' . $mny->sign . str_replace('-', '', $amount_formatted);
491
-                }
492
-            } else {
493
-                $amount_formatted = $amount_formatted . $mny->sign;
494
-            }
495
-
496
-            // filter to allow global setting of display_code
497
-            $display_code = (bool) apply_filters(
498
-                'FHEE__EEH_Template__format_currency__display_code',
499
-                $display_code
500
-            );
501
-
502
-            // add currency code ?
503
-            $amount_formatted = $display_code
504
-                ? $amount_formatted . ' <span class="' . $cur_code_span_class . '">(' . $mny->code . ')</span>'
505
-                : $amount_formatted;
506
-        }
507
-        // filter results
508
-        $amount_formatted = apply_filters(
509
-            'FHEE__EEH_Template__format_currency__amount_formatted',
510
-            $amount_formatted,
511
-            $mny,
512
-            $return_raw
513
-        );
514
-        // clean up vars
515
-        unset($mny);
516
-        // return formatted currency amount
517
-        return $amount_formatted;
518
-    }
519
-
520
-
521
-    /**
522
-     * This function is used for outputting the localized label for a given status id in the schema requested (and
523
-     * possibly plural).  The intended use of this function is only for cases where wanting a label outside of a
524
-     * related status model or model object (i.e. in documentation etc.)
525
-     *
526
-     * @param string  $status_id  Status ID matching a registered status in the esp_status table.  If there is no
527
-     *                            match, then 'Unknown' will be returned.
528
-     * @param boolean $plural     Whether to return plural or not
529
-     * @param string  $schema     'UPPER', 'lower', or 'Sentence'
530
-     * @return string             The localized label for the status id.
531
-     * @throws EE_Error
532
-     */
533
-    public static function pretty_status($status_id, $plural = false, $schema = 'upper')
534
-    {
535
-        $status = EEM_Status::instance()->localized_status(
536
-            [$status_id => esc_html__('unknown', 'event_espresso')],
537
-            $plural,
538
-            $schema
539
-        );
540
-        return $status[ $status_id ];
541
-    }
542
-
543
-
544
-    /**
545
-     * This helper just returns a button or link for the given parameters
546
-     *
547
-     * @param string $url   the url for the link, note that `esc_url` will be called on it
548
-     * @param string $label What is the label you want displayed for the button
549
-     * @param string $class what class is used for the button (defaults to 'button--primary')
550
-     * @param string $icon
551
-     * @param string $title
552
-     * @return string the html output for the button
553
-     */
554
-    public static function get_button_or_link($url, $label, $class = 'button button--primary', $icon = '', $title = '')
555
-    {
556
-        $icon_html = '';
557
-        if (! empty($icon)) {
558
-            $dashicons = preg_split("(ee-icon |dashicons )", $icon);
559
-            $dashicons = array_filter($dashicons);
560
-            $count     = count($dashicons);
561
-            $icon_html .= $count > 1 ? '<span class="ee-composite-dashicon">' : '';
562
-            foreach ($dashicons as $dashicon) {
563
-                $type      = strpos($dashicon, 'ee-icon') !== false ? 'ee-icon ' : 'dashicons ';
564
-                $icon_html .= '<span class="' . $type . $dashicon . '"></span>';
565
-            }
566
-            $icon_html .= $count > 1 ? '</span>' : '';
567
-        }
568
-        // sanitize & escape
569
-        $id    = sanitize_title_with_dashes($label);
570
-        $url   = esc_url_raw($url);
571
-        $class = esc_attr($class);
572
-        $title = esc_attr($title);
573
-        $class .= $title ? ' ee-aria-tooltip' : '';
574
-        $title = $title ? " aria-label='{$title}'" : '';
575
-        $label = esc_html($label);
576
-        return "<a id='{$id}' href='{$url}' class='{$class}'{$title}>{$icon_html}{$label}</a>";
577
-    }
578
-
579
-
580
-    /**
581
-     * This returns a generated link that will load the related help tab on admin pages.
582
-     *
583
-     * @param string      $help_tab_id the id for the connected help tab
584
-     * @param bool|string $page        The page identifier for the page the help tab is on
585
-     * @param bool|string $action      The action (route) for the admin page the help tab is on.
586
-     * @param bool|string $icon_style  (optional) include css class for the style you want to use for the help icon.
587
-     * @param bool|string $help_text   (optional) send help text you want to use for the link if default not to be used
588
-     * @return string              generated link
589
-     */
590
-    public static function get_help_tab_link(
591
-        $help_tab_id,
592
-        $page = false,
593
-        $action = false,
594
-        $icon_style = false,
595
-        $help_text = false
596
-    ) {
597
-        $allowedtags = AllowedTags::getAllowedTags();
598
-        /** @var RequestInterface $request */
599
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
600
-        $page    = $page ?: $request->getRequestParam('page', '', 'key');
601
-        $action  = $action ?: $request->getRequestParam('action', 'default', 'key');
602
-
603
-
604
-        $help_tab_lnk = $page . '-' . $action . '-' . $help_tab_id;
605
-        $icon         = ! $icon_style ? 'dashicons-editor-help' : $icon_style;
606
-        $help_text    = ! $help_text ? '' : $help_text;
607
-        return '
53
+	private static $_espresso_themes = [];
54
+
55
+
56
+	/**
57
+	 *    is_espresso_theme - returns TRUE or FALSE on whether the currently active WP theme is an espresso theme
58
+	 *
59
+	 * @return boolean
60
+	 */
61
+	public static function is_espresso_theme()
62
+	{
63
+		return wp_get_theme()->get('TextDomain') === 'event_espresso';
64
+	}
65
+
66
+
67
+	/**
68
+	 *    load_espresso_theme_functions - if current theme is an espresso theme, or uses ee theme template parts, then
69
+	 *    load its functions.php file ( if not already loaded )
70
+	 *
71
+	 * @return void
72
+	 */
73
+	public static function load_espresso_theme_functions()
74
+	{
75
+		if (! defined('EE_THEME_FUNCTIONS_LOADED')) {
76
+			if (is_readable(EE_PUBLIC . EE_Config::get_current_theme() . '/functions.php')) {
77
+				require_once(EE_PUBLIC . EE_Config::get_current_theme() . '/functions.php');
78
+			}
79
+		}
80
+	}
81
+
82
+
83
+	/**
84
+	 *    get_espresso_themes - returns an array of Espresso Child themes located in the /templates/ directory
85
+	 *
86
+	 * @return array
87
+	 */
88
+	public static function get_espresso_themes()
89
+	{
90
+		if (empty(EEH_Template::$_espresso_themes)) {
91
+			$espresso_themes = glob(EE_PUBLIC . '*', GLOB_ONLYDIR);
92
+			if (empty($espresso_themes)) {
93
+				return [];
94
+			}
95
+			if (($key = array_search('global_assets', $espresso_themes)) !== false) {
96
+				unset($espresso_themes[ $key ]);
97
+			}
98
+			EEH_Template::$_espresso_themes = [];
99
+			foreach ($espresso_themes as $espresso_theme) {
100
+				EEH_Template::$_espresso_themes[ basename($espresso_theme) ] = $espresso_theme;
101
+			}
102
+		}
103
+		return EEH_Template::$_espresso_themes;
104
+	}
105
+
106
+
107
+	/**
108
+	 * EEH_Template::get_template_part
109
+	 * basically a copy of the WordPress get_template_part() function but uses EEH_Template::locate_template() instead,
110
+	 * and doesn't add base versions of files so not a very useful function at all except that it adds familiarity PLUS
111
+	 * filtering based off of the entire template part name
112
+	 *
113
+	 * @param string $slug The slug name for the generic template.
114
+	 * @param string $name The name of the specialised template.
115
+	 * @param array  $template_args
116
+	 * @param bool   $return_string
117
+	 * @return string        the html output for the formatted money value
118
+	 */
119
+	public static function get_template_part(
120
+		$slug = null,
121
+		$name = null,
122
+		$template_args = [],
123
+		$return_string = false
124
+	) {
125
+		do_action("get_template_part_{$slug}-{$name}", $slug, $name);
126
+		$templates = [];
127
+		$name      = (string) $name;
128
+		if ($name != '') {
129
+			$templates[] = "{$slug}-{$name}.php";
130
+		}
131
+		// allow template parts to be turned off via something like:
132
+		// add_filter( 'FHEE__content_espresso_events_tickets_template__display_datetimes', '__return_false' );
133
+		if (apply_filters("FHEE__EEH_Template__get_template_part__display__{$slug}_{$name}", true)) {
134
+			return EEH_Template::locate_template($templates, $template_args, true, $return_string);
135
+		}
136
+		return '';
137
+	}
138
+
139
+
140
+	/**
141
+	 *    locate_template
142
+	 *    locate a template file by looking in the following places, in the following order:
143
+	 *        <server path up to>/wp-content/themes/<current active WordPress theme>/
144
+	 *        <assumed full absolute server path>
145
+	 *        <server path up to>/wp-content/uploads/espresso/templates/<current EE theme>/
146
+	 *        <server path up to>/wp-content/uploads/espresso/templates/
147
+	 *        <server path up to>/wp-content/plugins/<EE4 folder>/public/<current EE theme>/
148
+	 *        <server path up to>/wp-content/plugins/<EE4 folder>/core/templates/<current EE theme>/
149
+	 *        <server path up to>/wp-content/plugins/<EE4 folder>/
150
+	 *    as soon as the template is found in one of these locations, it will be returned or loaded
151
+	 *        Example:
152
+	 *          You are using the WordPress Twenty Sixteen theme,
153
+	 *        and you want to customize the "some-event.template.php" template,
154
+	 *          which is located in the "/relative/path/to/" folder relative to the main EE plugin folder.
155
+	 *          Assuming WP is installed on your server in the "/home/public_html/" folder,
156
+	 *        EEH_Template::locate_template() will look at the following paths in order until the template is found:
157
+	 *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
158
+	 *        /relative/path/to/some-event.template.php
159
+	 *        /home/public_html/wp-content/uploads/espresso/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
160
+	 *        /home/public_html/wp-content/uploads/espresso/templates/relative/path/to/some-event.template.php
161
+	 *        /home/public_html/wp-content/plugins/event-espresso-core-reg/public/Espresso_Arabica_2014/relative/path/to/some-event.template.php
162
+	 *        /home/public_html/wp-content/plugins/event-espresso-core-reg/core/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
163
+	 *        /home/public_html/wp-content/plugins/event-espresso-core-reg/relative/path/to/some-event.template.php
164
+	 *          Had you passed an absolute path to your template that was in some other location,
165
+	 *        ie: "/absolute/path/to/some-event.template.php"
166
+	 *          then the search would have been :
167
+	 *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
168
+	 *        /absolute/path/to/some-event.template.php
169
+	 *          and stopped there upon finding it in the second location
170
+	 *
171
+	 * @param array|string $templates       array of template file names including extension (or just a single string)
172
+	 * @param array        $template_args   an array of arguments to be extracted for use in the template
173
+	 * @param boolean      $load            whether to pass the located template path on to the
174
+	 *                                      EEH_Template::display_template() method or simply return it
175
+	 * @param boolean      $return_string   whether to send output immediately to screen, or capture and return as a
176
+	 *                                      string
177
+	 * @param boolean      $check_if_custom If TRUE, this flags this method to return boolean for whether this will
178
+	 *                                      generate a custom template or not. Used in places where you don't actually
179
+	 *                                      load the template, you just want to know if there's a custom version of it.
180
+	 * @return mixed
181
+	 * @throws DomainException
182
+	 * @throws InvalidArgumentException
183
+	 * @throws InvalidDataTypeException
184
+	 * @throws InvalidInterfaceException
185
+	 */
186
+	public static function locate_template(
187
+		$templates = [],
188
+		$template_args = [],
189
+		$load = true,
190
+		$return_string = true,
191
+		$check_if_custom = false
192
+	) {
193
+		// first use WP locate_template to check for template in the current theme folder
194
+		$template_path = locate_template($templates);
195
+
196
+		if ($check_if_custom && ! empty($template_path)) {
197
+			return true;
198
+		}
199
+
200
+		// not in the theme
201
+		if (empty($template_path)) {
202
+			// not even a template to look for ?
203
+			if (empty($templates)) {
204
+				$loader = LoaderFactory::getLoader();
205
+				/** @var RequestInterface $request */
206
+				$request = $loader->getShared(RequestInterface::class);
207
+				// get post_type
208
+				$post_type = $request->getRequestParam('post_type');
209
+				/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
210
+				$custom_post_types = $loader->getShared(
211
+					'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
212
+				);
213
+				// get array of EE Custom Post Types
214
+				$EE_CPTs = $custom_post_types->getDefinitions();
215
+				// build template name based on request
216
+				if (isset($EE_CPTs[ $post_type ])) {
217
+					$archive_or_single = is_archive() ? 'archive' : '';
218
+					$archive_or_single = is_single() ? 'single' : $archive_or_single;
219
+					$templates         = $archive_or_single . '-' . $post_type . '.php';
220
+				}
221
+			}
222
+			// currently active EE template theme
223
+			$current_theme = EE_Config::get_current_theme();
224
+
225
+			// array of paths to folders that may contain templates
226
+			$template_folder_paths = [
227
+				// first check the /wp-content/uploads/espresso/templates/(current EE theme)/  folder for an EE theme template file
228
+				EVENT_ESPRESSO_TEMPLATE_DIR . $current_theme,
229
+				// then in the root of the /wp-content/uploads/espresso/templates/ folder
230
+				EVENT_ESPRESSO_TEMPLATE_DIR,
231
+			];
232
+
233
+			// add core plugin folders for checking only if we're not $check_if_custom
234
+			if (! $check_if_custom) {
235
+				$core_paths            = [
236
+					// in the  /wp-content/plugins/(EE4 folder)/public/(current EE theme)/ folder within the plugin
237
+					EE_PUBLIC . $current_theme,
238
+					// in the  /wp-content/plugins/(EE4 folder)/core/templates/(current EE theme)/ folder within the plugin
239
+					EE_TEMPLATES . $current_theme,
240
+					// or maybe relative from the plugin root: /wp-content/plugins/(EE4 folder)/
241
+					EE_PLUGIN_DIR_PATH,
242
+				];
243
+				$template_folder_paths = array_merge($template_folder_paths, $core_paths);
244
+			}
245
+
246
+			// now filter that array
247
+			$template_folder_paths = apply_filters(
248
+				'FHEE__EEH_Template__locate_template__template_folder_paths',
249
+				$template_folder_paths
250
+			);
251
+			$templates             = is_array($templates) ? $templates : [$templates];
252
+			$template_folder_paths =
253
+				is_array($template_folder_paths) ? $template_folder_paths : [$template_folder_paths];
254
+			// array to hold all possible template paths
255
+			$full_template_paths = [];
256
+			$file_name           = '';
257
+
258
+			// loop through $templates
259
+			foreach ($templates as $template) {
260
+				// normalize directory separators
261
+				$template                      = EEH_File::standardise_directory_separators($template);
262
+				$file_name                     = basename($template);
263
+				$template_path_minus_file_name = substr($template, 0, (strlen($file_name) * -1));
264
+				// while looping through all template folder paths
265
+				foreach ($template_folder_paths as $template_folder_path) {
266
+					// normalize directory separators
267
+					$template_folder_path = EEH_File::standardise_directory_separators($template_folder_path);
268
+					// determine if any common base path exists between the two paths
269
+					$common_base_path = EEH_Template::_find_common_base_path(
270
+						[$template_folder_path, $template_path_minus_file_name]
271
+					);
272
+					if ($common_base_path !== '') {
273
+						// both paths have a common base, so just tack the filename onto our search path
274
+						$resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $file_name;
275
+					} else {
276
+						// no common base path, so let's just concatenate
277
+						$resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $template;
278
+					}
279
+					// build up our template locations array by adding our resolved paths
280
+					$full_template_paths[] = $resolved_path;
281
+				}
282
+				// if $template is an absolute path, then we'll tack it onto the start of our array so that it gets searched first
283
+				array_unshift($full_template_paths, $template);
284
+				// path to the directory of the current theme: /wp-content/themes/(current WP theme)/
285
+				array_unshift($full_template_paths, get_stylesheet_directory() . '/' . $file_name);
286
+			}
287
+			// filter final array of full template paths
288
+			$full_template_paths = apply_filters(
289
+				'FHEE__EEH_Template__locate_template__full_template_paths',
290
+				$full_template_paths,
291
+				$file_name
292
+			);
293
+			// now loop through our final array of template location paths and check each location
294
+			foreach ((array) $full_template_paths as $full_template_path) {
295
+				if (is_readable($full_template_path)) {
296
+					$template_path = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $full_template_path);
297
+					break;
298
+				}
299
+			}
300
+		}
301
+
302
+		// hook that can be used to display the full template path that will be used
303
+		do_action('AHEE__EEH_Template__locate_template__full_template_path', $template_path);
304
+
305
+		// if we got it and you want to see it...
306
+		if ($template_path && $load && ! $check_if_custom) {
307
+			if ($return_string) {
308
+				return EEH_Template::display_template($template_path, $template_args, true);
309
+			}
310
+			EEH_Template::display_template($template_path, $template_args);
311
+		}
312
+		return $check_if_custom && ! empty($template_path) ? true : $template_path;
313
+	}
314
+
315
+
316
+	/**
317
+	 * _find_common_base_path
318
+	 * given two paths, this determines if there is a common base path between the two
319
+	 *
320
+	 * @param array $paths
321
+	 * @return string
322
+	 */
323
+	protected static function _find_common_base_path($paths)
324
+	{
325
+		$last_offset      = 0;
326
+		$common_base_path = '';
327
+		while (($index = strpos($paths[0], '/', $last_offset)) !== false) {
328
+			$dir_length = $index - $last_offset + 1;
329
+			$directory  = substr($paths[0], $last_offset, $dir_length);
330
+			foreach ($paths as $path) {
331
+				if (substr($path, $last_offset, $dir_length) != $directory) {
332
+					return $common_base_path;
333
+				}
334
+			}
335
+			$common_base_path .= $directory;
336
+			$last_offset      = $index + 1;
337
+		}
338
+		return substr($common_base_path, 0, -1);
339
+	}
340
+
341
+
342
+	/**
343
+	 * load and display a template
344
+	 *
345
+	 * @param bool|string $template_path    server path to the file to be loaded, including file name and extension
346
+	 * @param array       $template_args    an array of arguments to be extracted for use in the template
347
+	 * @param boolean     $return_string    whether to send output immediately to screen, or capture and return as a
348
+	 *                                      string
349
+	 * @param bool        $throw_exceptions if set to true, will throw an exception if the template is either
350
+	 *                                      not found or is not readable
351
+	 * @return string
352
+	 * @throws DomainException
353
+	 */
354
+	public static function display_template(
355
+		$template_path = false,
356
+		$template_args = [],
357
+		$return_string = false,
358
+		$throw_exceptions = false
359
+	) {
360
+		/**
361
+		 * These two filters are intended for last minute changes to templates being loaded and/or template arg
362
+		 * modifications.  NOTE... modifying these things can cause breakage as most templates running through
363
+		 * the display_template method are templates we DON'T want modified (usually because of js
364
+		 * dependencies etc).  So unless you know what you are doing, do NOT filter templates or template args
365
+		 * using this.
366
+		 *
367
+		 * @since 4.6.0
368
+		 */
369
+		$template_path = (string) apply_filters('FHEE__EEH_Template__display_template__template_path', $template_path);
370
+		$template_args = (array) apply_filters('FHEE__EEH_Template__display_template__template_args', $template_args);
371
+
372
+		// you gimme nuttin - YOU GET NUTTIN !!
373
+		if (! $template_path || ! is_readable($template_path)) {
374
+			// ignore whether template is accessible ?
375
+			if ($throw_exceptions) {
376
+				throw new DomainException(
377
+					esc_html__('Invalid, unreadable, or missing file.', 'event_espresso')
378
+				);
379
+			}
380
+			return '';
381
+		}
382
+		// if $template_args are not in an array, then make it so
383
+		if (! is_array($template_args) && ! is_object($template_args)) {
384
+			$template_args = [$template_args];
385
+		}
386
+		extract($template_args, EXTR_SKIP);
387
+
388
+		if ($return_string) {
389
+			// because we want to return a string, we are going to capture the output
390
+			ob_start();
391
+			include($template_path);
392
+			return ob_get_clean();
393
+		}
394
+		include($template_path);
395
+		return '';
396
+	}
397
+
398
+
399
+	/**
400
+	 * get_object_css_class - attempts to generate a css class based on the type of EE object passed
401
+	 *
402
+	 * @param EE_Base_Class $object the EE object the css class is being generated for
403
+	 * @param string        $prefix added to the beginning of the generated class
404
+	 * @param string        $suffix added to the end of the generated class
405
+	 * @return string
406
+	 * @throws EE_Error
407
+	 * @throws ReflectionException
408
+	 */
409
+	public static function get_object_css_class($object = null, $prefix = '', $suffix = '')
410
+	{
411
+		// in the beginning...
412
+		$prefix = ! empty($prefix) ? rtrim($prefix, '-') . '-' : '';
413
+		// da muddle
414
+		$class = '';
415
+		// the end
416
+		$suffix = ! empty($suffix) ? '-' . ltrim($suffix, '-') : '';
417
+		// is the passed object an EE object ?
418
+		if ($object instanceof EE_Base_Class) {
419
+			// grab the exact type of object
420
+			$obj_class = get_class($object);
421
+			// depending on the type of object...
422
+			switch ($obj_class) {
423
+				// no specifics just yet...
424
+				default:
425
+					$class = strtolower(str_replace('_', '-', $obj_class));
426
+					$class .= method_exists($obj_class, 'name') ? '-' . sanitize_title($object->name()) : '';
427
+			}
428
+		}
429
+		return $prefix . $class . $suffix;
430
+	}
431
+
432
+
433
+	/**
434
+	 * EEH_Template::format_currency
435
+	 * This helper takes a raw float value and formats it according to the default config country currency settings, or
436
+	 * the country currency settings from the supplied country ISO code
437
+	 *
438
+	 * @param float   $amount       raw money value
439
+	 * @param boolean $return_raw   whether to return the formatted float value only with no currency sign or code
440
+	 * @param boolean $display_code whether to display the country code (USD). Default = TRUE
441
+	 * @param string  $CNT_ISO      2 letter ISO code for a country
442
+	 * @param string  $cur_code_span_class
443
+	 * @return string        the html output for the formatted money value
444
+	 */
445
+	public static function format_currency(
446
+		$amount = null,
447
+		$return_raw = false,
448
+		$display_code = true,
449
+		$CNT_ISO = '',
450
+		$cur_code_span_class = 'currency-code'
451
+	) {
452
+		// ensure amount was received
453
+		if ($amount === null) {
454
+			$msg = esc_html__('In order to format currency, an amount needs to be passed.', 'event_espresso');
455
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
456
+			return '';
457
+		}
458
+		// ensure amount is float
459
+		$amount  = (float) apply_filters('FHEE__EEH_Template__format_currency__raw_amount', (float) $amount);
460
+		$CNT_ISO = apply_filters('FHEE__EEH_Template__format_currency__CNT_ISO', $CNT_ISO, $amount);
461
+		// filter raw amount (allows 0.00 to be changed to "free" for example)
462
+		$amount_formatted = apply_filters('FHEE__EEH_Template__format_currency__amount', $amount, $return_raw);
463
+		// still a number, or was amount converted to a string like "free" ?
464
+		if (! is_float($amount_formatted)) {
465
+			return esc_html($amount_formatted);
466
+		}
467
+		try {
468
+			// was a country ISO code passed ? if so generate currency config object for that country
469
+			$mny = $CNT_ISO !== '' ? new EE_Currency_Config($CNT_ISO) : null;
470
+		} catch (Exception $e) {
471
+			// eat exception
472
+			$mny = null;
473
+		}
474
+		// verify results
475
+		if (! $mny instanceof EE_Currency_Config) {
476
+			// set default config country currency settings
477
+			$mny = EE_Registry::instance()->CFG->currency instanceof EE_Currency_Config
478
+				? EE_Registry::instance()->CFG->currency
479
+				: new EE_Currency_Config();
480
+		}
481
+		// format float
482
+		$amount_formatted = number_format($amount, $mny->dec_plc, $mny->dec_mrk, $mny->thsnds);
483
+		// add formatting ?
484
+		if (! $return_raw) {
485
+			// add currency sign
486
+			if ($mny->sign_b4) {
487
+				if ($amount >= 0) {
488
+					$amount_formatted = $mny->sign . $amount_formatted;
489
+				} else {
490
+					$amount_formatted = '-' . $mny->sign . str_replace('-', '', $amount_formatted);
491
+				}
492
+			} else {
493
+				$amount_formatted = $amount_formatted . $mny->sign;
494
+			}
495
+
496
+			// filter to allow global setting of display_code
497
+			$display_code = (bool) apply_filters(
498
+				'FHEE__EEH_Template__format_currency__display_code',
499
+				$display_code
500
+			);
501
+
502
+			// add currency code ?
503
+			$amount_formatted = $display_code
504
+				? $amount_formatted . ' <span class="' . $cur_code_span_class . '">(' . $mny->code . ')</span>'
505
+				: $amount_formatted;
506
+		}
507
+		// filter results
508
+		$amount_formatted = apply_filters(
509
+			'FHEE__EEH_Template__format_currency__amount_formatted',
510
+			$amount_formatted,
511
+			$mny,
512
+			$return_raw
513
+		);
514
+		// clean up vars
515
+		unset($mny);
516
+		// return formatted currency amount
517
+		return $amount_formatted;
518
+	}
519
+
520
+
521
+	/**
522
+	 * This function is used for outputting the localized label for a given status id in the schema requested (and
523
+	 * possibly plural).  The intended use of this function is only for cases where wanting a label outside of a
524
+	 * related status model or model object (i.e. in documentation etc.)
525
+	 *
526
+	 * @param string  $status_id  Status ID matching a registered status in the esp_status table.  If there is no
527
+	 *                            match, then 'Unknown' will be returned.
528
+	 * @param boolean $plural     Whether to return plural or not
529
+	 * @param string  $schema     'UPPER', 'lower', or 'Sentence'
530
+	 * @return string             The localized label for the status id.
531
+	 * @throws EE_Error
532
+	 */
533
+	public static function pretty_status($status_id, $plural = false, $schema = 'upper')
534
+	{
535
+		$status = EEM_Status::instance()->localized_status(
536
+			[$status_id => esc_html__('unknown', 'event_espresso')],
537
+			$plural,
538
+			$schema
539
+		);
540
+		return $status[ $status_id ];
541
+	}
542
+
543
+
544
+	/**
545
+	 * This helper just returns a button or link for the given parameters
546
+	 *
547
+	 * @param string $url   the url for the link, note that `esc_url` will be called on it
548
+	 * @param string $label What is the label you want displayed for the button
549
+	 * @param string $class what class is used for the button (defaults to 'button--primary')
550
+	 * @param string $icon
551
+	 * @param string $title
552
+	 * @return string the html output for the button
553
+	 */
554
+	public static function get_button_or_link($url, $label, $class = 'button button--primary', $icon = '', $title = '')
555
+	{
556
+		$icon_html = '';
557
+		if (! empty($icon)) {
558
+			$dashicons = preg_split("(ee-icon |dashicons )", $icon);
559
+			$dashicons = array_filter($dashicons);
560
+			$count     = count($dashicons);
561
+			$icon_html .= $count > 1 ? '<span class="ee-composite-dashicon">' : '';
562
+			foreach ($dashicons as $dashicon) {
563
+				$type      = strpos($dashicon, 'ee-icon') !== false ? 'ee-icon ' : 'dashicons ';
564
+				$icon_html .= '<span class="' . $type . $dashicon . '"></span>';
565
+			}
566
+			$icon_html .= $count > 1 ? '</span>' : '';
567
+		}
568
+		// sanitize & escape
569
+		$id    = sanitize_title_with_dashes($label);
570
+		$url   = esc_url_raw($url);
571
+		$class = esc_attr($class);
572
+		$title = esc_attr($title);
573
+		$class .= $title ? ' ee-aria-tooltip' : '';
574
+		$title = $title ? " aria-label='{$title}'" : '';
575
+		$label = esc_html($label);
576
+		return "<a id='{$id}' href='{$url}' class='{$class}'{$title}>{$icon_html}{$label}</a>";
577
+	}
578
+
579
+
580
+	/**
581
+	 * This returns a generated link that will load the related help tab on admin pages.
582
+	 *
583
+	 * @param string      $help_tab_id the id for the connected help tab
584
+	 * @param bool|string $page        The page identifier for the page the help tab is on
585
+	 * @param bool|string $action      The action (route) for the admin page the help tab is on.
586
+	 * @param bool|string $icon_style  (optional) include css class for the style you want to use for the help icon.
587
+	 * @param bool|string $help_text   (optional) send help text you want to use for the link if default not to be used
588
+	 * @return string              generated link
589
+	 */
590
+	public static function get_help_tab_link(
591
+		$help_tab_id,
592
+		$page = false,
593
+		$action = false,
594
+		$icon_style = false,
595
+		$help_text = false
596
+	) {
597
+		$allowedtags = AllowedTags::getAllowedTags();
598
+		/** @var RequestInterface $request */
599
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
600
+		$page    = $page ?: $request->getRequestParam('page', '', 'key');
601
+		$action  = $action ?: $request->getRequestParam('action', 'default', 'key');
602
+
603
+
604
+		$help_tab_lnk = $page . '-' . $action . '-' . $help_tab_id;
605
+		$icon         = ! $icon_style ? 'dashicons-editor-help' : $icon_style;
606
+		$help_text    = ! $help_text ? '' : $help_text;
607
+		return '
608 608
             <a id="' . esc_attr($help_tab_lnk) . '"
609 609
                class="espresso-help-tab-lnk ee-help-btn ee-aria-tooltip dashicons ' . esc_attr($icon) . '"
610 610
                aria-label="' . esc_attr__(
611
-                   'Click to open the \'Help\' tab for more information about this feature.',
612
-                   'event_espresso'
613
-               ) . '"
611
+				   'Click to open the \'Help\' tab for more information about this feature.',
612
+				   'event_espresso'
613
+			   ) . '"
614 614
             >
615 615
                 ' . wp_kses($help_text, $allowedtags) . '
616 616
             </a>';
617
-    }
618
-
619
-
620
-    /**
621
-     * This is a helper method to generate a status legend for a given status array.
622
-     * Note this will only work if the incoming statuses have a key in the EEM_Status->localized_status() methods
623
-     * status_array.
624
-     *
625
-     * @param array  $status_array   array of statuses that will make up the legend. In format:
626
-     *                               array(
627
-     *                               'status_item' => 'status_name'
628
-     *                               )
629
-     * @param string $active_status  This is used to indicate what the active status is IF that is to be highlighted in
630
-     *                               the legend.
631
-     * @return string               html structure for status.
632
-     * @throws EE_Error
633
-     */
634
-    public static function status_legend($status_array, $active_status = '')
635
-    {
636
-        if (! is_array($status_array)) {
637
-            throw new EE_Error(
638
-                esc_html__(
639
-                    'The EEH_Template::status_legend helper required the incoming status_array argument to be an array!',
640
-                    'event_espresso'
641
-                )
642
-            );
643
-        }
644
-
645
-        $content = '
617
+	}
618
+
619
+
620
+	/**
621
+	 * This is a helper method to generate a status legend for a given status array.
622
+	 * Note this will only work if the incoming statuses have a key in the EEM_Status->localized_status() methods
623
+	 * status_array.
624
+	 *
625
+	 * @param array  $status_array   array of statuses that will make up the legend. In format:
626
+	 *                               array(
627
+	 *                               'status_item' => 'status_name'
628
+	 *                               )
629
+	 * @param string $active_status  This is used to indicate what the active status is IF that is to be highlighted in
630
+	 *                               the legend.
631
+	 * @return string               html structure for status.
632
+	 * @throws EE_Error
633
+	 */
634
+	public static function status_legend($status_array, $active_status = '')
635
+	{
636
+		if (! is_array($status_array)) {
637
+			throw new EE_Error(
638
+				esc_html__(
639
+					'The EEH_Template::status_legend helper required the incoming status_array argument to be an array!',
640
+					'event_espresso'
641
+				)
642
+			);
643
+		}
644
+
645
+		$content = '
646 646
             <div class="ee-list-table-legend-container">
647 647
                 <h4 class="status-legend-title">
648 648
                     ' . esc_html__('Status Legend', 'event_espresso') . '
649 649
                 </h4>
650 650
                 <dl class="ee-list-table-legend">';
651 651
 
652
-        foreach ($status_array as $item => $status) {
653
-            $active_class = $active_status == $status ? 'class="ee-is-active-status"' : '';
654
-            $content      .= '
652
+		foreach ($status_array as $item => $status) {
653
+			$active_class = $active_status == $status ? 'class="ee-is-active-status"' : '';
654
+			$content      .= '
655 655
                     <dt id="' . esc_attr('ee-legend-item-tooltip-' . $item) . '" ' . $active_class . '>
656 656
                         <span class="' . esc_attr('ee-status-legend ee-status-bg--' . $status) . '"></span>
657 657
                         <span class="ee-legend-description">
658 658
                             ' . EEH_Template::pretty_status($status, false, 'sentence') . '
659 659
                         </span>
660 660
                     </dt>';
661
-        }
661
+		}
662 662
 
663
-        $content .= '
663
+		$content .= '
664 664
                 </dl>
665 665
             </div>
666 666
 ';
667
-        return $content;
668
-    }
669
-
670
-
671
-    /**
672
-     * Gets HTML for laying out a deeply-nested array (and objects) in a format
673
-     * that's nice for presenting in the wp admin
674
-     *
675
-     * @param mixed $data
676
-     * @return string
677
-     */
678
-    public static function layout_array_as_table($data)
679
-    {
680
-        if (is_object($data) || $data instanceof __PHP_Incomplete_Class) {
681
-            $data = (array) $data;
682
-        }
683
-        ob_start();
684
-        if (is_array($data)) {
685
-            if (EEH_Array::is_associative_array($data)) { ?>
667
+		return $content;
668
+	}
669
+
670
+
671
+	/**
672
+	 * Gets HTML for laying out a deeply-nested array (and objects) in a format
673
+	 * that's nice for presenting in the wp admin
674
+	 *
675
+	 * @param mixed $data
676
+	 * @return string
677
+	 */
678
+	public static function layout_array_as_table($data)
679
+	{
680
+		if (is_object($data) || $data instanceof __PHP_Incomplete_Class) {
681
+			$data = (array) $data;
682
+		}
683
+		ob_start();
684
+		if (is_array($data)) {
685
+			if (EEH_Array::is_associative_array($data)) { ?>
686 686
                 <table class="widefat">
687 687
                     <tbody>
688 688
                         <?php foreach ($data as $data_key => $data_values) { ?>
@@ -700,283 +700,283 @@  discard block
 block discarded – undo
700 700
             <?php } else { ?>
701 701
                 <ul>
702 702
                     <?php
703
-                    foreach ($data as $datum) {
704
-                        echo "<li>";
705
-                        echo self::layout_array_as_table($datum);
706
-                        echo "</li>";
707
-                    } ?>
703
+					foreach ($data as $datum) {
704
+						echo "<li>";
705
+						echo self::layout_array_as_table($datum);
706
+						echo "</li>";
707
+					} ?>
708 708
                 </ul>
709 709
             <?php }
710
-        } else {
711
-            // simple value
712
-            echo esc_html($data);
713
-        }
714
-        return ob_get_clean();
715
-    }
716
-
717
-
718
-    /**
719
-     * wrapper for self::get_paging_html() that simply echos the generated paging html
720
-     *
721
-     * @param        $total_items
722
-     * @param        $current
723
-     * @param        $per_page
724
-     * @param        $url
725
-     * @param bool   $show_num_field
726
-     * @param string $paged_arg_name
727
-     * @param array  $items_label
728
-     * @see   self:get_paging_html() for argument docs.
729
-     * @since 4.4.0
730
-     */
731
-    public static function paging_html(
732
-        $total_items,
733
-        $current,
734
-        $per_page,
735
-        $url,
736
-        $show_num_field = true,
737
-        $paged_arg_name = 'paged',
738
-        $items_label = []
739
-    ) {
740
-        echo self::get_paging_html(
741
-            $total_items,
742
-            $current,
743
-            $per_page,
744
-            $url,
745
-            $show_num_field,
746
-            $paged_arg_name,
747
-            $items_label
748
-        );
749
-    }
750
-
751
-
752
-    /**
753
-     * A method for generating paging similar to WP_List_Table
754
-     *
755
-     * @param int    $total_items       How many total items there are to page.
756
-     * @param int    $current           What the current page is.
757
-     * @param int    $per_page          How many items per page.
758
-     * @param string $url               What the base url for page links is.
759
-     * @param bool   $show_num_field    Whether to show the input for changing page number.
760
-     * @param string $paged_arg_name    The name of the key for the paged query argument.
761
-     * @param array  $items_label       An array of singular/plural values for the items label:
762
-     *                                  array(
763
-     *                                  'single' => 'item',
764
-     *                                  'plural' => 'items'
765
-     *                                  )
766
-     * @return  string
767
-     * @since    4.4.0
768
-     * @see      wp-admin/includes/class-wp-list-table.php WP_List_Table::pagination()
769
-     */
770
-    public static function get_paging_html(
771
-        int $total_items,
772
-        int $current,
773
-        int $per_page,
774
-        string $url,
775
-        bool $show_num_field = true,
776
-        string $paged_arg_name = 'paged',
777
-        array $items_label = []
778
-    ): string {
779
-        $page_links     = [];
780
-        $paged_arg_name = empty($paged_arg_name) ? 'paged' : sanitize_key($paged_arg_name);
781
-
782
-        // filter items_label
783
-        $items_label = apply_filters(
784
-            'FHEE__EEH_Template__get_paging_html__items_label',
785
-            $items_label
786
-        );
787
-
788
-        if (
789
-            empty($items_label)
790
-            || ! is_array($items_label)
791
-            || ! isset($items_label['single'])
792
-            || ! isset($items_label['plural'])
793
-        ) {
794
-            $items_label = [
795
-                'single' => esc_html__('1 item', 'event_espresso'),
796
-                'plural' => esc_html__('%s items', 'event_espresso'),
797
-            ];
798
-        } else {
799
-            $items_label = [
800
-                'single' => '1 ' . esc_html($items_label['single']),
801
-                'plural' => '%s ' . esc_html($items_label['plural']),
802
-            ];
803
-        }
804
-
805
-        $total_pages = (int) ceil($total_items / $per_page);
806
-
807
-        if ($total_pages <= 1) {
808
-            return '';
809
-        }
810
-
811
-        $item_label = $total_items > 1 ? sprintf($items_label['plural'], $total_items) : $items_label['single'];
812
-
813
-        $output = '<span class="displaying-num">' . $item_label . '</span>';
814
-
815
-        $disable_first = $current === 1 ? 'disabled' : '';
816
-        $disable_last  = $current === $total_pages ? 'disabled' : '';
817
-
818
-        $button_classes = 'button button--secondary button--icon-only button--small';
819
-
820
-        $page_links[] = sprintf(
821
-            '<a class="%s" aria-label="%s" href="%s"><span class="ee-pagination-arrow">%s</span></a>',
822
-            esc_attr("first-page $button_classes $disable_first"),
823
-            esc_attr__('Go to the first page', 'event_espresso'),
824
-            esc_url_raw(remove_query_arg($paged_arg_name, $url)),
825
-            '&laquo;'
826
-        );
827
-
828
-        $page_links[] = sprintf(
829
-            '<a class="%s" aria-label="%s" href="%s"><span class="ee-pagination-arrow">%s</span></a>',
830
-            esc_attr("prev-page $button_classes $disable_first"),
831
-            esc_attr__('Go to the previous page', 'event_espresso'),
832
-            esc_url_raw(add_query_arg($paged_arg_name, max(1, $current - 1), $url)),
833
-            '&lsaquo;'
834
-        );
835
-
836
-        $html_current_page = $show_num_field
837
-            ? sprintf(
838
-                "<input class='current-page ee-input-size--small' title='%s' type='text' name=$paged_arg_name value='%s' size='%d' />",
839
-                esc_attr__('Current page', 'event_espresso'),
840
-                esc_attr($current),
841
-                strlen($total_pages)
842
-            )
843
-            : $current;
844
-
845
-        $html_total_pages = sprintf(
846
-            '<span class="total-pages">%s</span>',
847
-            number_format_i18n($total_pages)
848
-        );
849
-        $page_links[]     = sprintf(
850
-            _x('%3$s%1$s of %2$s%4$s', 'paging', 'event_espresso'),
851
-            "{$html_current_page}<span class='paging-input-of'>",
852
-            "</span>{$html_total_pages}",
853
-            '<span class="paging-input">',
854
-            '</span>'
855
-        );
856
-
857
-        $page_links[] = sprintf(
858
-            '<a class="%s" aria-label="%s" href="%s"><span class="ee-pagination-arrow">%s</span></a>',
859
-            esc_attr("next-page $button_classes $disable_last"),
860
-            esc_attr__('Go to the next page', 'event_espresso'),
861
-            esc_url_raw(add_query_arg($paged_arg_name, min($total_pages, $current + 1), $url)),
862
-            '&rsaquo;'
863
-        );
864
-
865
-        $page_links[] = sprintf(
866
-            '<a class="%s" aria-label="%s" href="%s"><span class="ee-pagination-arrow">%s</span></a>',
867
-            esc_attr("last-page $button_classes $disable_last"),
868
-            esc_attr__('Go to the last page', 'event_espresso'),
869
-            esc_url_raw(add_query_arg($paged_arg_name, $total_pages, $url)),
870
-            '&raquo;'
871
-        );
872
-
873
-        $output .= "\n" . '<span class="pagination-links">' . join("\n", $page_links) . '</span>';
874
-
875
-        $page_class = ' no-pages';
876
-        if ($total_pages) {
877
-            $page_class = $total_pages < 2 ? ' one-page' : '';
878
-        }
879
-
880
-        return '<div class="tablenav"><div class="tablenav-pages' . $page_class . '">' . $output . '</div></div>';
881
-    }
882
-
883
-
884
-    /**
885
-     * @param string $wrap_class
886
-     * @param string $wrap_id
887
-     * @return string
888
-     */
889
-    public static function powered_by_event_espresso($wrap_class = '', $wrap_id = '', array $query_args = [])
890
-    {
891
-        $admin = is_admin() && ! (defined('DOING_AJAX') && DOING_AJAX);
892
-        if (
893
-            ! $admin
894
-            && ! apply_filters(
895
-                'FHEE__EEH_Template__powered_by_event_espresso__show_reg_footer',
896
-                EE_Registry::instance()->CFG->admin->show_reg_footer
897
-            )
898
-        ) {
899
-            return '';
900
-        }
901
-        $tag        = $admin ? 'span' : 'div';
902
-        $attributes = ! empty($wrap_id) ? " id=\"{$wrap_id}\"" : '';
903
-        $wrap_class = $admin ? "{$wrap_class} float-left" : $wrap_class;
904
-        $attributes .= ! empty($wrap_class)
905
-            ? " class=\"{$wrap_class} powered-by-event-espresso-credit\""
906
-            : ' class="powered-by-event-espresso-credit"';
907
-        $query_args = array_merge(
908
-            [
909
-                'ap_id'        => EE_Registry::instance()->CFG->admin->affiliate_id(),
910
-                'utm_source'   => 'powered_by_event_espresso',
911
-                'utm_medium'   => 'link',
912
-                'utm_campaign' => 'powered_by',
913
-            ],
914
-            $query_args
915
-        );
916
-        $powered_by = apply_filters(
917
-            'FHEE__EEH_Template__powered_by_event_espresso_text',
918
-            $admin ? 'Event Espresso - ' . EVENT_ESPRESSO_VERSION : 'Event Espresso'
919
-        );
920
-        $url        = add_query_arg($query_args, 'https://eventespresso.com/');
921
-        $url        = apply_filters('FHEE__EEH_Template__powered_by_event_espresso__url', $url);
922
-        return (string) apply_filters(
923
-            'FHEE__EEH_Template__powered_by_event_espresso__html',
924
-            sprintf(
925
-                esc_html_x(
926
-                    '%3$s%1$sOnline event registration and ticketing powered by %2$s%3$s',
927
-                    'Online event registration and ticketing powered by [link to eventespresso.com]',
928
-                    'event_espresso'
929
-                ),
930
-                "<{$tag}{$attributes}>",
931
-                "<a href=\"{$url}\" target=\"_blank\" rel=\"nofollow\">{$powered_by}</a></{$tag}>",
932
-                $admin ? '' : '<br />'
933
-            ),
934
-            $wrap_class,
935
-            $wrap_id
936
-        );
937
-    }
938
-
939
-
940
-    /**
941
-     * @param string $image_name
942
-     * @return string|null
943
-     * @since   4.10.14.p
944
-     */
945
-    public static function getScreenshotUrl($image_name)
946
-    {
947
-        return esc_url_raw(EE_GLOBAL_ASSETS_URL . 'images/screenshots/' . $image_name . '.jpg');
948
-    }
710
+		} else {
711
+			// simple value
712
+			echo esc_html($data);
713
+		}
714
+		return ob_get_clean();
715
+	}
716
+
717
+
718
+	/**
719
+	 * wrapper for self::get_paging_html() that simply echos the generated paging html
720
+	 *
721
+	 * @param        $total_items
722
+	 * @param        $current
723
+	 * @param        $per_page
724
+	 * @param        $url
725
+	 * @param bool   $show_num_field
726
+	 * @param string $paged_arg_name
727
+	 * @param array  $items_label
728
+	 * @see   self:get_paging_html() for argument docs.
729
+	 * @since 4.4.0
730
+	 */
731
+	public static function paging_html(
732
+		$total_items,
733
+		$current,
734
+		$per_page,
735
+		$url,
736
+		$show_num_field = true,
737
+		$paged_arg_name = 'paged',
738
+		$items_label = []
739
+	) {
740
+		echo self::get_paging_html(
741
+			$total_items,
742
+			$current,
743
+			$per_page,
744
+			$url,
745
+			$show_num_field,
746
+			$paged_arg_name,
747
+			$items_label
748
+		);
749
+	}
750
+
751
+
752
+	/**
753
+	 * A method for generating paging similar to WP_List_Table
754
+	 *
755
+	 * @param int    $total_items       How many total items there are to page.
756
+	 * @param int    $current           What the current page is.
757
+	 * @param int    $per_page          How many items per page.
758
+	 * @param string $url               What the base url for page links is.
759
+	 * @param bool   $show_num_field    Whether to show the input for changing page number.
760
+	 * @param string $paged_arg_name    The name of the key for the paged query argument.
761
+	 * @param array  $items_label       An array of singular/plural values for the items label:
762
+	 *                                  array(
763
+	 *                                  'single' => 'item',
764
+	 *                                  'plural' => 'items'
765
+	 *                                  )
766
+	 * @return  string
767
+	 * @since    4.4.0
768
+	 * @see      wp-admin/includes/class-wp-list-table.php WP_List_Table::pagination()
769
+	 */
770
+	public static function get_paging_html(
771
+		int $total_items,
772
+		int $current,
773
+		int $per_page,
774
+		string $url,
775
+		bool $show_num_field = true,
776
+		string $paged_arg_name = 'paged',
777
+		array $items_label = []
778
+	): string {
779
+		$page_links     = [];
780
+		$paged_arg_name = empty($paged_arg_name) ? 'paged' : sanitize_key($paged_arg_name);
781
+
782
+		// filter items_label
783
+		$items_label = apply_filters(
784
+			'FHEE__EEH_Template__get_paging_html__items_label',
785
+			$items_label
786
+		);
787
+
788
+		if (
789
+			empty($items_label)
790
+			|| ! is_array($items_label)
791
+			|| ! isset($items_label['single'])
792
+			|| ! isset($items_label['plural'])
793
+		) {
794
+			$items_label = [
795
+				'single' => esc_html__('1 item', 'event_espresso'),
796
+				'plural' => esc_html__('%s items', 'event_espresso'),
797
+			];
798
+		} else {
799
+			$items_label = [
800
+				'single' => '1 ' . esc_html($items_label['single']),
801
+				'plural' => '%s ' . esc_html($items_label['plural']),
802
+			];
803
+		}
804
+
805
+		$total_pages = (int) ceil($total_items / $per_page);
806
+
807
+		if ($total_pages <= 1) {
808
+			return '';
809
+		}
810
+
811
+		$item_label = $total_items > 1 ? sprintf($items_label['plural'], $total_items) : $items_label['single'];
812
+
813
+		$output = '<span class="displaying-num">' . $item_label . '</span>';
814
+
815
+		$disable_first = $current === 1 ? 'disabled' : '';
816
+		$disable_last  = $current === $total_pages ? 'disabled' : '';
817
+
818
+		$button_classes = 'button button--secondary button--icon-only button--small';
819
+
820
+		$page_links[] = sprintf(
821
+			'<a class="%s" aria-label="%s" href="%s"><span class="ee-pagination-arrow">%s</span></a>',
822
+			esc_attr("first-page $button_classes $disable_first"),
823
+			esc_attr__('Go to the first page', 'event_espresso'),
824
+			esc_url_raw(remove_query_arg($paged_arg_name, $url)),
825
+			'&laquo;'
826
+		);
827
+
828
+		$page_links[] = sprintf(
829
+			'<a class="%s" aria-label="%s" href="%s"><span class="ee-pagination-arrow">%s</span></a>',
830
+			esc_attr("prev-page $button_classes $disable_first"),
831
+			esc_attr__('Go to the previous page', 'event_espresso'),
832
+			esc_url_raw(add_query_arg($paged_arg_name, max(1, $current - 1), $url)),
833
+			'&lsaquo;'
834
+		);
835
+
836
+		$html_current_page = $show_num_field
837
+			? sprintf(
838
+				"<input class='current-page ee-input-size--small' title='%s' type='text' name=$paged_arg_name value='%s' size='%d' />",
839
+				esc_attr__('Current page', 'event_espresso'),
840
+				esc_attr($current),
841
+				strlen($total_pages)
842
+			)
843
+			: $current;
844
+
845
+		$html_total_pages = sprintf(
846
+			'<span class="total-pages">%s</span>',
847
+			number_format_i18n($total_pages)
848
+		);
849
+		$page_links[]     = sprintf(
850
+			_x('%3$s%1$s of %2$s%4$s', 'paging', 'event_espresso'),
851
+			"{$html_current_page}<span class='paging-input-of'>",
852
+			"</span>{$html_total_pages}",
853
+			'<span class="paging-input">',
854
+			'</span>'
855
+		);
856
+
857
+		$page_links[] = sprintf(
858
+			'<a class="%s" aria-label="%s" href="%s"><span class="ee-pagination-arrow">%s</span></a>',
859
+			esc_attr("next-page $button_classes $disable_last"),
860
+			esc_attr__('Go to the next page', 'event_espresso'),
861
+			esc_url_raw(add_query_arg($paged_arg_name, min($total_pages, $current + 1), $url)),
862
+			'&rsaquo;'
863
+		);
864
+
865
+		$page_links[] = sprintf(
866
+			'<a class="%s" aria-label="%s" href="%s"><span class="ee-pagination-arrow">%s</span></a>',
867
+			esc_attr("last-page $button_classes $disable_last"),
868
+			esc_attr__('Go to the last page', 'event_espresso'),
869
+			esc_url_raw(add_query_arg($paged_arg_name, $total_pages, $url)),
870
+			'&raquo;'
871
+		);
872
+
873
+		$output .= "\n" . '<span class="pagination-links">' . join("\n", $page_links) . '</span>';
874
+
875
+		$page_class = ' no-pages';
876
+		if ($total_pages) {
877
+			$page_class = $total_pages < 2 ? ' one-page' : '';
878
+		}
879
+
880
+		return '<div class="tablenav"><div class="tablenav-pages' . $page_class . '">' . $output . '</div></div>';
881
+	}
882
+
883
+
884
+	/**
885
+	 * @param string $wrap_class
886
+	 * @param string $wrap_id
887
+	 * @return string
888
+	 */
889
+	public static function powered_by_event_espresso($wrap_class = '', $wrap_id = '', array $query_args = [])
890
+	{
891
+		$admin = is_admin() && ! (defined('DOING_AJAX') && DOING_AJAX);
892
+		if (
893
+			! $admin
894
+			&& ! apply_filters(
895
+				'FHEE__EEH_Template__powered_by_event_espresso__show_reg_footer',
896
+				EE_Registry::instance()->CFG->admin->show_reg_footer
897
+			)
898
+		) {
899
+			return '';
900
+		}
901
+		$tag        = $admin ? 'span' : 'div';
902
+		$attributes = ! empty($wrap_id) ? " id=\"{$wrap_id}\"" : '';
903
+		$wrap_class = $admin ? "{$wrap_class} float-left" : $wrap_class;
904
+		$attributes .= ! empty($wrap_class)
905
+			? " class=\"{$wrap_class} powered-by-event-espresso-credit\""
906
+			: ' class="powered-by-event-espresso-credit"';
907
+		$query_args = array_merge(
908
+			[
909
+				'ap_id'        => EE_Registry::instance()->CFG->admin->affiliate_id(),
910
+				'utm_source'   => 'powered_by_event_espresso',
911
+				'utm_medium'   => 'link',
912
+				'utm_campaign' => 'powered_by',
913
+			],
914
+			$query_args
915
+		);
916
+		$powered_by = apply_filters(
917
+			'FHEE__EEH_Template__powered_by_event_espresso_text',
918
+			$admin ? 'Event Espresso - ' . EVENT_ESPRESSO_VERSION : 'Event Espresso'
919
+		);
920
+		$url        = add_query_arg($query_args, 'https://eventespresso.com/');
921
+		$url        = apply_filters('FHEE__EEH_Template__powered_by_event_espresso__url', $url);
922
+		return (string) apply_filters(
923
+			'FHEE__EEH_Template__powered_by_event_espresso__html',
924
+			sprintf(
925
+				esc_html_x(
926
+					'%3$s%1$sOnline event registration and ticketing powered by %2$s%3$s',
927
+					'Online event registration and ticketing powered by [link to eventespresso.com]',
928
+					'event_espresso'
929
+				),
930
+				"<{$tag}{$attributes}>",
931
+				"<a href=\"{$url}\" target=\"_blank\" rel=\"nofollow\">{$powered_by}</a></{$tag}>",
932
+				$admin ? '' : '<br />'
933
+			),
934
+			$wrap_class,
935
+			$wrap_id
936
+		);
937
+	}
938
+
939
+
940
+	/**
941
+	 * @param string $image_name
942
+	 * @return string|null
943
+	 * @since   4.10.14.p
944
+	 */
945
+	public static function getScreenshotUrl($image_name)
946
+	{
947
+		return esc_url_raw(EE_GLOBAL_ASSETS_URL . 'images/screenshots/' . $image_name . '.jpg');
948
+	}
949 949
 }
950 950
 
951 951
 
952 952
 if (! function_exists('espresso_pagination')) {
953
-    /**
954
-     *    espresso_pagination
955
-     *
956
-     * @access    public
957
-     * @return    void
958
-     */
959
-    function espresso_pagination()
960
-    {
961
-        global $wp_query;
962
-        $big        = 999999999; // need an unlikely integer
963
-        $pagination = paginate_links(
964
-            [
965
-                'base'         => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
966
-                'format'       => '?paged=%#%',
967
-                'current'      => max(1, get_query_var('paged')),
968
-                'total'        => $wp_query->max_num_pages,
969
-                'show_all'     => true,
970
-                'end_size'     => 10,
971
-                'mid_size'     => 6,
972
-                'prev_next'    => true,
973
-                'prev_text'    => esc_html__('&lsaquo; PREV', 'event_espresso'),
974
-                'next_text'    => esc_html__('NEXT &rsaquo;', 'event_espresso'),
975
-                'type'         => 'plain',
976
-                'add_args'     => false,
977
-                'add_fragment' => '',
978
-            ]
979
-        );
980
-        echo ! empty($pagination) ? '<div class="ee-pagination-dv ee-clear-float">' . $pagination . '</div>' : '';
981
-    }
953
+	/**
954
+	 *    espresso_pagination
955
+	 *
956
+	 * @access    public
957
+	 * @return    void
958
+	 */
959
+	function espresso_pagination()
960
+	{
961
+		global $wp_query;
962
+		$big        = 999999999; // need an unlikely integer
963
+		$pagination = paginate_links(
964
+			[
965
+				'base'         => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
966
+				'format'       => '?paged=%#%',
967
+				'current'      => max(1, get_query_var('paged')),
968
+				'total'        => $wp_query->max_num_pages,
969
+				'show_all'     => true,
970
+				'end_size'     => 10,
971
+				'mid_size'     => 6,
972
+				'prev_next'    => true,
973
+				'prev_text'    => esc_html__('&lsaquo; PREV', 'event_espresso'),
974
+				'next_text'    => esc_html__('NEXT &rsaquo;', 'event_espresso'),
975
+				'type'         => 'plain',
976
+				'add_args'     => false,
977
+				'add_fragment' => '',
978
+			]
979
+		);
980
+		echo ! empty($pagination) ? '<div class="ee-pagination-dv ee-clear-float">' . $pagination . '</div>' : '';
981
+	}
982 982
 }
Please login to merge, or discard this patch.
Spacing   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -6,7 +6,7 @@  discard block
 block discarded – undo
6 6
 use EventEspresso\core\services\request\RequestInterface;
7 7
 use EventEspresso\core\services\request\sanitizers\AllowedTags;
8 8
 
9
-if (! function_exists('espresso_get_template_part')) {
9
+if ( ! function_exists('espresso_get_template_part')) {
10 10
     /**
11 11
      * espresso_get_template_part
12 12
      * basically a copy of the WordPress get_template_part() function but uses EEH_Template::locate_template() instead, and doesn't add base versions of files
@@ -22,7 +22,7 @@  discard block
 block discarded – undo
22 22
 }
23 23
 
24 24
 
25
-if (! function_exists('espresso_get_object_css_class')) {
25
+if ( ! function_exists('espresso_get_object_css_class')) {
26 26
     /**
27 27
      * espresso_get_object_css_class - attempts to generate a css class based on the type of EE object passed
28 28
      *
@@ -72,9 +72,9 @@  discard block
 block discarded – undo
72 72
      */
73 73
     public static function load_espresso_theme_functions()
74 74
     {
75
-        if (! defined('EE_THEME_FUNCTIONS_LOADED')) {
76
-            if (is_readable(EE_PUBLIC . EE_Config::get_current_theme() . '/functions.php')) {
77
-                require_once(EE_PUBLIC . EE_Config::get_current_theme() . '/functions.php');
75
+        if ( ! defined('EE_THEME_FUNCTIONS_LOADED')) {
76
+            if (is_readable(EE_PUBLIC.EE_Config::get_current_theme().'/functions.php')) {
77
+                require_once(EE_PUBLIC.EE_Config::get_current_theme().'/functions.php');
78 78
             }
79 79
         }
80 80
     }
@@ -88,16 +88,16 @@  discard block
 block discarded – undo
88 88
     public static function get_espresso_themes()
89 89
     {
90 90
         if (empty(EEH_Template::$_espresso_themes)) {
91
-            $espresso_themes = glob(EE_PUBLIC . '*', GLOB_ONLYDIR);
91
+            $espresso_themes = glob(EE_PUBLIC.'*', GLOB_ONLYDIR);
92 92
             if (empty($espresso_themes)) {
93 93
                 return [];
94 94
             }
95 95
             if (($key = array_search('global_assets', $espresso_themes)) !== false) {
96
-                unset($espresso_themes[ $key ]);
96
+                unset($espresso_themes[$key]);
97 97
             }
98 98
             EEH_Template::$_espresso_themes = [];
99 99
             foreach ($espresso_themes as $espresso_theme) {
100
-                EEH_Template::$_espresso_themes[ basename($espresso_theme) ] = $espresso_theme;
100
+                EEH_Template::$_espresso_themes[basename($espresso_theme)] = $espresso_theme;
101 101
             }
102 102
         }
103 103
         return EEH_Template::$_espresso_themes;
@@ -213,10 +213,10 @@  discard block
 block discarded – undo
213 213
                 // get array of EE Custom Post Types
214 214
                 $EE_CPTs = $custom_post_types->getDefinitions();
215 215
                 // build template name based on request
216
-                if (isset($EE_CPTs[ $post_type ])) {
216
+                if (isset($EE_CPTs[$post_type])) {
217 217
                     $archive_or_single = is_archive() ? 'archive' : '';
218 218
                     $archive_or_single = is_single() ? 'single' : $archive_or_single;
219
-                    $templates         = $archive_or_single . '-' . $post_type . '.php';
219
+                    $templates         = $archive_or_single.'-'.$post_type.'.php';
220 220
                 }
221 221
             }
222 222
             // currently active EE template theme
@@ -225,18 +225,18 @@  discard block
 block discarded – undo
225 225
             // array of paths to folders that may contain templates
226 226
             $template_folder_paths = [
227 227
                 // first check the /wp-content/uploads/espresso/templates/(current EE theme)/  folder for an EE theme template file
228
-                EVENT_ESPRESSO_TEMPLATE_DIR . $current_theme,
228
+                EVENT_ESPRESSO_TEMPLATE_DIR.$current_theme,
229 229
                 // then in the root of the /wp-content/uploads/espresso/templates/ folder
230 230
                 EVENT_ESPRESSO_TEMPLATE_DIR,
231 231
             ];
232 232
 
233 233
             // add core plugin folders for checking only if we're not $check_if_custom
234
-            if (! $check_if_custom) {
235
-                $core_paths            = [
234
+            if ( ! $check_if_custom) {
235
+                $core_paths = [
236 236
                     // in the  /wp-content/plugins/(EE4 folder)/public/(current EE theme)/ folder within the plugin
237
-                    EE_PUBLIC . $current_theme,
237
+                    EE_PUBLIC.$current_theme,
238 238
                     // in the  /wp-content/plugins/(EE4 folder)/core/templates/(current EE theme)/ folder within the plugin
239
-                    EE_TEMPLATES . $current_theme,
239
+                    EE_TEMPLATES.$current_theme,
240 240
                     // or maybe relative from the plugin root: /wp-content/plugins/(EE4 folder)/
241 241
                     EE_PLUGIN_DIR_PATH,
242 242
                 ];
@@ -271,10 +271,10 @@  discard block
 block discarded – undo
271 271
                     );
272 272
                     if ($common_base_path !== '') {
273 273
                         // both paths have a common base, so just tack the filename onto our search path
274
-                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $file_name;
274
+                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path).$file_name;
275 275
                     } else {
276 276
                         // no common base path, so let's just concatenate
277
-                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $template;
277
+                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path).$template;
278 278
                     }
279 279
                     // build up our template locations array by adding our resolved paths
280 280
                     $full_template_paths[] = $resolved_path;
@@ -282,7 +282,7 @@  discard block
 block discarded – undo
282 282
                 // if $template is an absolute path, then we'll tack it onto the start of our array so that it gets searched first
283 283
                 array_unshift($full_template_paths, $template);
284 284
                 // path to the directory of the current theme: /wp-content/themes/(current WP theme)/
285
-                array_unshift($full_template_paths, get_stylesheet_directory() . '/' . $file_name);
285
+                array_unshift($full_template_paths, get_stylesheet_directory().'/'.$file_name);
286 286
             }
287 287
             // filter final array of full template paths
288 288
             $full_template_paths = apply_filters(
@@ -333,7 +333,7 @@  discard block
 block discarded – undo
333 333
                 }
334 334
             }
335 335
             $common_base_path .= $directory;
336
-            $last_offset      = $index + 1;
336
+            $last_offset = $index + 1;
337 337
         }
338 338
         return substr($common_base_path, 0, -1);
339 339
     }
@@ -370,7 +370,7 @@  discard block
 block discarded – undo
370 370
         $template_args = (array) apply_filters('FHEE__EEH_Template__display_template__template_args', $template_args);
371 371
 
372 372
         // you gimme nuttin - YOU GET NUTTIN !!
373
-        if (! $template_path || ! is_readable($template_path)) {
373
+        if ( ! $template_path || ! is_readable($template_path)) {
374 374
             // ignore whether template is accessible ?
375 375
             if ($throw_exceptions) {
376 376
                 throw new DomainException(
@@ -380,7 +380,7 @@  discard block
 block discarded – undo
380 380
             return '';
381 381
         }
382 382
         // if $template_args are not in an array, then make it so
383
-        if (! is_array($template_args) && ! is_object($template_args)) {
383
+        if ( ! is_array($template_args) && ! is_object($template_args)) {
384 384
             $template_args = [$template_args];
385 385
         }
386 386
         extract($template_args, EXTR_SKIP);
@@ -409,11 +409,11 @@  discard block
 block discarded – undo
409 409
     public static function get_object_css_class($object = null, $prefix = '', $suffix = '')
410 410
     {
411 411
         // in the beginning...
412
-        $prefix = ! empty($prefix) ? rtrim($prefix, '-') . '-' : '';
412
+        $prefix = ! empty($prefix) ? rtrim($prefix, '-').'-' : '';
413 413
         // da muddle
414 414
         $class = '';
415 415
         // the end
416
-        $suffix = ! empty($suffix) ? '-' . ltrim($suffix, '-') : '';
416
+        $suffix = ! empty($suffix) ? '-'.ltrim($suffix, '-') : '';
417 417
         // is the passed object an EE object ?
418 418
         if ($object instanceof EE_Base_Class) {
419 419
             // grab the exact type of object
@@ -423,10 +423,10 @@  discard block
 block discarded – undo
423 423
                 // no specifics just yet...
424 424
                 default:
425 425
                     $class = strtolower(str_replace('_', '-', $obj_class));
426
-                    $class .= method_exists($obj_class, 'name') ? '-' . sanitize_title($object->name()) : '';
426
+                    $class .= method_exists($obj_class, 'name') ? '-'.sanitize_title($object->name()) : '';
427 427
             }
428 428
         }
429
-        return $prefix . $class . $suffix;
429
+        return $prefix.$class.$suffix;
430 430
     }
431 431
 
432 432
 
@@ -461,7 +461,7 @@  discard block
 block discarded – undo
461 461
         // filter raw amount (allows 0.00 to be changed to "free" for example)
462 462
         $amount_formatted = apply_filters('FHEE__EEH_Template__format_currency__amount', $amount, $return_raw);
463 463
         // still a number, or was amount converted to a string like "free" ?
464
-        if (! is_float($amount_formatted)) {
464
+        if ( ! is_float($amount_formatted)) {
465 465
             return esc_html($amount_formatted);
466 466
         }
467 467
         try {
@@ -472,7 +472,7 @@  discard block
 block discarded – undo
472 472
             $mny = null;
473 473
         }
474 474
         // verify results
475
-        if (! $mny instanceof EE_Currency_Config) {
475
+        if ( ! $mny instanceof EE_Currency_Config) {
476 476
             // set default config country currency settings
477 477
             $mny = EE_Registry::instance()->CFG->currency instanceof EE_Currency_Config
478 478
                 ? EE_Registry::instance()->CFG->currency
@@ -481,16 +481,16 @@  discard block
 block discarded – undo
481 481
         // format float
482 482
         $amount_formatted = number_format($amount, $mny->dec_plc, $mny->dec_mrk, $mny->thsnds);
483 483
         // add formatting ?
484
-        if (! $return_raw) {
484
+        if ( ! $return_raw) {
485 485
             // add currency sign
486 486
             if ($mny->sign_b4) {
487 487
                 if ($amount >= 0) {
488
-                    $amount_formatted = $mny->sign . $amount_formatted;
488
+                    $amount_formatted = $mny->sign.$amount_formatted;
489 489
                 } else {
490
-                    $amount_formatted = '-' . $mny->sign . str_replace('-', '', $amount_formatted);
490
+                    $amount_formatted = '-'.$mny->sign.str_replace('-', '', $amount_formatted);
491 491
                 }
492 492
             } else {
493
-                $amount_formatted = $amount_formatted . $mny->sign;
493
+                $amount_formatted = $amount_formatted.$mny->sign;
494 494
             }
495 495
 
496 496
             // filter to allow global setting of display_code
@@ -501,7 +501,7 @@  discard block
 block discarded – undo
501 501
 
502 502
             // add currency code ?
503 503
             $amount_formatted = $display_code
504
-                ? $amount_formatted . ' <span class="' . $cur_code_span_class . '">(' . $mny->code . ')</span>'
504
+                ? $amount_formatted.' <span class="'.$cur_code_span_class.'">('.$mny->code.')</span>'
505 505
                 : $amount_formatted;
506 506
         }
507 507
         // filter results
@@ -537,7 +537,7 @@  discard block
 block discarded – undo
537 537
             $plural,
538 538
             $schema
539 539
         );
540
-        return $status[ $status_id ];
540
+        return $status[$status_id];
541 541
     }
542 542
 
543 543
 
@@ -554,14 +554,14 @@  discard block
 block discarded – undo
554 554
     public static function get_button_or_link($url, $label, $class = 'button button--primary', $icon = '', $title = '')
555 555
     {
556 556
         $icon_html = '';
557
-        if (! empty($icon)) {
557
+        if ( ! empty($icon)) {
558 558
             $dashicons = preg_split("(ee-icon |dashicons )", $icon);
559 559
             $dashicons = array_filter($dashicons);
560 560
             $count     = count($dashicons);
561 561
             $icon_html .= $count > 1 ? '<span class="ee-composite-dashicon">' : '';
562 562
             foreach ($dashicons as $dashicon) {
563
-                $type      = strpos($dashicon, 'ee-icon') !== false ? 'ee-icon ' : 'dashicons ';
564
-                $icon_html .= '<span class="' . $type . $dashicon . '"></span>';
563
+                $type = strpos($dashicon, 'ee-icon') !== false ? 'ee-icon ' : 'dashicons ';
564
+                $icon_html .= '<span class="'.$type.$dashicon.'"></span>';
565 565
             }
566 566
             $icon_html .= $count > 1 ? '</span>' : '';
567 567
         }
@@ -601,18 +601,18 @@  discard block
 block discarded – undo
601 601
         $action  = $action ?: $request->getRequestParam('action', 'default', 'key');
602 602
 
603 603
 
604
-        $help_tab_lnk = $page . '-' . $action . '-' . $help_tab_id;
604
+        $help_tab_lnk = $page.'-'.$action.'-'.$help_tab_id;
605 605
         $icon         = ! $icon_style ? 'dashicons-editor-help' : $icon_style;
606 606
         $help_text    = ! $help_text ? '' : $help_text;
607 607
         return '
608
-            <a id="' . esc_attr($help_tab_lnk) . '"
609
-               class="espresso-help-tab-lnk ee-help-btn ee-aria-tooltip dashicons ' . esc_attr($icon) . '"
608
+            <a id="' . esc_attr($help_tab_lnk).'"
609
+               class="espresso-help-tab-lnk ee-help-btn ee-aria-tooltip dashicons ' . esc_attr($icon).'"
610 610
                aria-label="' . esc_attr__(
611 611
                    'Click to open the \'Help\' tab for more information about this feature.',
612 612
                    'event_espresso'
613
-               ) . '"
613
+               ).'"
614 614
             >
615
-                ' . wp_kses($help_text, $allowedtags) . '
615
+                ' . wp_kses($help_text, $allowedtags).'
616 616
             </a>';
617 617
     }
618 618
 
@@ -633,7 +633,7 @@  discard block
 block discarded – undo
633 633
      */
634 634
     public static function status_legend($status_array, $active_status = '')
635 635
     {
636
-        if (! is_array($status_array)) {
636
+        if ( ! is_array($status_array)) {
637 637
             throw new EE_Error(
638 638
                 esc_html__(
639 639
                     'The EEH_Template::status_legend helper required the incoming status_array argument to be an array!',
@@ -645,17 +645,17 @@  discard block
 block discarded – undo
645 645
         $content = '
646 646
             <div class="ee-list-table-legend-container">
647 647
                 <h4 class="status-legend-title">
648
-                    ' . esc_html__('Status Legend', 'event_espresso') . '
648
+                    ' . esc_html__('Status Legend', 'event_espresso').'
649 649
                 </h4>
650 650
                 <dl class="ee-list-table-legend">';
651 651
 
652 652
         foreach ($status_array as $item => $status) {
653 653
             $active_class = $active_status == $status ? 'class="ee-is-active-status"' : '';
654
-            $content      .= '
655
-                    <dt id="' . esc_attr('ee-legend-item-tooltip-' . $item) . '" ' . $active_class . '>
656
-                        <span class="' . esc_attr('ee-status-legend ee-status-bg--' . $status) . '"></span>
654
+            $content .= '
655
+                    <dt id="' . esc_attr('ee-legend-item-tooltip-'.$item).'" '.$active_class.'>
656
+                        <span class="' . esc_attr('ee-status-legend ee-status-bg--'.$status).'"></span>
657 657
                         <span class="ee-legend-description">
658
-                            ' . EEH_Template::pretty_status($status, false, 'sentence') . '
658
+                            ' . EEH_Template::pretty_status($status, false, 'sentence').'
659 659
                         </span>
660 660
                     </dt>';
661 661
         }
@@ -797,8 +797,8 @@  discard block
 block discarded – undo
797 797
             ];
798 798
         } else {
799 799
             $items_label = [
800
-                'single' => '1 ' . esc_html($items_label['single']),
801
-                'plural' => '%s ' . esc_html($items_label['plural']),
800
+                'single' => '1 '.esc_html($items_label['single']),
801
+                'plural' => '%s '.esc_html($items_label['plural']),
802 802
             ];
803 803
         }
804 804
 
@@ -810,7 +810,7 @@  discard block
 block discarded – undo
810 810
 
811 811
         $item_label = $total_items > 1 ? sprintf($items_label['plural'], $total_items) : $items_label['single'];
812 812
 
813
-        $output = '<span class="displaying-num">' . $item_label . '</span>';
813
+        $output = '<span class="displaying-num">'.$item_label.'</span>';
814 814
 
815 815
         $disable_first = $current === 1 ? 'disabled' : '';
816 816
         $disable_last  = $current === $total_pages ? 'disabled' : '';
@@ -846,7 +846,7 @@  discard block
 block discarded – undo
846 846
             '<span class="total-pages">%s</span>',
847 847
             number_format_i18n($total_pages)
848 848
         );
849
-        $page_links[]     = sprintf(
849
+        $page_links[] = sprintf(
850 850
             _x('%3$s%1$s of %2$s%4$s', 'paging', 'event_espresso'),
851 851
             "{$html_current_page}<span class='paging-input-of'>",
852 852
             "</span>{$html_total_pages}",
@@ -870,14 +870,14 @@  discard block
 block discarded – undo
870 870
             '&raquo;'
871 871
         );
872 872
 
873
-        $output .= "\n" . '<span class="pagination-links">' . join("\n", $page_links) . '</span>';
873
+        $output .= "\n".'<span class="pagination-links">'.join("\n", $page_links).'</span>';
874 874
 
875 875
         $page_class = ' no-pages';
876 876
         if ($total_pages) {
877 877
             $page_class = $total_pages < 2 ? ' one-page' : '';
878 878
         }
879 879
 
880
-        return '<div class="tablenav"><div class="tablenav-pages' . $page_class . '">' . $output . '</div></div>';
880
+        return '<div class="tablenav"><div class="tablenav-pages'.$page_class.'">'.$output.'</div></div>';
881 881
     }
882 882
 
883 883
 
@@ -915,7 +915,7 @@  discard block
 block discarded – undo
915 915
         );
916 916
         $powered_by = apply_filters(
917 917
             'FHEE__EEH_Template__powered_by_event_espresso_text',
918
-            $admin ? 'Event Espresso - ' . EVENT_ESPRESSO_VERSION : 'Event Espresso'
918
+            $admin ? 'Event Espresso - '.EVENT_ESPRESSO_VERSION : 'Event Espresso'
919 919
         );
920 920
         $url        = add_query_arg($query_args, 'https://eventespresso.com/');
921 921
         $url        = apply_filters('FHEE__EEH_Template__powered_by_event_espresso__url', $url);
@@ -944,12 +944,12 @@  discard block
 block discarded – undo
944 944
      */
945 945
     public static function getScreenshotUrl($image_name)
946 946
     {
947
-        return esc_url_raw(EE_GLOBAL_ASSETS_URL . 'images/screenshots/' . $image_name . '.jpg');
947
+        return esc_url_raw(EE_GLOBAL_ASSETS_URL.'images/screenshots/'.$image_name.'.jpg');
948 948
     }
949 949
 }
950 950
 
951 951
 
952
-if (! function_exists('espresso_pagination')) {
952
+if ( ! function_exists('espresso_pagination')) {
953 953
     /**
954 954
      *    espresso_pagination
955 955
      *
@@ -977,6 +977,6 @@  discard block
 block discarded – undo
977 977
                 'add_fragment' => '',
978 978
             ]
979 979
         );
980
-        echo ! empty($pagination) ? '<div class="ee-pagination-dv ee-clear-float">' . $pagination . '</div>' : '';
980
+        echo ! empty($pagination) ? '<div class="ee-pagination-dv ee-clear-float">'.$pagination.'</div>' : '';
981 981
     }
982 982
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Event.class.php 1 patch
Indentation   +1559 added lines, -1559 removed lines patch added patch discarded remove patch
@@ -16,1563 +16,1563 @@
 block discarded – undo
16 16
  */
17 17
 class EE_Event extends EE_CPT_Base implements EEI_Line_Item_Object, EEI_Admin_Links, EEI_Has_Icon, EEI_Event
18 18
 {
19
-    /**
20
-     * cached value for the the logical active status for the event
21
-     *
22
-     * @see get_active_status()
23
-     * @var string
24
-     */
25
-    protected $_active_status = '';
26
-
27
-    /**
28
-     * This is just used for caching the Primary Datetime for the Event on initial retrieval
29
-     *
30
-     * @var EE_Datetime
31
-     */
32
-    protected $_Primary_Datetime;
33
-
34
-    /**
35
-     * @var EventSpacesCalculator $available_spaces_calculator
36
-     */
37
-    protected $available_spaces_calculator;
38
-
39
-
40
-    /**
41
-     * @param array  $props_n_values          incoming values
42
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
43
-     *                                        used.)
44
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
45
-     *                                        date_format and the second value is the time format
46
-     * @return EE_Event
47
-     * @throws EE_Error
48
-     * @throws ReflectionException
49
-     */
50
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
51
-    {
52
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
53
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
54
-    }
55
-
56
-
57
-    /**
58
-     * @param array  $props_n_values  incoming values from the database
59
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
60
-     *                                the website will be used.
61
-     * @return EE_Event
62
-     * @throws EE_Error
63
-     * @throws ReflectionException
64
-     */
65
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
66
-    {
67
-        return new self($props_n_values, true, $timezone);
68
-    }
69
-
70
-
71
-    /**
72
-     * @return EventSpacesCalculator
73
-     * @throws \EE_Error
74
-     */
75
-    public function getAvailableSpacesCalculator()
76
-    {
77
-        if (! $this->available_spaces_calculator instanceof EventSpacesCalculator) {
78
-            $this->available_spaces_calculator = new EventSpacesCalculator($this);
79
-        }
80
-        return $this->available_spaces_calculator;
81
-    }
82
-
83
-
84
-    /**
85
-     * Overrides parent set() method so that all calls to set( 'status', $status ) can be routed to internal methods
86
-     *
87
-     * @param string $field_name
88
-     * @param mixed  $field_value
89
-     * @param bool   $use_default
90
-     * @throws EE_Error
91
-     * @throws ReflectionException
92
-     */
93
-    public function set($field_name, $field_value, $use_default = false)
94
-    {
95
-        switch ($field_name) {
96
-            case 'status':
97
-                $this->set_status($field_value, $use_default);
98
-                break;
99
-            default:
100
-                parent::set($field_name, $field_value, $use_default);
101
-        }
102
-    }
103
-
104
-
105
-    /**
106
-     *    set_status
107
-     * Checks if event status is being changed to SOLD OUT
108
-     * and updates event meta data with previous event status
109
-     * so that we can revert things if/when the event is no longer sold out
110
-     *
111
-     * @access public
112
-     * @param string $new_status
113
-     * @param bool   $use_default
114
-     * @return void
115
-     * @throws EE_Error
116
-     * @throws ReflectionException
117
-     */
118
-    public function set_status($new_status = null, $use_default = false)
119
-    {
120
-        // if nothing is set, and we aren't explicitly wanting to reset the status, then just leave
121
-        if (empty($new_status) && ! $use_default) {
122
-            return;
123
-        }
124
-        // get current Event status
125
-        $old_status = $this->status();
126
-        // if status has changed
127
-        if ($old_status !== $new_status) {
128
-            // TO sold_out
129
-            if ($new_status === EEM_Event::sold_out) {
130
-                // save the previous event status so that we can revert if the event is no longer sold out
131
-                $this->add_post_meta('_previous_event_status', $old_status);
132
-                do_action('AHEE__EE_Event__set_status__to_sold_out', $this, $old_status, $new_status);
133
-            // OR FROM  sold_out
134
-            } elseif ($old_status === EEM_Event::sold_out) {
135
-                $this->delete_post_meta('_previous_event_status');
136
-                do_action('AHEE__EE_Event__set_status__from_sold_out', $this, $old_status, $new_status);
137
-            }
138
-            // clear out the active status so that it gets reset the next time it is requested
139
-            $this->_active_status = null;
140
-            // update status
141
-            parent::set('status', $new_status, $use_default);
142
-            do_action('AHEE__EE_Event__set_status__after_update', $this);
143
-            return;
144
-        }
145
-        // even though the old value matches the new value, it's still good to
146
-        // allow the parent set method to have a say
147
-        parent::set('status', $new_status, $use_default);
148
-    }
149
-
150
-
151
-    /**
152
-     * Gets all the datetimes for this event
153
-     *
154
-     * @param array $query_params @see
155
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
156
-     * @return EE_Base_Class[]|EE_Datetime[]
157
-     * @throws EE_Error
158
-     * @throws ReflectionException
159
-     */
160
-    public function datetimes($query_params = array())
161
-    {
162
-        return $this->get_many_related('Datetime', $query_params);
163
-    }
164
-
165
-
166
-    /**
167
-     * Gets all the datetimes for this event that are currently ACTIVE,
168
-     * meaning the datetime has started and has not yet ended.
169
-     *
170
-     * @param int|null $start_date      timestamp to use for event date start time, defaults to NOW unless set to 0
171
-     * @param array|null $query_params  will recursively replace default values
172
-     * @throws EE_Error
173
-     * @throws ReflectionException
174
-     * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
175
-     */
176
-    public function activeDatetimes(?int $start_date, ?array $query_params = []): array
177
-    {
178
-        // if start date is null, then use current time
179
-        $start_date = $start_date ?? time();
180
-        $where = [];
181
-        if ($start_date) {
182
-            $where['DTT_EVT_start'] = ['<', $start_date];
183
-            $where['DTT_EVT_end']   = ['>', time()];
184
-        }
185
-        $query_params = array_replace_recursive(
186
-            [
187
-                $where,
188
-                'order_by' => ['DTT_EVT_start' => 'ASC']
189
-            ],
190
-            $query_params
191
-        );
192
-        return $this->get_many_related('Datetime', $query_params);
193
-    }
194
-
195
-
196
-    /**
197
-     * Gets all the datetimes for this event, ordered by DTT_EVT_start in ascending order
198
-     *
199
-     * @return EE_Base_Class[]|EE_Datetime[]
200
-     * @throws EE_Error
201
-     * @throws ReflectionException
202
-     */
203
-    public function datetimes_in_chronological_order()
204
-    {
205
-        return $this->get_many_related('Datetime', array('order_by' => array('DTT_EVT_start' => 'ASC')));
206
-    }
207
-
208
-
209
-    /**
210
-     * Gets all the datetimes for this event, ordered by the DTT_order on the datetime.
211
-     * @darren, we should probably UNSET timezone on the EEM_Datetime model
212
-     * after running our query, so that this timezone isn't set for EVERY query
213
-     * on EEM_Datetime for the rest of the request, no?
214
-     *
215
-     * @param boolean $show_expired whether or not to include expired events
216
-     * @param boolean $show_deleted whether or not to include deleted events
217
-     * @param null    $limit
218
-     * @return EE_Datetime[]
219
-     * @throws EE_Error
220
-     * @throws ReflectionException
221
-     */
222
-    public function datetimes_ordered($show_expired = true, $show_deleted = false, $limit = null)
223
-    {
224
-        return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_event_ordered_by_DTT_order(
225
-            $this->ID(),
226
-            $show_expired,
227
-            $show_deleted,
228
-            $limit
229
-        );
230
-    }
231
-
232
-
233
-    /**
234
-     * Returns one related datetime. Mostly only used by some legacy code.
235
-     *
236
-     * @return EE_Base_Class|EE_Datetime
237
-     * @throws EE_Error
238
-     * @throws ReflectionException
239
-     */
240
-    public function first_datetime()
241
-    {
242
-        return $this->get_first_related('Datetime');
243
-    }
244
-
245
-
246
-    /**
247
-     * Returns the 'primary' datetime for the event
248
-     *
249
-     * @param bool $try_to_exclude_expired
250
-     * @param bool $try_to_exclude_deleted
251
-     * @return EE_Datetime
252
-     * @throws EE_Error
253
-     * @throws ReflectionException
254
-     */
255
-    public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true)
256
-    {
257
-        if (! empty($this->_Primary_Datetime)) {
258
-            return $this->_Primary_Datetime;
259
-        }
260
-        $this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)->get_primary_datetime_for_event(
261
-            $this->ID(),
262
-            $try_to_exclude_expired,
263
-            $try_to_exclude_deleted
264
-        );
265
-        return $this->_Primary_Datetime;
266
-    }
267
-
268
-
269
-    /**
270
-     * Gets all the tickets available for purchase of this event
271
-     *
272
-     * @param array $query_params @see
273
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
274
-     * @return EE_Base_Class[]|EE_Ticket[]
275
-     * @throws EE_Error
276
-     * @throws ReflectionException
277
-     */
278
-    public function tickets($query_params = array())
279
-    {
280
-        // first get all datetimes
281
-        $datetimes = $this->datetimes_ordered();
282
-        if (! $datetimes) {
283
-            return array();
284
-        }
285
-        $datetime_ids = array();
286
-        foreach ($datetimes as $datetime) {
287
-            $datetime_ids[] = $datetime->ID();
288
-        }
289
-        $where_params = array('Datetime.DTT_ID' => array('IN', $datetime_ids));
290
-        // if incoming $query_params has where conditions let's merge but not override existing.
291
-        if (is_array($query_params) && isset($query_params[0])) {
292
-            $where_params = array_merge($query_params[0], $where_params);
293
-            unset($query_params[0]);
294
-        }
295
-        // now add $where_params to $query_params
296
-        $query_params[0] = $where_params;
297
-        return EEM_Ticket::instance()->get_all($query_params);
298
-    }
299
-
300
-
301
-    /**
302
-     * get all unexpired untrashed tickets
303
-     *
304
-     * @return EE_Ticket[]
305
-     * @throws EE_Error
306
-     */
307
-    public function active_tickets()
308
-    {
309
-        return $this->tickets(
310
-            array(
311
-                array(
312
-                    'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
313
-                    'TKT_deleted'  => false,
314
-                ),
315
-            )
316
-        );
317
-    }
318
-
319
-
320
-    /**
321
-     * @return bool
322
-     * @throws EE_Error
323
-     * @throws ReflectionException
324
-     */
325
-    public function additional_limit()
326
-    {
327
-        return $this->get('EVT_additional_limit');
328
-    }
329
-
330
-
331
-    /**
332
-     * @return bool
333
-     * @throws EE_Error
334
-     * @throws ReflectionException
335
-     */
336
-    public function allow_overflow()
337
-    {
338
-        return $this->get('EVT_allow_overflow');
339
-    }
340
-
341
-
342
-    /**
343
-     * @return bool
344
-     * @throws EE_Error
345
-     * @throws ReflectionException
346
-     */
347
-    public function created()
348
-    {
349
-        return $this->get('EVT_created');
350
-    }
351
-
352
-
353
-    /**
354
-     * @return bool
355
-     * @throws EE_Error
356
-     * @throws ReflectionException
357
-     */
358
-    public function description()
359
-    {
360
-        return $this->get('EVT_desc');
361
-    }
362
-
363
-
364
-    /**
365
-     * Runs do_shortcode and wpautop on the description
366
-     *
367
-     * @return string of html
368
-     * @throws EE_Error
369
-     * @throws ReflectionException
370
-     */
371
-    public function description_filtered()
372
-    {
373
-        return $this->get_pretty('EVT_desc');
374
-    }
375
-
376
-
377
-    /**
378
-     * @return bool
379
-     * @throws EE_Error
380
-     * @throws ReflectionException
381
-     */
382
-    public function display_description()
383
-    {
384
-        return $this->get('EVT_display_desc');
385
-    }
386
-
387
-
388
-    /**
389
-     * @return bool
390
-     * @throws EE_Error
391
-     * @throws ReflectionException
392
-     */
393
-    public function display_ticket_selector()
394
-    {
395
-        return (bool) $this->get('EVT_display_ticket_selector');
396
-    }
397
-
398
-
399
-    /**
400
-     * @return string
401
-     * @throws EE_Error
402
-     * @throws ReflectionException
403
-     */
404
-    public function external_url()
405
-    {
406
-        return $this->get('EVT_external_URL');
407
-    }
408
-
409
-
410
-    /**
411
-     * @return bool
412
-     * @throws EE_Error
413
-     * @throws ReflectionException
414
-     */
415
-    public function member_only()
416
-    {
417
-        return $this->get('EVT_member_only');
418
-    }
419
-
420
-
421
-    /**
422
-     * @return bool
423
-     * @throws EE_Error
424
-     * @throws ReflectionException
425
-     */
426
-    public function phone()
427
-    {
428
-        return $this->get('EVT_phone');
429
-    }
430
-
431
-
432
-    /**
433
-     * @return bool
434
-     * @throws EE_Error
435
-     * @throws ReflectionException
436
-     */
437
-    public function modified()
438
-    {
439
-        return $this->get('EVT_modified');
440
-    }
441
-
442
-
443
-    /**
444
-     * @return bool
445
-     * @throws EE_Error
446
-     * @throws ReflectionException
447
-     */
448
-    public function name()
449
-    {
450
-        return $this->get('EVT_name');
451
-    }
452
-
453
-
454
-    /**
455
-     * @return bool
456
-     * @throws EE_Error
457
-     * @throws ReflectionException
458
-     */
459
-    public function order()
460
-    {
461
-        return $this->get('EVT_order');
462
-    }
463
-
464
-
465
-    /**
466
-     * @return bool|string
467
-     * @throws EE_Error
468
-     * @throws ReflectionException
469
-     */
470
-    public function default_registration_status()
471
-    {
472
-        $event_default_registration_status = $this->get('EVT_default_registration_status');
473
-        return ! empty($event_default_registration_status)
474
-            ? $event_default_registration_status
475
-            : EE_Registry::instance()->CFG->registration->default_STS_ID;
476
-    }
477
-
478
-
479
-    /**
480
-     * @param int  $num_words
481
-     * @param null $more
482
-     * @param bool $not_full_desc
483
-     * @return bool|string
484
-     * @throws EE_Error
485
-     * @throws ReflectionException
486
-     */
487
-    public function short_description($num_words = 55, $more = null, $not_full_desc = false)
488
-    {
489
-        $short_desc = $this->get('EVT_short_desc');
490
-        if (! empty($short_desc) || $not_full_desc) {
491
-            return $short_desc;
492
-        }
493
-        $full_desc = $this->get('EVT_desc');
494
-        return wp_trim_words($full_desc, $num_words, $more);
495
-    }
496
-
497
-
498
-    /**
499
-     * @return bool
500
-     * @throws EE_Error
501
-     * @throws ReflectionException
502
-     */
503
-    public function slug()
504
-    {
505
-        return $this->get('EVT_slug');
506
-    }
507
-
508
-
509
-    /**
510
-     * @return bool
511
-     * @throws EE_Error
512
-     * @throws ReflectionException
513
-     */
514
-    public function timezone_string()
515
-    {
516
-        return $this->get('EVT_timezone_string');
517
-    }
518
-
519
-
520
-    /**
521
-     * @return bool
522
-     * @throws EE_Error
523
-     * @throws ReflectionException
524
-     */
525
-    public function visible_on()
526
-    {
527
-        return $this->get('EVT_visible_on');
528
-    }
529
-
530
-
531
-    /**
532
-     * @return int
533
-     * @throws EE_Error
534
-     * @throws ReflectionException
535
-     */
536
-    public function wp_user()
537
-    {
538
-        return $this->get('EVT_wp_user');
539
-    }
540
-
541
-
542
-    /**
543
-     * @return bool
544
-     * @throws EE_Error
545
-     * @throws ReflectionException
546
-     */
547
-    public function donations()
548
-    {
549
-        return $this->get('EVT_donations');
550
-    }
551
-
552
-
553
-    /**
554
-     * @param $limit
555
-     * @throws EE_Error
556
-     */
557
-    public function set_additional_limit($limit)
558
-    {
559
-        $this->set('EVT_additional_limit', $limit);
560
-    }
561
-
562
-
563
-    /**
564
-     * @param $created
565
-     * @throws EE_Error
566
-     */
567
-    public function set_created($created)
568
-    {
569
-        $this->set('EVT_created', $created);
570
-    }
571
-
572
-
573
-    /**
574
-     * @param $desc
575
-     * @throws EE_Error
576
-     */
577
-    public function set_description($desc)
578
-    {
579
-        $this->set('EVT_desc', $desc);
580
-    }
581
-
582
-
583
-    /**
584
-     * @param $display_desc
585
-     * @throws EE_Error
586
-     */
587
-    public function set_display_description($display_desc)
588
-    {
589
-        $this->set('EVT_display_desc', $display_desc);
590
-    }
591
-
592
-
593
-    /**
594
-     * @param $display_ticket_selector
595
-     * @throws EE_Error
596
-     */
597
-    public function set_display_ticket_selector($display_ticket_selector)
598
-    {
599
-        $this->set('EVT_display_ticket_selector', $display_ticket_selector);
600
-    }
601
-
602
-
603
-    /**
604
-     * @param $external_url
605
-     * @throws EE_Error
606
-     */
607
-    public function set_external_url($external_url)
608
-    {
609
-        $this->set('EVT_external_URL', $external_url);
610
-    }
611
-
612
-
613
-    /**
614
-     * @param $member_only
615
-     * @throws EE_Error
616
-     */
617
-    public function set_member_only($member_only)
618
-    {
619
-        $this->set('EVT_member_only', $member_only);
620
-    }
621
-
622
-
623
-    /**
624
-     * @param $event_phone
625
-     * @throws EE_Error
626
-     */
627
-    public function set_event_phone($event_phone)
628
-    {
629
-        $this->set('EVT_phone', $event_phone);
630
-    }
631
-
632
-
633
-    /**
634
-     * @param $modified
635
-     * @throws EE_Error
636
-     */
637
-    public function set_modified($modified)
638
-    {
639
-        $this->set('EVT_modified', $modified);
640
-    }
641
-
642
-
643
-    /**
644
-     * @param $name
645
-     * @throws EE_Error
646
-     */
647
-    public function set_name($name)
648
-    {
649
-        $this->set('EVT_name', $name);
650
-    }
651
-
652
-
653
-    /**
654
-     * @param $order
655
-     * @throws EE_Error
656
-     */
657
-    public function set_order($order)
658
-    {
659
-        $this->set('EVT_order', $order);
660
-    }
661
-
662
-
663
-    /**
664
-     * @param $short_desc
665
-     * @throws EE_Error
666
-     */
667
-    public function set_short_description($short_desc)
668
-    {
669
-        $this->set('EVT_short_desc', $short_desc);
670
-    }
671
-
672
-
673
-    /**
674
-     * @param $slug
675
-     * @throws EE_Error
676
-     */
677
-    public function set_slug($slug)
678
-    {
679
-        $this->set('EVT_slug', $slug);
680
-    }
681
-
682
-
683
-    /**
684
-     * @param $timezone_string
685
-     * @throws EE_Error
686
-     */
687
-    public function set_timezone_string($timezone_string)
688
-    {
689
-        $this->set('EVT_timezone_string', $timezone_string);
690
-    }
691
-
692
-
693
-    /**
694
-     * @param $visible_on
695
-     * @throws EE_Error
696
-     */
697
-    public function set_visible_on($visible_on)
698
-    {
699
-        $this->set('EVT_visible_on', $visible_on);
700
-    }
701
-
702
-
703
-    /**
704
-     * @param $wp_user
705
-     * @throws EE_Error
706
-     */
707
-    public function set_wp_user($wp_user)
708
-    {
709
-        $this->set('EVT_wp_user', $wp_user);
710
-    }
711
-
712
-
713
-    /**
714
-     * @param $default_registration_status
715
-     * @throws EE_Error
716
-     */
717
-    public function set_default_registration_status($default_registration_status)
718
-    {
719
-        $this->set('EVT_default_registration_status', $default_registration_status);
720
-    }
721
-
722
-
723
-    /**
724
-     * @param $donations
725
-     * @throws EE_Error
726
-     */
727
-    public function set_donations($donations)
728
-    {
729
-        $this->set('EVT_donations', $donations);
730
-    }
731
-
732
-
733
-    /**
734
-     * Adds a venue to this event
735
-     *
736
-     * @param int|EE_Venue /int $venue_id_or_obj
737
-     * @return EE_Base_Class|EE_Venue
738
-     * @throws EE_Error
739
-     * @throws ReflectionException
740
-     */
741
-    public function add_venue($venue_id_or_obj): EE_Venue
742
-    {
743
-        return $this->_add_relation_to($venue_id_or_obj, 'Venue');
744
-    }
745
-
746
-
747
-    /**
748
-     * Removes a venue from the event
749
-     *
750
-     * @param EE_Venue /int $venue_id_or_obj
751
-     * @return EE_Base_Class|EE_Venue
752
-     * @throws EE_Error
753
-     * @throws ReflectionException
754
-     */
755
-    public function remove_venue($venue_id_or_obj): EE_Venue
756
-    {
757
-        $venue_id_or_obj = ! empty($venue_id_or_obj) ? $venue_id_or_obj : $this->venue();
758
-        return $this->_remove_relation_to($venue_id_or_obj, 'Venue');
759
-    }
760
-
761
-
762
-    /**
763
-     * Gets the venue related to the event. May provide additional $query_params if desired
764
-     *
765
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
766
-     * @return int
767
-     * @throws EE_Error
768
-     * @throws ReflectionException
769
-     */
770
-    public function venue_ID(array $query_params = array()): int
771
-    {
772
-        $venue = $this->get_first_related('Venue', $query_params);
773
-        return $venue instanceof EE_Venue ? $venue->ID() : 0;
774
-    }
775
-
776
-
777
-    /**
778
-     * Gets the venue related to the event. May provide additional $query_params if desired
779
-     *
780
-     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
781
-     * @return EE_Base_Class|EE_Venue
782
-     * @throws EE_Error
783
-     * @throws ReflectionException
784
-     */
785
-    public function venue(array $query_params = array())
786
-    {
787
-        return $this->get_first_related('Venue', $query_params);
788
-    }
789
-
790
-
791
-    /**
792
-     * @param array $query_params
793
-     * @return EE_Base_Class[]|EE_Venue[]
794
-     * @throws EE_Error
795
-     * @throws ReflectionException
796
-     * @deprecated $VID:$
797
-     */
798
-    public function venues(array $query_params = array()): array
799
-    {
800
-        return [$this->venue($query_params)];
801
-    }
802
-
803
-
804
-    /**
805
-     * check if event id is present and if event is published
806
-     *
807
-     * @access public
808
-     * @return boolean true yes, false no
809
-     * @throws EE_Error
810
-     * @throws ReflectionException
811
-     */
812
-    private function _has_ID_and_is_published()
813
-    {
814
-        // first check if event id is present and not NULL,
815
-        // then check if this event is published (or any of the equivalent "published" statuses)
816
-        return
817
-            $this->ID() && $this->ID() !== null
818
-            && (
819
-                $this->status() === 'publish'
820
-                || $this->status() === EEM_Event::sold_out
821
-                || $this->status() === EEM_Event::postponed
822
-                || $this->status() === EEM_Event::cancelled
823
-            );
824
-    }
825
-
826
-
827
-    /**
828
-     * This simply compares the internal dates with NOW and determines if the event is upcoming or not.
829
-     *
830
-     * @access public
831
-     * @return boolean true yes, false no
832
-     * @throws EE_Error
833
-     * @throws ReflectionException
834
-     */
835
-    public function is_upcoming()
836
-    {
837
-        // check if event id is present and if this event is published
838
-        if ($this->is_inactive()) {
839
-            return false;
840
-        }
841
-        // set initial value
842
-        $upcoming = false;
843
-        // next let's get all datetimes and loop through them
844
-        $datetimes = $this->datetimes_in_chronological_order();
845
-        foreach ($datetimes as $datetime) {
846
-            if ($datetime instanceof EE_Datetime) {
847
-                // if this dtt is expired then we continue cause one of the other datetimes might be upcoming.
848
-                if ($datetime->is_expired()) {
849
-                    continue;
850
-                }
851
-                // if this dtt is active then we return false.
852
-                if ($datetime->is_active()) {
853
-                    return false;
854
-                }
855
-                // otherwise let's check upcoming status
856
-                $upcoming = $datetime->is_upcoming();
857
-            }
858
-        }
859
-        return $upcoming;
860
-    }
861
-
862
-
863
-    /**
864
-     * @return bool
865
-     * @throws EE_Error
866
-     * @throws ReflectionException
867
-     */
868
-    public function is_active()
869
-    {
870
-        // check if event id is present and if this event is published
871
-        if ($this->is_inactive()) {
872
-            return false;
873
-        }
874
-        // set initial value
875
-        $active = false;
876
-        // next let's get all datetimes and loop through them
877
-        $datetimes = $this->datetimes_in_chronological_order();
878
-        foreach ($datetimes as $datetime) {
879
-            if ($datetime instanceof EE_Datetime) {
880
-                // if this dtt is expired then we continue cause one of the other datetimes might be active.
881
-                if ($datetime->is_expired()) {
882
-                    continue;
883
-                }
884
-                // if this dtt is upcoming then we return false.
885
-                if ($datetime->is_upcoming()) {
886
-                    return false;
887
-                }
888
-                // otherwise let's check active status
889
-                $active = $datetime->is_active();
890
-            }
891
-        }
892
-        return $active;
893
-    }
894
-
895
-
896
-    /**
897
-     * @return bool
898
-     * @throws EE_Error
899
-     * @throws ReflectionException
900
-     */
901
-    public function is_expired()
902
-    {
903
-        // check if event id is present and if this event is published
904
-        if ($this->is_inactive()) {
905
-            return false;
906
-        }
907
-        // set initial value
908
-        $expired = false;
909
-        // first let's get all datetimes and loop through them
910
-        $datetimes = $this->datetimes_in_chronological_order();
911
-        foreach ($datetimes as $datetime) {
912
-            if ($datetime instanceof EE_Datetime) {
913
-                // if this dtt is upcoming or active then we return false.
914
-                if ($datetime->is_upcoming() || $datetime->is_active()) {
915
-                    return false;
916
-                }
917
-                // otherwise let's check active status
918
-                $expired = $datetime->is_expired();
919
-            }
920
-        }
921
-        return $expired;
922
-    }
923
-
924
-
925
-    /**
926
-     * @return bool
927
-     * @throws EE_Error
928
-     */
929
-    public function is_inactive()
930
-    {
931
-        // check if event id is present and if this event is published
932
-        if ($this->_has_ID_and_is_published()) {
933
-            return false;
934
-        }
935
-        return true;
936
-    }
937
-
938
-
939
-    /**
940
-     * calculate spaces remaining based on "saleable" tickets
941
-     *
942
-     * @param array $tickets
943
-     * @param bool  $filtered
944
-     * @return int|float
945
-     * @throws EE_Error
946
-     * @throws DomainException
947
-     * @throws UnexpectedEntityException
948
-     */
949
-    public function spaces_remaining($tickets = array(), $filtered = true)
950
-    {
951
-        $this->getAvailableSpacesCalculator()->setActiveTickets($tickets);
952
-        $spaces_remaining = $this->getAvailableSpacesCalculator()->spacesRemaining();
953
-        return $filtered
954
-            ? apply_filters(
955
-                'FHEE_EE_Event__spaces_remaining',
956
-                $spaces_remaining,
957
-                $this,
958
-                $tickets
959
-            )
960
-            : $spaces_remaining;
961
-    }
962
-
963
-
964
-    /**
965
-     *    perform_sold_out_status_check
966
-     *    checks all of this events's datetime  reg_limit - sold values to determine if ANY datetimes have spaces
967
-     *    available... if NOT, then the event status will get toggled to 'sold_out'
968
-     *
969
-     * @return bool    return the ACTUAL sold out state.
970
-     * @throws EE_Error
971
-     * @throws DomainException
972
-     * @throws UnexpectedEntityException
973
-     * @throws ReflectionException
974
-     */
975
-    public function perform_sold_out_status_check()
976
-    {
977
-        // get all tickets
978
-        $tickets = $this->tickets(
979
-            array(
980
-                'default_where_conditions' => 'none',
981
-                'order_by' => array('TKT_qty' => 'ASC'),
982
-            )
983
-        );
984
-        $all_expired = true;
985
-        foreach ($tickets as $ticket) {
986
-            if (! $ticket->is_expired()) {
987
-                $all_expired = false;
988
-                break;
989
-            }
990
-        }
991
-        // if all the tickets are just expired, then don't update the event status to sold out
992
-        if ($all_expired) {
993
-            return true;
994
-        }
995
-        $spaces_remaining = $this->spaces_remaining($tickets);
996
-        if ($spaces_remaining < 1) {
997
-            if ($this->status() !== EEM_Event::post_status_private) {
998
-                $this->set_status(EEM_Event::sold_out);
999
-                $this->save();
1000
-            }
1001
-            $sold_out = true;
1002
-        } else {
1003
-            $sold_out = false;
1004
-            // was event previously marked as sold out ?
1005
-            if ($this->status() === EEM_Event::sold_out) {
1006
-                // revert status to previous value, if it was set
1007
-                $previous_event_status = $this->get_post_meta('_previous_event_status', true);
1008
-                if ($previous_event_status) {
1009
-                    $this->set_status($previous_event_status);
1010
-                    $this->save();
1011
-                }
1012
-            }
1013
-        }
1014
-        do_action('AHEE__EE_Event__perform_sold_out_status_check__end', $this, $sold_out, $spaces_remaining, $tickets);
1015
-        return $sold_out;
1016
-    }
1017
-
1018
-
1019
-    /**
1020
-     * This returns the total remaining spaces for sale on this event.
1021
-     *
1022
-     * @uses EE_Event::total_available_spaces()
1023
-     * @return float|int
1024
-     * @throws EE_Error
1025
-     * @throws DomainException
1026
-     * @throws UnexpectedEntityException
1027
-     */
1028
-    public function spaces_remaining_for_sale()
1029
-    {
1030
-        return $this->total_available_spaces(true);
1031
-    }
1032
-
1033
-
1034
-    /**
1035
-     * This returns the total spaces available for an event
1036
-     * while considering all the qtys on the tickets and the reg limits
1037
-     * on the datetimes attached to this event.
1038
-     *
1039
-     * @param   bool $consider_sold Whether to consider any tickets that have already sold in our calculation.
1040
-     *                              If this is false, then we return the most tickets that could ever be sold
1041
-     *                              for this event with the datetime and tickets setup on the event under optimal
1042
-     *                              selling conditions.  Otherwise we return a live calculation of spaces available
1043
-     *                              based on tickets sold.  Depending on setup and stage of sales, this
1044
-     *                              may appear to equal remaining tickets.  However, the more tickets are
1045
-     *                              sold out, the more accurate the "live" total is.
1046
-     * @return float|int
1047
-     * @throws EE_Error
1048
-     * @throws DomainException
1049
-     * @throws UnexpectedEntityException
1050
-     */
1051
-    public function total_available_spaces($consider_sold = false)
1052
-    {
1053
-        $spaces_available = $consider_sold
1054
-            ? $this->getAvailableSpacesCalculator()->spacesRemaining()
1055
-            : $this->getAvailableSpacesCalculator()->totalSpacesAvailable();
1056
-        return apply_filters(
1057
-            'FHEE_EE_Event__total_available_spaces__spaces_available',
1058
-            $spaces_available,
1059
-            $this,
1060
-            $this->getAvailableSpacesCalculator()->getDatetimes(),
1061
-            $this->getAvailableSpacesCalculator()->getActiveTickets()
1062
-        );
1063
-    }
1064
-
1065
-
1066
-    /**
1067
-     * Checks if the event is set to sold out
1068
-     *
1069
-     * @param  bool $actual whether or not to perform calculations to not only figure the
1070
-     *                      actual status but also to flip the status if necessary to sold
1071
-     *                      out If false, we just check the existing status of the event
1072
-     * @return boolean
1073
-     * @throws EE_Error
1074
-     */
1075
-    public function is_sold_out($actual = false)
1076
-    {
1077
-        if (! $actual) {
1078
-            return $this->status() === EEM_Event::sold_out;
1079
-        }
1080
-        return $this->perform_sold_out_status_check();
1081
-    }
1082
-
1083
-
1084
-    /**
1085
-     * Checks if the event is marked as postponed
1086
-     *
1087
-     * @return boolean
1088
-     */
1089
-    public function is_postponed()
1090
-    {
1091
-        return $this->status() === EEM_Event::postponed;
1092
-    }
1093
-
1094
-
1095
-    /**
1096
-     * Checks if the event is marked as cancelled
1097
-     *
1098
-     * @return boolean
1099
-     */
1100
-    public function is_cancelled()
1101
-    {
1102
-        return $this->status() === EEM_Event::cancelled;
1103
-    }
1104
-
1105
-
1106
-    /**
1107
-     * Get the logical active status in a hierarchical order for all the datetimes.  Note
1108
-     * Basically, we order the datetimes by EVT_start_date.  Then first test on whether the event is published.  If its
1109
-     * NOT published then we test for whether its expired or not.  IF it IS published then we test first on whether an
1110
-     * event has any active dates.  If no active dates then we check for any upcoming dates.  If no upcoming dates then
1111
-     * the event is considered expired.
1112
-     * NOTE: this method does NOT calculate whether the datetimes are sold out when event is published.  Sold Out is a
1113
-     * status set on the EVENT when it is not published and thus is done
1114
-     *
1115
-     * @param bool $reset
1116
-     * @return bool | string - based on EE_Datetime active constants or FALSE if error.
1117
-     * @throws EE_Error
1118
-     * @throws ReflectionException
1119
-     */
1120
-    public function get_active_status($reset = false)
1121
-    {
1122
-        // if the active status has already been set, then just use that value (unless we are resetting it)
1123
-        if (! empty($this->_active_status) && ! $reset) {
1124
-            return $this->_active_status;
1125
-        }
1126
-        // first check if event id is present on this object
1127
-        if (! $this->ID()) {
1128
-            return false;
1129
-        }
1130
-        $where_params_for_event = array(array('EVT_ID' => $this->ID()));
1131
-        // if event is published:
1132
-        if ($this->status() === EEM_Event::post_status_publish || $this->status() === EEM_Event::post_status_private) {
1133
-            // active?
1134
-            if (
1135
-                EEM_Datetime::instance()->get_datetime_count_for_status(
1136
-                    EE_Datetime::active,
1137
-                    $where_params_for_event
1138
-                ) > 0
1139
-            ) {
1140
-                $this->_active_status = EE_Datetime::active;
1141
-            } else {
1142
-                // upcoming?
1143
-                if (
1144
-                    EEM_Datetime::instance()->get_datetime_count_for_status(
1145
-                        EE_Datetime::upcoming,
1146
-                        $where_params_for_event
1147
-                    ) > 0
1148
-                ) {
1149
-                    $this->_active_status = EE_Datetime::upcoming;
1150
-                } else {
1151
-                    // expired?
1152
-                    if (
1153
-                        EEM_Datetime::instance()->get_datetime_count_for_status(
1154
-                            EE_Datetime::expired,
1155
-                            $where_params_for_event
1156
-                        ) > 0
1157
-                    ) {
1158
-                        $this->_active_status = EE_Datetime::expired;
1159
-                    } else {
1160
-                        // it would be odd if things make it this far because it basically means there are no datetime's
1161
-                        // attached to the event.  So in this case it will just be considered inactive.
1162
-                        $this->_active_status = EE_Datetime::inactive;
1163
-                    }
1164
-                }
1165
-            }
1166
-        } else {
1167
-            // the event is not published, so let's just set it's active status according to its' post status
1168
-            switch ($this->status()) {
1169
-                case EEM_Event::sold_out:
1170
-                    $this->_active_status = EE_Datetime::sold_out;
1171
-                    break;
1172
-                case EEM_Event::cancelled:
1173
-                    $this->_active_status = EE_Datetime::cancelled;
1174
-                    break;
1175
-                case EEM_Event::postponed:
1176
-                    $this->_active_status = EE_Datetime::postponed;
1177
-                    break;
1178
-                default:
1179
-                    $this->_active_status = EE_Datetime::inactive;
1180
-            }
1181
-        }
1182
-        return $this->_active_status;
1183
-    }
1184
-
1185
-
1186
-    /**
1187
-     *    pretty_active_status
1188
-     *
1189
-     * @access public
1190
-     * @param boolean $echo whether to return (FALSE), or echo out the result (TRUE)
1191
-     * @return mixed void|string
1192
-     * @throws EE_Error
1193
-     * @throws ReflectionException
1194
-     */
1195
-    public function pretty_active_status($echo = true)
1196
-    {
1197
-        $active_status = $this->get_active_status();
1198
-        $status = '<span class="ee-status ee-status-bg--' . esc_attr($active_status) . ' event-active-status-' .
1199
-                  esc_attr($active_status) . '">'
1200
-                  . EEH_Template::pretty_status($active_status, false, 'sentence')
1201
-                  . '</span>';
1202
-        if ($echo) {
1203
-            echo wp_kses($status, AllowedTags::getAllowedTags());
1204
-            return '';
1205
-        }
1206
-        return $status; // already escaped
1207
-    }
1208
-
1209
-
1210
-    /**
1211
-     * @return bool|int
1212
-     * @throws EE_Error
1213
-     * @throws ReflectionException
1214
-     */
1215
-    public function get_number_of_tickets_sold()
1216
-    {
1217
-        $tkt_sold = 0;
1218
-        if (! $this->ID()) {
1219
-            return 0;
1220
-        }
1221
-        $datetimes = $this->datetimes();
1222
-        foreach ($datetimes as $datetime) {
1223
-            if ($datetime instanceof EE_Datetime) {
1224
-                $tkt_sold += $datetime->sold();
1225
-            }
1226
-        }
1227
-        return $tkt_sold;
1228
-    }
1229
-
1230
-
1231
-    /**
1232
-     * This just returns a count of all the registrations for this event
1233
-     *
1234
-     * @access  public
1235
-     * @return int
1236
-     * @throws EE_Error
1237
-     */
1238
-    public function get_count_of_all_registrations()
1239
-    {
1240
-        return EEM_Event::instance()->count_related($this, 'Registration');
1241
-    }
1242
-
1243
-
1244
-    /**
1245
-     * This returns the ticket with the earliest start time that is
1246
-     * available for this event (across all datetimes attached to the event)
1247
-     *
1248
-     * @return EE_Base_Class|EE_Ticket|null
1249
-     * @throws EE_Error
1250
-     * @throws ReflectionException
1251
-     */
1252
-    public function get_ticket_with_earliest_start_time()
1253
-    {
1254
-        $where['Datetime.EVT_ID'] = $this->ID();
1255
-        $query_params = array($where, 'order_by' => array('TKT_start_date' => 'ASC'));
1256
-        return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1257
-    }
1258
-
1259
-
1260
-    /**
1261
-     * This returns the ticket with the latest end time that is available
1262
-     * for this event (across all datetimes attached to the event)
1263
-     *
1264
-     * @return EE_Base_Class|EE_Ticket|null
1265
-     * @throws EE_Error
1266
-     * @throws ReflectionException
1267
-     */
1268
-    public function get_ticket_with_latest_end_time()
1269
-    {
1270
-        $where['Datetime.EVT_ID'] = $this->ID();
1271
-        $query_params = array($where, 'order_by' => array('TKT_end_date' => 'DESC'));
1272
-        return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1273
-    }
1274
-
1275
-
1276
-    /**
1277
-     * This returns the number of different ticket types currently on sale for this event.
1278
-     *
1279
-     * @return int
1280
-     * @throws EE_Error
1281
-     * @throws ReflectionException
1282
-     */
1283
-    public function countTicketsOnSale()
1284
-    {
1285
-        $where = array(
1286
-            'Datetime.EVT_ID' => $this->ID(),
1287
-            'TKT_start_date'  => array('<', time()),
1288
-            'TKT_end_date'    => array('>', time()),
1289
-        );
1290
-        return EEM_Ticket::instance()->count(array($where));
1291
-    }
1292
-
1293
-
1294
-    /**
1295
-     * This returns whether there are any tickets on sale for this event.
1296
-     *
1297
-     * @return bool true = YES tickets on sale.
1298
-     * @throws EE_Error
1299
-     */
1300
-    public function tickets_on_sale()
1301
-    {
1302
-        return $this->countTicketsOnSale() > 0;
1303
-    }
1304
-
1305
-
1306
-    /**
1307
-     * Gets the URL for viewing this event on the front-end. Overrides parent
1308
-     * to check for an external URL first
1309
-     *
1310
-     * @return string
1311
-     * @throws EE_Error
1312
-     */
1313
-    public function get_permalink()
1314
-    {
1315
-        if ($this->external_url()) {
1316
-            return $this->external_url();
1317
-        }
1318
-        return parent::get_permalink();
1319
-    }
1320
-
1321
-
1322
-    /**
1323
-     * Gets the first term for 'espresso_event_categories' we can find
1324
-     *
1325
-     * @param array $query_params @see
1326
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1327
-     * @return EE_Base_Class|EE_Term|null
1328
-     * @throws EE_Error
1329
-     * @throws ReflectionException
1330
-     */
1331
-    public function first_event_category($query_params = array())
1332
-    {
1333
-        $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1334
-        $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1335
-        return EEM_Term::instance()->get_one($query_params);
1336
-    }
1337
-
1338
-
1339
-    /**
1340
-     * Gets all terms for 'espresso_event_categories' we can find
1341
-     *
1342
-     * @param array $query_params
1343
-     * @return EE_Base_Class[]|EE_Term[]
1344
-     * @throws EE_Error
1345
-     * @throws ReflectionException
1346
-     */
1347
-    public function get_all_event_categories($query_params = array())
1348
-    {
1349
-        $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1350
-        $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1351
-        return EEM_Term::instance()->get_all($query_params);
1352
-    }
1353
-
1354
-
1355
-    /**
1356
-     * Adds a question group to this event
1357
-     *
1358
-     * @param EE_Question_Group|int $question_group_id_or_obj
1359
-     * @param bool $for_primary if true, the question group will be added for the primary
1360
-     *                                           registrant, if false will be added for others. default: false
1361
-     * @return EE_Base_Class|EE_Question_Group
1362
-     * @throws EE_Error
1363
-     * @throws InvalidArgumentException
1364
-     * @throws InvalidDataTypeException
1365
-     * @throws InvalidInterfaceException
1366
-     * @throws ReflectionException
1367
-     */
1368
-    public function add_question_group($question_group_id_or_obj, $for_primary = false)
1369
-    {
1370
-        // If the row already exists, it will be updated. If it doesn't, it will be inserted.
1371
-        // That's in EE_HABTM_Relation::add_relation_to().
1372
-        return $this->_add_relation_to(
1373
-            $question_group_id_or_obj,
1374
-            'Question_Group',
1375
-            [
1376
-                EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary) => true
1377
-            ]
1378
-        );
1379
-    }
1380
-
1381
-
1382
-    /**
1383
-     * Removes a question group from the event
1384
-     *
1385
-     * @param EE_Question_Group|int $question_group_id_or_obj
1386
-     * @param bool $for_primary if true, the question group will be removed from the primary
1387
-     *                                           registrant, if false will be removed from others. default: false
1388
-     * @return EE_Base_Class|EE_Question_Group
1389
-     * @throws EE_Error
1390
-     * @throws InvalidArgumentException
1391
-     * @throws ReflectionException
1392
-     * @throws InvalidDataTypeException
1393
-     * @throws InvalidInterfaceException
1394
-     */
1395
-    public function remove_question_group($question_group_id_or_obj, $for_primary = false)
1396
-    {
1397
-        // If the question group is used for the other type (primary or additional)
1398
-        // then just update it. If not, delete it outright.
1399
-        $existing_relation = $this->get_first_related(
1400
-            'Event_Question_Group',
1401
-            [
1402
-                [
1403
-                    'QSG_ID' => EEM_Question_Group::instance()->ensure_is_ID($question_group_id_or_obj)
1404
-                ]
1405
-            ]
1406
-        );
1407
-        $field_to_update = EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary);
1408
-        $other_field = EEM_Event_Question_Group::instance()->fieldNameForContext(! $for_primary);
1409
-        if ($existing_relation->get($other_field) === false) {
1410
-            // Delete it. It's now no longer for primary or additional question groups.
1411
-            return $this->_remove_relation_to($question_group_id_or_obj, 'Question_Group');
1412
-        }
1413
-        // Just update it. They'll still use this question group for the other category
1414
-        $existing_relation->save(
1415
-            [
1416
-                $field_to_update => false
1417
-            ]
1418
-        );
1419
-    }
1420
-
1421
-
1422
-    /**
1423
-     * Gets all the question groups, ordering them by QSG_order ascending
1424
-     *
1425
-     * @param array $query_params @see
1426
-     *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1427
-     * @return EE_Base_Class[]|EE_Question_Group[]
1428
-     * @throws EE_Error
1429
-     * @throws ReflectionException
1430
-     */
1431
-    public function question_groups($query_params = array())
1432
-    {
1433
-        $query_params = ! empty($query_params) ? $query_params : array('order_by' => array('QSG_order' => 'ASC'));
1434
-        return $this->get_many_related('Question_Group', $query_params);
1435
-    }
1436
-
1437
-
1438
-    /**
1439
-     * Implementation for EEI_Has_Icon interface method.
1440
-     *
1441
-     * @see EEI_Visual_Representation for comments
1442
-     * @return string
1443
-     */
1444
-    public function get_icon()
1445
-    {
1446
-        return '<span class="dashicons dashicons-flag"></span>';
1447
-    }
1448
-
1449
-
1450
-    /**
1451
-     * Implementation for EEI_Admin_Links interface method.
1452
-     *
1453
-     * @see EEI_Admin_Links for comments
1454
-     * @return string
1455
-     * @throws EE_Error
1456
-     */
1457
-    public function get_admin_details_link()
1458
-    {
1459
-        return $this->get_admin_edit_link();
1460
-    }
1461
-
1462
-
1463
-    /**
1464
-     * Implementation for EEI_Admin_Links interface method.
1465
-     *
1466
-     * @return string
1467
-     * @throws EE_Error*@throws ReflectionException
1468
-     * @see EEI_Admin_Links for comments
1469
-     */
1470
-    public function get_admin_edit_link()
1471
-    {
1472
-        return EEH_URL::add_query_args_and_nonce(
1473
-            array(
1474
-                'page'   => 'espresso_events',
1475
-                'action' => 'edit',
1476
-                'post'   => $this->ID(),
1477
-            ),
1478
-            admin_url('admin.php')
1479
-        );
1480
-    }
1481
-
1482
-
1483
-    /**
1484
-     * Implementation for EEI_Admin_Links interface method.
1485
-     *
1486
-     * @see EEI_Admin_Links for comments
1487
-     * @return string
1488
-     */
1489
-    public function get_admin_settings_link()
1490
-    {
1491
-        return EEH_URL::add_query_args_and_nonce(
1492
-            array(
1493
-                'page'   => 'espresso_events',
1494
-                'action' => 'default_event_settings',
1495
-            ),
1496
-            admin_url('admin.php')
1497
-        );
1498
-    }
1499
-
1500
-
1501
-    /**
1502
-     * Implementation for EEI_Admin_Links interface method.
1503
-     *
1504
-     * @see EEI_Admin_Links for comments
1505
-     * @return string
1506
-     */
1507
-    public function get_admin_overview_link()
1508
-    {
1509
-        return EEH_URL::add_query_args_and_nonce(
1510
-            array(
1511
-                'page'   => 'espresso_events',
1512
-                'action' => 'default',
1513
-            ),
1514
-            admin_url('admin.php')
1515
-        );
1516
-    }
1517
-
1518
-
1519
-    /**
1520
-     * @return string|null
1521
-     * @throws EE_Error
1522
-     * @throws ReflectionException
1523
-     */
1524
-    public function registrationFormUuid(): ?string
1525
-    {
1526
-        return $this->get('FSC_UUID');
1527
-    }
1528
-
1529
-
1530
-    /**
1531
-     * Gets all the form sections for this event
1532
-     *
1533
-     * @return EE_Base_Class[]|EE_Form_Section[]
1534
-     * @throws EE_Error
1535
-     * @throws ReflectionException
1536
-     */
1537
-    public function registrationForm()
1538
-    {
1539
-        $FSC_UUID = $this->registrationFormUuid();
1540
-
1541
-        if (empty($FSC_UUID)) {
1542
-            return [];
1543
-        }
1544
-
1545
-        return EEM_Form_Section::instance()->get_all([
1546
-            [
1547
-                'OR' => [
1548
-                    'FSC_UUID'      => $FSC_UUID, // top level form
1549
-                    'FSC_belongsTo' => $FSC_UUID, // child form sections
1550
-                ]
1551
-                ],
1552
-            'order_by' => ['FSC_order' => 'ASC'],
1553
-        ]);
1554
-    }
1555
-
1556
-
1557
-    /**
1558
-     * @param string $UUID
1559
-     * @throws EE_Error
1560
-     */
1561
-    public function setRegistrationFormUuid(string $UUID): void
1562
-    {
1563
-        if (! Cuid::isCuid($UUID)) {
1564
-            throw new InvalidArgumentException(
1565
-                sprintf(
1566
-                /* translators: 1: UUID value, 2: UUID generator function. */
1567
-                    esc_html__(
1568
-                        'The supplied UUID "%1$s" is invalid or missing. Please use %2$s to generate a valid one.',
1569
-                        'event_espresso'
1570
-                    ),
1571
-                    $UUID,
1572
-                    '`Cuid::cuid()`'
1573
-                )
1574
-            );
1575
-        }
1576
-        $this->set('FSC_UUID', $UUID);
1577
-    }
19
+	/**
20
+	 * cached value for the the logical active status for the event
21
+	 *
22
+	 * @see get_active_status()
23
+	 * @var string
24
+	 */
25
+	protected $_active_status = '';
26
+
27
+	/**
28
+	 * This is just used for caching the Primary Datetime for the Event on initial retrieval
29
+	 *
30
+	 * @var EE_Datetime
31
+	 */
32
+	protected $_Primary_Datetime;
33
+
34
+	/**
35
+	 * @var EventSpacesCalculator $available_spaces_calculator
36
+	 */
37
+	protected $available_spaces_calculator;
38
+
39
+
40
+	/**
41
+	 * @param array  $props_n_values          incoming values
42
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
43
+	 *                                        used.)
44
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
45
+	 *                                        date_format and the second value is the time format
46
+	 * @return EE_Event
47
+	 * @throws EE_Error
48
+	 * @throws ReflectionException
49
+	 */
50
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
51
+	{
52
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
53
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
54
+	}
55
+
56
+
57
+	/**
58
+	 * @param array  $props_n_values  incoming values from the database
59
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
60
+	 *                                the website will be used.
61
+	 * @return EE_Event
62
+	 * @throws EE_Error
63
+	 * @throws ReflectionException
64
+	 */
65
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
66
+	{
67
+		return new self($props_n_values, true, $timezone);
68
+	}
69
+
70
+
71
+	/**
72
+	 * @return EventSpacesCalculator
73
+	 * @throws \EE_Error
74
+	 */
75
+	public function getAvailableSpacesCalculator()
76
+	{
77
+		if (! $this->available_spaces_calculator instanceof EventSpacesCalculator) {
78
+			$this->available_spaces_calculator = new EventSpacesCalculator($this);
79
+		}
80
+		return $this->available_spaces_calculator;
81
+	}
82
+
83
+
84
+	/**
85
+	 * Overrides parent set() method so that all calls to set( 'status', $status ) can be routed to internal methods
86
+	 *
87
+	 * @param string $field_name
88
+	 * @param mixed  $field_value
89
+	 * @param bool   $use_default
90
+	 * @throws EE_Error
91
+	 * @throws ReflectionException
92
+	 */
93
+	public function set($field_name, $field_value, $use_default = false)
94
+	{
95
+		switch ($field_name) {
96
+			case 'status':
97
+				$this->set_status($field_value, $use_default);
98
+				break;
99
+			default:
100
+				parent::set($field_name, $field_value, $use_default);
101
+		}
102
+	}
103
+
104
+
105
+	/**
106
+	 *    set_status
107
+	 * Checks if event status is being changed to SOLD OUT
108
+	 * and updates event meta data with previous event status
109
+	 * so that we can revert things if/when the event is no longer sold out
110
+	 *
111
+	 * @access public
112
+	 * @param string $new_status
113
+	 * @param bool   $use_default
114
+	 * @return void
115
+	 * @throws EE_Error
116
+	 * @throws ReflectionException
117
+	 */
118
+	public function set_status($new_status = null, $use_default = false)
119
+	{
120
+		// if nothing is set, and we aren't explicitly wanting to reset the status, then just leave
121
+		if (empty($new_status) && ! $use_default) {
122
+			return;
123
+		}
124
+		// get current Event status
125
+		$old_status = $this->status();
126
+		// if status has changed
127
+		if ($old_status !== $new_status) {
128
+			// TO sold_out
129
+			if ($new_status === EEM_Event::sold_out) {
130
+				// save the previous event status so that we can revert if the event is no longer sold out
131
+				$this->add_post_meta('_previous_event_status', $old_status);
132
+				do_action('AHEE__EE_Event__set_status__to_sold_out', $this, $old_status, $new_status);
133
+			// OR FROM  sold_out
134
+			} elseif ($old_status === EEM_Event::sold_out) {
135
+				$this->delete_post_meta('_previous_event_status');
136
+				do_action('AHEE__EE_Event__set_status__from_sold_out', $this, $old_status, $new_status);
137
+			}
138
+			// clear out the active status so that it gets reset the next time it is requested
139
+			$this->_active_status = null;
140
+			// update status
141
+			parent::set('status', $new_status, $use_default);
142
+			do_action('AHEE__EE_Event__set_status__after_update', $this);
143
+			return;
144
+		}
145
+		// even though the old value matches the new value, it's still good to
146
+		// allow the parent set method to have a say
147
+		parent::set('status', $new_status, $use_default);
148
+	}
149
+
150
+
151
+	/**
152
+	 * Gets all the datetimes for this event
153
+	 *
154
+	 * @param array $query_params @see
155
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
156
+	 * @return EE_Base_Class[]|EE_Datetime[]
157
+	 * @throws EE_Error
158
+	 * @throws ReflectionException
159
+	 */
160
+	public function datetimes($query_params = array())
161
+	{
162
+		return $this->get_many_related('Datetime', $query_params);
163
+	}
164
+
165
+
166
+	/**
167
+	 * Gets all the datetimes for this event that are currently ACTIVE,
168
+	 * meaning the datetime has started and has not yet ended.
169
+	 *
170
+	 * @param int|null $start_date      timestamp to use for event date start time, defaults to NOW unless set to 0
171
+	 * @param array|null $query_params  will recursively replace default values
172
+	 * @throws EE_Error
173
+	 * @throws ReflectionException
174
+	 * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
175
+	 */
176
+	public function activeDatetimes(?int $start_date, ?array $query_params = []): array
177
+	{
178
+		// if start date is null, then use current time
179
+		$start_date = $start_date ?? time();
180
+		$where = [];
181
+		if ($start_date) {
182
+			$where['DTT_EVT_start'] = ['<', $start_date];
183
+			$where['DTT_EVT_end']   = ['>', time()];
184
+		}
185
+		$query_params = array_replace_recursive(
186
+			[
187
+				$where,
188
+				'order_by' => ['DTT_EVT_start' => 'ASC']
189
+			],
190
+			$query_params
191
+		);
192
+		return $this->get_many_related('Datetime', $query_params);
193
+	}
194
+
195
+
196
+	/**
197
+	 * Gets all the datetimes for this event, ordered by DTT_EVT_start in ascending order
198
+	 *
199
+	 * @return EE_Base_Class[]|EE_Datetime[]
200
+	 * @throws EE_Error
201
+	 * @throws ReflectionException
202
+	 */
203
+	public function datetimes_in_chronological_order()
204
+	{
205
+		return $this->get_many_related('Datetime', array('order_by' => array('DTT_EVT_start' => 'ASC')));
206
+	}
207
+
208
+
209
+	/**
210
+	 * Gets all the datetimes for this event, ordered by the DTT_order on the datetime.
211
+	 * @darren, we should probably UNSET timezone on the EEM_Datetime model
212
+	 * after running our query, so that this timezone isn't set for EVERY query
213
+	 * on EEM_Datetime for the rest of the request, no?
214
+	 *
215
+	 * @param boolean $show_expired whether or not to include expired events
216
+	 * @param boolean $show_deleted whether or not to include deleted events
217
+	 * @param null    $limit
218
+	 * @return EE_Datetime[]
219
+	 * @throws EE_Error
220
+	 * @throws ReflectionException
221
+	 */
222
+	public function datetimes_ordered($show_expired = true, $show_deleted = false, $limit = null)
223
+	{
224
+		return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_event_ordered_by_DTT_order(
225
+			$this->ID(),
226
+			$show_expired,
227
+			$show_deleted,
228
+			$limit
229
+		);
230
+	}
231
+
232
+
233
+	/**
234
+	 * Returns one related datetime. Mostly only used by some legacy code.
235
+	 *
236
+	 * @return EE_Base_Class|EE_Datetime
237
+	 * @throws EE_Error
238
+	 * @throws ReflectionException
239
+	 */
240
+	public function first_datetime()
241
+	{
242
+		return $this->get_first_related('Datetime');
243
+	}
244
+
245
+
246
+	/**
247
+	 * Returns the 'primary' datetime for the event
248
+	 *
249
+	 * @param bool $try_to_exclude_expired
250
+	 * @param bool $try_to_exclude_deleted
251
+	 * @return EE_Datetime
252
+	 * @throws EE_Error
253
+	 * @throws ReflectionException
254
+	 */
255
+	public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true)
256
+	{
257
+		if (! empty($this->_Primary_Datetime)) {
258
+			return $this->_Primary_Datetime;
259
+		}
260
+		$this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)->get_primary_datetime_for_event(
261
+			$this->ID(),
262
+			$try_to_exclude_expired,
263
+			$try_to_exclude_deleted
264
+		);
265
+		return $this->_Primary_Datetime;
266
+	}
267
+
268
+
269
+	/**
270
+	 * Gets all the tickets available for purchase of this event
271
+	 *
272
+	 * @param array $query_params @see
273
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
274
+	 * @return EE_Base_Class[]|EE_Ticket[]
275
+	 * @throws EE_Error
276
+	 * @throws ReflectionException
277
+	 */
278
+	public function tickets($query_params = array())
279
+	{
280
+		// first get all datetimes
281
+		$datetimes = $this->datetimes_ordered();
282
+		if (! $datetimes) {
283
+			return array();
284
+		}
285
+		$datetime_ids = array();
286
+		foreach ($datetimes as $datetime) {
287
+			$datetime_ids[] = $datetime->ID();
288
+		}
289
+		$where_params = array('Datetime.DTT_ID' => array('IN', $datetime_ids));
290
+		// if incoming $query_params has where conditions let's merge but not override existing.
291
+		if (is_array($query_params) && isset($query_params[0])) {
292
+			$where_params = array_merge($query_params[0], $where_params);
293
+			unset($query_params[0]);
294
+		}
295
+		// now add $where_params to $query_params
296
+		$query_params[0] = $where_params;
297
+		return EEM_Ticket::instance()->get_all($query_params);
298
+	}
299
+
300
+
301
+	/**
302
+	 * get all unexpired untrashed tickets
303
+	 *
304
+	 * @return EE_Ticket[]
305
+	 * @throws EE_Error
306
+	 */
307
+	public function active_tickets()
308
+	{
309
+		return $this->tickets(
310
+			array(
311
+				array(
312
+					'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
313
+					'TKT_deleted'  => false,
314
+				),
315
+			)
316
+		);
317
+	}
318
+
319
+
320
+	/**
321
+	 * @return bool
322
+	 * @throws EE_Error
323
+	 * @throws ReflectionException
324
+	 */
325
+	public function additional_limit()
326
+	{
327
+		return $this->get('EVT_additional_limit');
328
+	}
329
+
330
+
331
+	/**
332
+	 * @return bool
333
+	 * @throws EE_Error
334
+	 * @throws ReflectionException
335
+	 */
336
+	public function allow_overflow()
337
+	{
338
+		return $this->get('EVT_allow_overflow');
339
+	}
340
+
341
+
342
+	/**
343
+	 * @return bool
344
+	 * @throws EE_Error
345
+	 * @throws ReflectionException
346
+	 */
347
+	public function created()
348
+	{
349
+		return $this->get('EVT_created');
350
+	}
351
+
352
+
353
+	/**
354
+	 * @return bool
355
+	 * @throws EE_Error
356
+	 * @throws ReflectionException
357
+	 */
358
+	public function description()
359
+	{
360
+		return $this->get('EVT_desc');
361
+	}
362
+
363
+
364
+	/**
365
+	 * Runs do_shortcode and wpautop on the description
366
+	 *
367
+	 * @return string of html
368
+	 * @throws EE_Error
369
+	 * @throws ReflectionException
370
+	 */
371
+	public function description_filtered()
372
+	{
373
+		return $this->get_pretty('EVT_desc');
374
+	}
375
+
376
+
377
+	/**
378
+	 * @return bool
379
+	 * @throws EE_Error
380
+	 * @throws ReflectionException
381
+	 */
382
+	public function display_description()
383
+	{
384
+		return $this->get('EVT_display_desc');
385
+	}
386
+
387
+
388
+	/**
389
+	 * @return bool
390
+	 * @throws EE_Error
391
+	 * @throws ReflectionException
392
+	 */
393
+	public function display_ticket_selector()
394
+	{
395
+		return (bool) $this->get('EVT_display_ticket_selector');
396
+	}
397
+
398
+
399
+	/**
400
+	 * @return string
401
+	 * @throws EE_Error
402
+	 * @throws ReflectionException
403
+	 */
404
+	public function external_url()
405
+	{
406
+		return $this->get('EVT_external_URL');
407
+	}
408
+
409
+
410
+	/**
411
+	 * @return bool
412
+	 * @throws EE_Error
413
+	 * @throws ReflectionException
414
+	 */
415
+	public function member_only()
416
+	{
417
+		return $this->get('EVT_member_only');
418
+	}
419
+
420
+
421
+	/**
422
+	 * @return bool
423
+	 * @throws EE_Error
424
+	 * @throws ReflectionException
425
+	 */
426
+	public function phone()
427
+	{
428
+		return $this->get('EVT_phone');
429
+	}
430
+
431
+
432
+	/**
433
+	 * @return bool
434
+	 * @throws EE_Error
435
+	 * @throws ReflectionException
436
+	 */
437
+	public function modified()
438
+	{
439
+		return $this->get('EVT_modified');
440
+	}
441
+
442
+
443
+	/**
444
+	 * @return bool
445
+	 * @throws EE_Error
446
+	 * @throws ReflectionException
447
+	 */
448
+	public function name()
449
+	{
450
+		return $this->get('EVT_name');
451
+	}
452
+
453
+
454
+	/**
455
+	 * @return bool
456
+	 * @throws EE_Error
457
+	 * @throws ReflectionException
458
+	 */
459
+	public function order()
460
+	{
461
+		return $this->get('EVT_order');
462
+	}
463
+
464
+
465
+	/**
466
+	 * @return bool|string
467
+	 * @throws EE_Error
468
+	 * @throws ReflectionException
469
+	 */
470
+	public function default_registration_status()
471
+	{
472
+		$event_default_registration_status = $this->get('EVT_default_registration_status');
473
+		return ! empty($event_default_registration_status)
474
+			? $event_default_registration_status
475
+			: EE_Registry::instance()->CFG->registration->default_STS_ID;
476
+	}
477
+
478
+
479
+	/**
480
+	 * @param int  $num_words
481
+	 * @param null $more
482
+	 * @param bool $not_full_desc
483
+	 * @return bool|string
484
+	 * @throws EE_Error
485
+	 * @throws ReflectionException
486
+	 */
487
+	public function short_description($num_words = 55, $more = null, $not_full_desc = false)
488
+	{
489
+		$short_desc = $this->get('EVT_short_desc');
490
+		if (! empty($short_desc) || $not_full_desc) {
491
+			return $short_desc;
492
+		}
493
+		$full_desc = $this->get('EVT_desc');
494
+		return wp_trim_words($full_desc, $num_words, $more);
495
+	}
496
+
497
+
498
+	/**
499
+	 * @return bool
500
+	 * @throws EE_Error
501
+	 * @throws ReflectionException
502
+	 */
503
+	public function slug()
504
+	{
505
+		return $this->get('EVT_slug');
506
+	}
507
+
508
+
509
+	/**
510
+	 * @return bool
511
+	 * @throws EE_Error
512
+	 * @throws ReflectionException
513
+	 */
514
+	public function timezone_string()
515
+	{
516
+		return $this->get('EVT_timezone_string');
517
+	}
518
+
519
+
520
+	/**
521
+	 * @return bool
522
+	 * @throws EE_Error
523
+	 * @throws ReflectionException
524
+	 */
525
+	public function visible_on()
526
+	{
527
+		return $this->get('EVT_visible_on');
528
+	}
529
+
530
+
531
+	/**
532
+	 * @return int
533
+	 * @throws EE_Error
534
+	 * @throws ReflectionException
535
+	 */
536
+	public function wp_user()
537
+	{
538
+		return $this->get('EVT_wp_user');
539
+	}
540
+
541
+
542
+	/**
543
+	 * @return bool
544
+	 * @throws EE_Error
545
+	 * @throws ReflectionException
546
+	 */
547
+	public function donations()
548
+	{
549
+		return $this->get('EVT_donations');
550
+	}
551
+
552
+
553
+	/**
554
+	 * @param $limit
555
+	 * @throws EE_Error
556
+	 */
557
+	public function set_additional_limit($limit)
558
+	{
559
+		$this->set('EVT_additional_limit', $limit);
560
+	}
561
+
562
+
563
+	/**
564
+	 * @param $created
565
+	 * @throws EE_Error
566
+	 */
567
+	public function set_created($created)
568
+	{
569
+		$this->set('EVT_created', $created);
570
+	}
571
+
572
+
573
+	/**
574
+	 * @param $desc
575
+	 * @throws EE_Error
576
+	 */
577
+	public function set_description($desc)
578
+	{
579
+		$this->set('EVT_desc', $desc);
580
+	}
581
+
582
+
583
+	/**
584
+	 * @param $display_desc
585
+	 * @throws EE_Error
586
+	 */
587
+	public function set_display_description($display_desc)
588
+	{
589
+		$this->set('EVT_display_desc', $display_desc);
590
+	}
591
+
592
+
593
+	/**
594
+	 * @param $display_ticket_selector
595
+	 * @throws EE_Error
596
+	 */
597
+	public function set_display_ticket_selector($display_ticket_selector)
598
+	{
599
+		$this->set('EVT_display_ticket_selector', $display_ticket_selector);
600
+	}
601
+
602
+
603
+	/**
604
+	 * @param $external_url
605
+	 * @throws EE_Error
606
+	 */
607
+	public function set_external_url($external_url)
608
+	{
609
+		$this->set('EVT_external_URL', $external_url);
610
+	}
611
+
612
+
613
+	/**
614
+	 * @param $member_only
615
+	 * @throws EE_Error
616
+	 */
617
+	public function set_member_only($member_only)
618
+	{
619
+		$this->set('EVT_member_only', $member_only);
620
+	}
621
+
622
+
623
+	/**
624
+	 * @param $event_phone
625
+	 * @throws EE_Error
626
+	 */
627
+	public function set_event_phone($event_phone)
628
+	{
629
+		$this->set('EVT_phone', $event_phone);
630
+	}
631
+
632
+
633
+	/**
634
+	 * @param $modified
635
+	 * @throws EE_Error
636
+	 */
637
+	public function set_modified($modified)
638
+	{
639
+		$this->set('EVT_modified', $modified);
640
+	}
641
+
642
+
643
+	/**
644
+	 * @param $name
645
+	 * @throws EE_Error
646
+	 */
647
+	public function set_name($name)
648
+	{
649
+		$this->set('EVT_name', $name);
650
+	}
651
+
652
+
653
+	/**
654
+	 * @param $order
655
+	 * @throws EE_Error
656
+	 */
657
+	public function set_order($order)
658
+	{
659
+		$this->set('EVT_order', $order);
660
+	}
661
+
662
+
663
+	/**
664
+	 * @param $short_desc
665
+	 * @throws EE_Error
666
+	 */
667
+	public function set_short_description($short_desc)
668
+	{
669
+		$this->set('EVT_short_desc', $short_desc);
670
+	}
671
+
672
+
673
+	/**
674
+	 * @param $slug
675
+	 * @throws EE_Error
676
+	 */
677
+	public function set_slug($slug)
678
+	{
679
+		$this->set('EVT_slug', $slug);
680
+	}
681
+
682
+
683
+	/**
684
+	 * @param $timezone_string
685
+	 * @throws EE_Error
686
+	 */
687
+	public function set_timezone_string($timezone_string)
688
+	{
689
+		$this->set('EVT_timezone_string', $timezone_string);
690
+	}
691
+
692
+
693
+	/**
694
+	 * @param $visible_on
695
+	 * @throws EE_Error
696
+	 */
697
+	public function set_visible_on($visible_on)
698
+	{
699
+		$this->set('EVT_visible_on', $visible_on);
700
+	}
701
+
702
+
703
+	/**
704
+	 * @param $wp_user
705
+	 * @throws EE_Error
706
+	 */
707
+	public function set_wp_user($wp_user)
708
+	{
709
+		$this->set('EVT_wp_user', $wp_user);
710
+	}
711
+
712
+
713
+	/**
714
+	 * @param $default_registration_status
715
+	 * @throws EE_Error
716
+	 */
717
+	public function set_default_registration_status($default_registration_status)
718
+	{
719
+		$this->set('EVT_default_registration_status', $default_registration_status);
720
+	}
721
+
722
+
723
+	/**
724
+	 * @param $donations
725
+	 * @throws EE_Error
726
+	 */
727
+	public function set_donations($donations)
728
+	{
729
+		$this->set('EVT_donations', $donations);
730
+	}
731
+
732
+
733
+	/**
734
+	 * Adds a venue to this event
735
+	 *
736
+	 * @param int|EE_Venue /int $venue_id_or_obj
737
+	 * @return EE_Base_Class|EE_Venue
738
+	 * @throws EE_Error
739
+	 * @throws ReflectionException
740
+	 */
741
+	public function add_venue($venue_id_or_obj): EE_Venue
742
+	{
743
+		return $this->_add_relation_to($venue_id_or_obj, 'Venue');
744
+	}
745
+
746
+
747
+	/**
748
+	 * Removes a venue from the event
749
+	 *
750
+	 * @param EE_Venue /int $venue_id_or_obj
751
+	 * @return EE_Base_Class|EE_Venue
752
+	 * @throws EE_Error
753
+	 * @throws ReflectionException
754
+	 */
755
+	public function remove_venue($venue_id_or_obj): EE_Venue
756
+	{
757
+		$venue_id_or_obj = ! empty($venue_id_or_obj) ? $venue_id_or_obj : $this->venue();
758
+		return $this->_remove_relation_to($venue_id_or_obj, 'Venue');
759
+	}
760
+
761
+
762
+	/**
763
+	 * Gets the venue related to the event. May provide additional $query_params if desired
764
+	 *
765
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
766
+	 * @return int
767
+	 * @throws EE_Error
768
+	 * @throws ReflectionException
769
+	 */
770
+	public function venue_ID(array $query_params = array()): int
771
+	{
772
+		$venue = $this->get_first_related('Venue', $query_params);
773
+		return $venue instanceof EE_Venue ? $venue->ID() : 0;
774
+	}
775
+
776
+
777
+	/**
778
+	 * Gets the venue related to the event. May provide additional $query_params if desired
779
+	 *
780
+	 * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
781
+	 * @return EE_Base_Class|EE_Venue
782
+	 * @throws EE_Error
783
+	 * @throws ReflectionException
784
+	 */
785
+	public function venue(array $query_params = array())
786
+	{
787
+		return $this->get_first_related('Venue', $query_params);
788
+	}
789
+
790
+
791
+	/**
792
+	 * @param array $query_params
793
+	 * @return EE_Base_Class[]|EE_Venue[]
794
+	 * @throws EE_Error
795
+	 * @throws ReflectionException
796
+	 * @deprecated $VID:$
797
+	 */
798
+	public function venues(array $query_params = array()): array
799
+	{
800
+		return [$this->venue($query_params)];
801
+	}
802
+
803
+
804
+	/**
805
+	 * check if event id is present and if event is published
806
+	 *
807
+	 * @access public
808
+	 * @return boolean true yes, false no
809
+	 * @throws EE_Error
810
+	 * @throws ReflectionException
811
+	 */
812
+	private function _has_ID_and_is_published()
813
+	{
814
+		// first check if event id is present and not NULL,
815
+		// then check if this event is published (or any of the equivalent "published" statuses)
816
+		return
817
+			$this->ID() && $this->ID() !== null
818
+			&& (
819
+				$this->status() === 'publish'
820
+				|| $this->status() === EEM_Event::sold_out
821
+				|| $this->status() === EEM_Event::postponed
822
+				|| $this->status() === EEM_Event::cancelled
823
+			);
824
+	}
825
+
826
+
827
+	/**
828
+	 * This simply compares the internal dates with NOW and determines if the event is upcoming or not.
829
+	 *
830
+	 * @access public
831
+	 * @return boolean true yes, false no
832
+	 * @throws EE_Error
833
+	 * @throws ReflectionException
834
+	 */
835
+	public function is_upcoming()
836
+	{
837
+		// check if event id is present and if this event is published
838
+		if ($this->is_inactive()) {
839
+			return false;
840
+		}
841
+		// set initial value
842
+		$upcoming = false;
843
+		// next let's get all datetimes and loop through them
844
+		$datetimes = $this->datetimes_in_chronological_order();
845
+		foreach ($datetimes as $datetime) {
846
+			if ($datetime instanceof EE_Datetime) {
847
+				// if this dtt is expired then we continue cause one of the other datetimes might be upcoming.
848
+				if ($datetime->is_expired()) {
849
+					continue;
850
+				}
851
+				// if this dtt is active then we return false.
852
+				if ($datetime->is_active()) {
853
+					return false;
854
+				}
855
+				// otherwise let's check upcoming status
856
+				$upcoming = $datetime->is_upcoming();
857
+			}
858
+		}
859
+		return $upcoming;
860
+	}
861
+
862
+
863
+	/**
864
+	 * @return bool
865
+	 * @throws EE_Error
866
+	 * @throws ReflectionException
867
+	 */
868
+	public function is_active()
869
+	{
870
+		// check if event id is present and if this event is published
871
+		if ($this->is_inactive()) {
872
+			return false;
873
+		}
874
+		// set initial value
875
+		$active = false;
876
+		// next let's get all datetimes and loop through them
877
+		$datetimes = $this->datetimes_in_chronological_order();
878
+		foreach ($datetimes as $datetime) {
879
+			if ($datetime instanceof EE_Datetime) {
880
+				// if this dtt is expired then we continue cause one of the other datetimes might be active.
881
+				if ($datetime->is_expired()) {
882
+					continue;
883
+				}
884
+				// if this dtt is upcoming then we return false.
885
+				if ($datetime->is_upcoming()) {
886
+					return false;
887
+				}
888
+				// otherwise let's check active status
889
+				$active = $datetime->is_active();
890
+			}
891
+		}
892
+		return $active;
893
+	}
894
+
895
+
896
+	/**
897
+	 * @return bool
898
+	 * @throws EE_Error
899
+	 * @throws ReflectionException
900
+	 */
901
+	public function is_expired()
902
+	{
903
+		// check if event id is present and if this event is published
904
+		if ($this->is_inactive()) {
905
+			return false;
906
+		}
907
+		// set initial value
908
+		$expired = false;
909
+		// first let's get all datetimes and loop through them
910
+		$datetimes = $this->datetimes_in_chronological_order();
911
+		foreach ($datetimes as $datetime) {
912
+			if ($datetime instanceof EE_Datetime) {
913
+				// if this dtt is upcoming or active then we return false.
914
+				if ($datetime->is_upcoming() || $datetime->is_active()) {
915
+					return false;
916
+				}
917
+				// otherwise let's check active status
918
+				$expired = $datetime->is_expired();
919
+			}
920
+		}
921
+		return $expired;
922
+	}
923
+
924
+
925
+	/**
926
+	 * @return bool
927
+	 * @throws EE_Error
928
+	 */
929
+	public function is_inactive()
930
+	{
931
+		// check if event id is present and if this event is published
932
+		if ($this->_has_ID_and_is_published()) {
933
+			return false;
934
+		}
935
+		return true;
936
+	}
937
+
938
+
939
+	/**
940
+	 * calculate spaces remaining based on "saleable" tickets
941
+	 *
942
+	 * @param array $tickets
943
+	 * @param bool  $filtered
944
+	 * @return int|float
945
+	 * @throws EE_Error
946
+	 * @throws DomainException
947
+	 * @throws UnexpectedEntityException
948
+	 */
949
+	public function spaces_remaining($tickets = array(), $filtered = true)
950
+	{
951
+		$this->getAvailableSpacesCalculator()->setActiveTickets($tickets);
952
+		$spaces_remaining = $this->getAvailableSpacesCalculator()->spacesRemaining();
953
+		return $filtered
954
+			? apply_filters(
955
+				'FHEE_EE_Event__spaces_remaining',
956
+				$spaces_remaining,
957
+				$this,
958
+				$tickets
959
+			)
960
+			: $spaces_remaining;
961
+	}
962
+
963
+
964
+	/**
965
+	 *    perform_sold_out_status_check
966
+	 *    checks all of this events's datetime  reg_limit - sold values to determine if ANY datetimes have spaces
967
+	 *    available... if NOT, then the event status will get toggled to 'sold_out'
968
+	 *
969
+	 * @return bool    return the ACTUAL sold out state.
970
+	 * @throws EE_Error
971
+	 * @throws DomainException
972
+	 * @throws UnexpectedEntityException
973
+	 * @throws ReflectionException
974
+	 */
975
+	public function perform_sold_out_status_check()
976
+	{
977
+		// get all tickets
978
+		$tickets = $this->tickets(
979
+			array(
980
+				'default_where_conditions' => 'none',
981
+				'order_by' => array('TKT_qty' => 'ASC'),
982
+			)
983
+		);
984
+		$all_expired = true;
985
+		foreach ($tickets as $ticket) {
986
+			if (! $ticket->is_expired()) {
987
+				$all_expired = false;
988
+				break;
989
+			}
990
+		}
991
+		// if all the tickets are just expired, then don't update the event status to sold out
992
+		if ($all_expired) {
993
+			return true;
994
+		}
995
+		$spaces_remaining = $this->spaces_remaining($tickets);
996
+		if ($spaces_remaining < 1) {
997
+			if ($this->status() !== EEM_Event::post_status_private) {
998
+				$this->set_status(EEM_Event::sold_out);
999
+				$this->save();
1000
+			}
1001
+			$sold_out = true;
1002
+		} else {
1003
+			$sold_out = false;
1004
+			// was event previously marked as sold out ?
1005
+			if ($this->status() === EEM_Event::sold_out) {
1006
+				// revert status to previous value, if it was set
1007
+				$previous_event_status = $this->get_post_meta('_previous_event_status', true);
1008
+				if ($previous_event_status) {
1009
+					$this->set_status($previous_event_status);
1010
+					$this->save();
1011
+				}
1012
+			}
1013
+		}
1014
+		do_action('AHEE__EE_Event__perform_sold_out_status_check__end', $this, $sold_out, $spaces_remaining, $tickets);
1015
+		return $sold_out;
1016
+	}
1017
+
1018
+
1019
+	/**
1020
+	 * This returns the total remaining spaces for sale on this event.
1021
+	 *
1022
+	 * @uses EE_Event::total_available_spaces()
1023
+	 * @return float|int
1024
+	 * @throws EE_Error
1025
+	 * @throws DomainException
1026
+	 * @throws UnexpectedEntityException
1027
+	 */
1028
+	public function spaces_remaining_for_sale()
1029
+	{
1030
+		return $this->total_available_spaces(true);
1031
+	}
1032
+
1033
+
1034
+	/**
1035
+	 * This returns the total spaces available for an event
1036
+	 * while considering all the qtys on the tickets and the reg limits
1037
+	 * on the datetimes attached to this event.
1038
+	 *
1039
+	 * @param   bool $consider_sold Whether to consider any tickets that have already sold in our calculation.
1040
+	 *                              If this is false, then we return the most tickets that could ever be sold
1041
+	 *                              for this event with the datetime and tickets setup on the event under optimal
1042
+	 *                              selling conditions.  Otherwise we return a live calculation of spaces available
1043
+	 *                              based on tickets sold.  Depending on setup and stage of sales, this
1044
+	 *                              may appear to equal remaining tickets.  However, the more tickets are
1045
+	 *                              sold out, the more accurate the "live" total is.
1046
+	 * @return float|int
1047
+	 * @throws EE_Error
1048
+	 * @throws DomainException
1049
+	 * @throws UnexpectedEntityException
1050
+	 */
1051
+	public function total_available_spaces($consider_sold = false)
1052
+	{
1053
+		$spaces_available = $consider_sold
1054
+			? $this->getAvailableSpacesCalculator()->spacesRemaining()
1055
+			: $this->getAvailableSpacesCalculator()->totalSpacesAvailable();
1056
+		return apply_filters(
1057
+			'FHEE_EE_Event__total_available_spaces__spaces_available',
1058
+			$spaces_available,
1059
+			$this,
1060
+			$this->getAvailableSpacesCalculator()->getDatetimes(),
1061
+			$this->getAvailableSpacesCalculator()->getActiveTickets()
1062
+		);
1063
+	}
1064
+
1065
+
1066
+	/**
1067
+	 * Checks if the event is set to sold out
1068
+	 *
1069
+	 * @param  bool $actual whether or not to perform calculations to not only figure the
1070
+	 *                      actual status but also to flip the status if necessary to sold
1071
+	 *                      out If false, we just check the existing status of the event
1072
+	 * @return boolean
1073
+	 * @throws EE_Error
1074
+	 */
1075
+	public function is_sold_out($actual = false)
1076
+	{
1077
+		if (! $actual) {
1078
+			return $this->status() === EEM_Event::sold_out;
1079
+		}
1080
+		return $this->perform_sold_out_status_check();
1081
+	}
1082
+
1083
+
1084
+	/**
1085
+	 * Checks if the event is marked as postponed
1086
+	 *
1087
+	 * @return boolean
1088
+	 */
1089
+	public function is_postponed()
1090
+	{
1091
+		return $this->status() === EEM_Event::postponed;
1092
+	}
1093
+
1094
+
1095
+	/**
1096
+	 * Checks if the event is marked as cancelled
1097
+	 *
1098
+	 * @return boolean
1099
+	 */
1100
+	public function is_cancelled()
1101
+	{
1102
+		return $this->status() === EEM_Event::cancelled;
1103
+	}
1104
+
1105
+
1106
+	/**
1107
+	 * Get the logical active status in a hierarchical order for all the datetimes.  Note
1108
+	 * Basically, we order the datetimes by EVT_start_date.  Then first test on whether the event is published.  If its
1109
+	 * NOT published then we test for whether its expired or not.  IF it IS published then we test first on whether an
1110
+	 * event has any active dates.  If no active dates then we check for any upcoming dates.  If no upcoming dates then
1111
+	 * the event is considered expired.
1112
+	 * NOTE: this method does NOT calculate whether the datetimes are sold out when event is published.  Sold Out is a
1113
+	 * status set on the EVENT when it is not published and thus is done
1114
+	 *
1115
+	 * @param bool $reset
1116
+	 * @return bool | string - based on EE_Datetime active constants or FALSE if error.
1117
+	 * @throws EE_Error
1118
+	 * @throws ReflectionException
1119
+	 */
1120
+	public function get_active_status($reset = false)
1121
+	{
1122
+		// if the active status has already been set, then just use that value (unless we are resetting it)
1123
+		if (! empty($this->_active_status) && ! $reset) {
1124
+			return $this->_active_status;
1125
+		}
1126
+		// first check if event id is present on this object
1127
+		if (! $this->ID()) {
1128
+			return false;
1129
+		}
1130
+		$where_params_for_event = array(array('EVT_ID' => $this->ID()));
1131
+		// if event is published:
1132
+		if ($this->status() === EEM_Event::post_status_publish || $this->status() === EEM_Event::post_status_private) {
1133
+			// active?
1134
+			if (
1135
+				EEM_Datetime::instance()->get_datetime_count_for_status(
1136
+					EE_Datetime::active,
1137
+					$where_params_for_event
1138
+				) > 0
1139
+			) {
1140
+				$this->_active_status = EE_Datetime::active;
1141
+			} else {
1142
+				// upcoming?
1143
+				if (
1144
+					EEM_Datetime::instance()->get_datetime_count_for_status(
1145
+						EE_Datetime::upcoming,
1146
+						$where_params_for_event
1147
+					) > 0
1148
+				) {
1149
+					$this->_active_status = EE_Datetime::upcoming;
1150
+				} else {
1151
+					// expired?
1152
+					if (
1153
+						EEM_Datetime::instance()->get_datetime_count_for_status(
1154
+							EE_Datetime::expired,
1155
+							$where_params_for_event
1156
+						) > 0
1157
+					) {
1158
+						$this->_active_status = EE_Datetime::expired;
1159
+					} else {
1160
+						// it would be odd if things make it this far because it basically means there are no datetime's
1161
+						// attached to the event.  So in this case it will just be considered inactive.
1162
+						$this->_active_status = EE_Datetime::inactive;
1163
+					}
1164
+				}
1165
+			}
1166
+		} else {
1167
+			// the event is not published, so let's just set it's active status according to its' post status
1168
+			switch ($this->status()) {
1169
+				case EEM_Event::sold_out:
1170
+					$this->_active_status = EE_Datetime::sold_out;
1171
+					break;
1172
+				case EEM_Event::cancelled:
1173
+					$this->_active_status = EE_Datetime::cancelled;
1174
+					break;
1175
+				case EEM_Event::postponed:
1176
+					$this->_active_status = EE_Datetime::postponed;
1177
+					break;
1178
+				default:
1179
+					$this->_active_status = EE_Datetime::inactive;
1180
+			}
1181
+		}
1182
+		return $this->_active_status;
1183
+	}
1184
+
1185
+
1186
+	/**
1187
+	 *    pretty_active_status
1188
+	 *
1189
+	 * @access public
1190
+	 * @param boolean $echo whether to return (FALSE), or echo out the result (TRUE)
1191
+	 * @return mixed void|string
1192
+	 * @throws EE_Error
1193
+	 * @throws ReflectionException
1194
+	 */
1195
+	public function pretty_active_status($echo = true)
1196
+	{
1197
+		$active_status = $this->get_active_status();
1198
+		$status = '<span class="ee-status ee-status-bg--' . esc_attr($active_status) . ' event-active-status-' .
1199
+				  esc_attr($active_status) . '">'
1200
+				  . EEH_Template::pretty_status($active_status, false, 'sentence')
1201
+				  . '</span>';
1202
+		if ($echo) {
1203
+			echo wp_kses($status, AllowedTags::getAllowedTags());
1204
+			return '';
1205
+		}
1206
+		return $status; // already escaped
1207
+	}
1208
+
1209
+
1210
+	/**
1211
+	 * @return bool|int
1212
+	 * @throws EE_Error
1213
+	 * @throws ReflectionException
1214
+	 */
1215
+	public function get_number_of_tickets_sold()
1216
+	{
1217
+		$tkt_sold = 0;
1218
+		if (! $this->ID()) {
1219
+			return 0;
1220
+		}
1221
+		$datetimes = $this->datetimes();
1222
+		foreach ($datetimes as $datetime) {
1223
+			if ($datetime instanceof EE_Datetime) {
1224
+				$tkt_sold += $datetime->sold();
1225
+			}
1226
+		}
1227
+		return $tkt_sold;
1228
+	}
1229
+
1230
+
1231
+	/**
1232
+	 * This just returns a count of all the registrations for this event
1233
+	 *
1234
+	 * @access  public
1235
+	 * @return int
1236
+	 * @throws EE_Error
1237
+	 */
1238
+	public function get_count_of_all_registrations()
1239
+	{
1240
+		return EEM_Event::instance()->count_related($this, 'Registration');
1241
+	}
1242
+
1243
+
1244
+	/**
1245
+	 * This returns the ticket with the earliest start time that is
1246
+	 * available for this event (across all datetimes attached to the event)
1247
+	 *
1248
+	 * @return EE_Base_Class|EE_Ticket|null
1249
+	 * @throws EE_Error
1250
+	 * @throws ReflectionException
1251
+	 */
1252
+	public function get_ticket_with_earliest_start_time()
1253
+	{
1254
+		$where['Datetime.EVT_ID'] = $this->ID();
1255
+		$query_params = array($where, 'order_by' => array('TKT_start_date' => 'ASC'));
1256
+		return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1257
+	}
1258
+
1259
+
1260
+	/**
1261
+	 * This returns the ticket with the latest end time that is available
1262
+	 * for this event (across all datetimes attached to the event)
1263
+	 *
1264
+	 * @return EE_Base_Class|EE_Ticket|null
1265
+	 * @throws EE_Error
1266
+	 * @throws ReflectionException
1267
+	 */
1268
+	public function get_ticket_with_latest_end_time()
1269
+	{
1270
+		$where['Datetime.EVT_ID'] = $this->ID();
1271
+		$query_params = array($where, 'order_by' => array('TKT_end_date' => 'DESC'));
1272
+		return EE_Registry::instance()->load_model('Ticket')->get_one($query_params);
1273
+	}
1274
+
1275
+
1276
+	/**
1277
+	 * This returns the number of different ticket types currently on sale for this event.
1278
+	 *
1279
+	 * @return int
1280
+	 * @throws EE_Error
1281
+	 * @throws ReflectionException
1282
+	 */
1283
+	public function countTicketsOnSale()
1284
+	{
1285
+		$where = array(
1286
+			'Datetime.EVT_ID' => $this->ID(),
1287
+			'TKT_start_date'  => array('<', time()),
1288
+			'TKT_end_date'    => array('>', time()),
1289
+		);
1290
+		return EEM_Ticket::instance()->count(array($where));
1291
+	}
1292
+
1293
+
1294
+	/**
1295
+	 * This returns whether there are any tickets on sale for this event.
1296
+	 *
1297
+	 * @return bool true = YES tickets on sale.
1298
+	 * @throws EE_Error
1299
+	 */
1300
+	public function tickets_on_sale()
1301
+	{
1302
+		return $this->countTicketsOnSale() > 0;
1303
+	}
1304
+
1305
+
1306
+	/**
1307
+	 * Gets the URL for viewing this event on the front-end. Overrides parent
1308
+	 * to check for an external URL first
1309
+	 *
1310
+	 * @return string
1311
+	 * @throws EE_Error
1312
+	 */
1313
+	public function get_permalink()
1314
+	{
1315
+		if ($this->external_url()) {
1316
+			return $this->external_url();
1317
+		}
1318
+		return parent::get_permalink();
1319
+	}
1320
+
1321
+
1322
+	/**
1323
+	 * Gets the first term for 'espresso_event_categories' we can find
1324
+	 *
1325
+	 * @param array $query_params @see
1326
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1327
+	 * @return EE_Base_Class|EE_Term|null
1328
+	 * @throws EE_Error
1329
+	 * @throws ReflectionException
1330
+	 */
1331
+	public function first_event_category($query_params = array())
1332
+	{
1333
+		$query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1334
+		$query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1335
+		return EEM_Term::instance()->get_one($query_params);
1336
+	}
1337
+
1338
+
1339
+	/**
1340
+	 * Gets all terms for 'espresso_event_categories' we can find
1341
+	 *
1342
+	 * @param array $query_params
1343
+	 * @return EE_Base_Class[]|EE_Term[]
1344
+	 * @throws EE_Error
1345
+	 * @throws ReflectionException
1346
+	 */
1347
+	public function get_all_event_categories($query_params = array())
1348
+	{
1349
+		$query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1350
+		$query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID();
1351
+		return EEM_Term::instance()->get_all($query_params);
1352
+	}
1353
+
1354
+
1355
+	/**
1356
+	 * Adds a question group to this event
1357
+	 *
1358
+	 * @param EE_Question_Group|int $question_group_id_or_obj
1359
+	 * @param bool $for_primary if true, the question group will be added for the primary
1360
+	 *                                           registrant, if false will be added for others. default: false
1361
+	 * @return EE_Base_Class|EE_Question_Group
1362
+	 * @throws EE_Error
1363
+	 * @throws InvalidArgumentException
1364
+	 * @throws InvalidDataTypeException
1365
+	 * @throws InvalidInterfaceException
1366
+	 * @throws ReflectionException
1367
+	 */
1368
+	public function add_question_group($question_group_id_or_obj, $for_primary = false)
1369
+	{
1370
+		// If the row already exists, it will be updated. If it doesn't, it will be inserted.
1371
+		// That's in EE_HABTM_Relation::add_relation_to().
1372
+		return $this->_add_relation_to(
1373
+			$question_group_id_or_obj,
1374
+			'Question_Group',
1375
+			[
1376
+				EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary) => true
1377
+			]
1378
+		);
1379
+	}
1380
+
1381
+
1382
+	/**
1383
+	 * Removes a question group from the event
1384
+	 *
1385
+	 * @param EE_Question_Group|int $question_group_id_or_obj
1386
+	 * @param bool $for_primary if true, the question group will be removed from the primary
1387
+	 *                                           registrant, if false will be removed from others. default: false
1388
+	 * @return EE_Base_Class|EE_Question_Group
1389
+	 * @throws EE_Error
1390
+	 * @throws InvalidArgumentException
1391
+	 * @throws ReflectionException
1392
+	 * @throws InvalidDataTypeException
1393
+	 * @throws InvalidInterfaceException
1394
+	 */
1395
+	public function remove_question_group($question_group_id_or_obj, $for_primary = false)
1396
+	{
1397
+		// If the question group is used for the other type (primary or additional)
1398
+		// then just update it. If not, delete it outright.
1399
+		$existing_relation = $this->get_first_related(
1400
+			'Event_Question_Group',
1401
+			[
1402
+				[
1403
+					'QSG_ID' => EEM_Question_Group::instance()->ensure_is_ID($question_group_id_or_obj)
1404
+				]
1405
+			]
1406
+		);
1407
+		$field_to_update = EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary);
1408
+		$other_field = EEM_Event_Question_Group::instance()->fieldNameForContext(! $for_primary);
1409
+		if ($existing_relation->get($other_field) === false) {
1410
+			// Delete it. It's now no longer for primary or additional question groups.
1411
+			return $this->_remove_relation_to($question_group_id_or_obj, 'Question_Group');
1412
+		}
1413
+		// Just update it. They'll still use this question group for the other category
1414
+		$existing_relation->save(
1415
+			[
1416
+				$field_to_update => false
1417
+			]
1418
+		);
1419
+	}
1420
+
1421
+
1422
+	/**
1423
+	 * Gets all the question groups, ordering them by QSG_order ascending
1424
+	 *
1425
+	 * @param array $query_params @see
1426
+	 *                            https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1427
+	 * @return EE_Base_Class[]|EE_Question_Group[]
1428
+	 * @throws EE_Error
1429
+	 * @throws ReflectionException
1430
+	 */
1431
+	public function question_groups($query_params = array())
1432
+	{
1433
+		$query_params = ! empty($query_params) ? $query_params : array('order_by' => array('QSG_order' => 'ASC'));
1434
+		return $this->get_many_related('Question_Group', $query_params);
1435
+	}
1436
+
1437
+
1438
+	/**
1439
+	 * Implementation for EEI_Has_Icon interface method.
1440
+	 *
1441
+	 * @see EEI_Visual_Representation for comments
1442
+	 * @return string
1443
+	 */
1444
+	public function get_icon()
1445
+	{
1446
+		return '<span class="dashicons dashicons-flag"></span>';
1447
+	}
1448
+
1449
+
1450
+	/**
1451
+	 * Implementation for EEI_Admin_Links interface method.
1452
+	 *
1453
+	 * @see EEI_Admin_Links for comments
1454
+	 * @return string
1455
+	 * @throws EE_Error
1456
+	 */
1457
+	public function get_admin_details_link()
1458
+	{
1459
+		return $this->get_admin_edit_link();
1460
+	}
1461
+
1462
+
1463
+	/**
1464
+	 * Implementation for EEI_Admin_Links interface method.
1465
+	 *
1466
+	 * @return string
1467
+	 * @throws EE_Error*@throws ReflectionException
1468
+	 * @see EEI_Admin_Links for comments
1469
+	 */
1470
+	public function get_admin_edit_link()
1471
+	{
1472
+		return EEH_URL::add_query_args_and_nonce(
1473
+			array(
1474
+				'page'   => 'espresso_events',
1475
+				'action' => 'edit',
1476
+				'post'   => $this->ID(),
1477
+			),
1478
+			admin_url('admin.php')
1479
+		);
1480
+	}
1481
+
1482
+
1483
+	/**
1484
+	 * Implementation for EEI_Admin_Links interface method.
1485
+	 *
1486
+	 * @see EEI_Admin_Links for comments
1487
+	 * @return string
1488
+	 */
1489
+	public function get_admin_settings_link()
1490
+	{
1491
+		return EEH_URL::add_query_args_and_nonce(
1492
+			array(
1493
+				'page'   => 'espresso_events',
1494
+				'action' => 'default_event_settings',
1495
+			),
1496
+			admin_url('admin.php')
1497
+		);
1498
+	}
1499
+
1500
+
1501
+	/**
1502
+	 * Implementation for EEI_Admin_Links interface method.
1503
+	 *
1504
+	 * @see EEI_Admin_Links for comments
1505
+	 * @return string
1506
+	 */
1507
+	public function get_admin_overview_link()
1508
+	{
1509
+		return EEH_URL::add_query_args_and_nonce(
1510
+			array(
1511
+				'page'   => 'espresso_events',
1512
+				'action' => 'default',
1513
+			),
1514
+			admin_url('admin.php')
1515
+		);
1516
+	}
1517
+
1518
+
1519
+	/**
1520
+	 * @return string|null
1521
+	 * @throws EE_Error
1522
+	 * @throws ReflectionException
1523
+	 */
1524
+	public function registrationFormUuid(): ?string
1525
+	{
1526
+		return $this->get('FSC_UUID');
1527
+	}
1528
+
1529
+
1530
+	/**
1531
+	 * Gets all the form sections for this event
1532
+	 *
1533
+	 * @return EE_Base_Class[]|EE_Form_Section[]
1534
+	 * @throws EE_Error
1535
+	 * @throws ReflectionException
1536
+	 */
1537
+	public function registrationForm()
1538
+	{
1539
+		$FSC_UUID = $this->registrationFormUuid();
1540
+
1541
+		if (empty($FSC_UUID)) {
1542
+			return [];
1543
+		}
1544
+
1545
+		return EEM_Form_Section::instance()->get_all([
1546
+			[
1547
+				'OR' => [
1548
+					'FSC_UUID'      => $FSC_UUID, // top level form
1549
+					'FSC_belongsTo' => $FSC_UUID, // child form sections
1550
+				]
1551
+				],
1552
+			'order_by' => ['FSC_order' => 'ASC'],
1553
+		]);
1554
+	}
1555
+
1556
+
1557
+	/**
1558
+	 * @param string $UUID
1559
+	 * @throws EE_Error
1560
+	 */
1561
+	public function setRegistrationFormUuid(string $UUID): void
1562
+	{
1563
+		if (! Cuid::isCuid($UUID)) {
1564
+			throw new InvalidArgumentException(
1565
+				sprintf(
1566
+				/* translators: 1: UUID value, 2: UUID generator function. */
1567
+					esc_html__(
1568
+						'The supplied UUID "%1$s" is invalid or missing. Please use %2$s to generate a valid one.',
1569
+						'event_espresso'
1570
+					),
1571
+					$UUID,
1572
+					'`Cuid::cuid()`'
1573
+				)
1574
+			);
1575
+		}
1576
+		$this->set('FSC_UUID', $UUID);
1577
+	}
1578 1578
 }
Please login to merge, or discard this patch.
admin/extend/registrations/EE_Event_Registrations_List_Table.class.php 2 patches
Indentation   +670 added lines, -670 removed lines patch added patch discarded remove patch
@@ -15,718 +15,718 @@
 block discarded – undo
15 15
  */
16 16
 class EE_Event_Registrations_List_Table extends EE_Admin_List_Table
17 17
 {
18
-    /**
19
-     * @var RequestInterface
20
-     */
21
-    protected $request;
22
-
23
-    /**
24
-     * @var Extend_Registrations_Admin_Page
25
-     */
26
-    protected $_admin_page;
27
-
28
-    /**
29
-     * The event ID if one is specified in the request
30
-     *
31
-     * @var int
32
-     */
33
-    protected $event_id = 0;
34
-
35
-    /**
36
-     * This property will hold the related Datetimes on an event IF the event id is included in the request.
37
-     *
38
-     * @var DatetimesForEventCheckIn
39
-     */
40
-    protected $datetimes_for_event = [];
41
-
42
-    /**
43
-     * The DTT_ID if the current view has a specified datetime.
44
-     *
45
-     * @var int
46
-     */
47
-    protected $datetime_id = 0;
48
-
49
-    /**
50
-     * @var EE_Datetime
51
-     */
52
-    protected $datetime;
53
-
54
-    /**
55
-     * @var EE_Event
56
-     */
57
-    protected $event;
58
-
59
-    /**
60
-     * @var DatetimesForEventCheckIn
61
-     */
62
-    protected $datetimes_for_current_row;
63
-
64
-    /**
65
-     * @var bool
66
-     */
67
-    protected $hide_expired;
68
-
69
-    /**
70
-     * @var bool
71
-     */
72
-    protected $hide_upcoming;
73
-
74
-
75
-    /**
76
-     * EE_Event_Registrations_List_Table constructor.
77
-     *
78
-     * @param Registrations_Admin_Page $admin_page
79
-     * @throws EE_Error
80
-     * @throws ReflectionException
81
-     */
82
-    public function __construct($admin_page)
83
-    {
84
-        $this->request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
85
-        $this->resolveRequestVars();
86
-        parent::__construct($admin_page);
87
-    }
88
-
89
-
90
-    /**
91
-     * @throws EE_Error
92
-     * @throws ReflectionException
93
-     * @since $VID:$
94
-     */
95
-    private function resolveRequestVars()
96
-    {
97
-        $this->event_id = $this->request->getRequestParam('event_id', 0, 'int');
98
-        $this->datetimes_for_event = DatetimesForEventCheckIn::fromEventID($this->event_id);
99
-        // if we're filtering for a specific event and it only has one datetime, then grab its ID
100
-        $datetime          = $this->datetimes_for_event->getOneDatetimeForEvent();
101
-        $this->datetime_id = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
102
-        // else check the request, but use the above as the default (and hope they match if BOTH exist, LOLZ)
103
-        $this->datetime_id = $this->request->getRequestParam(
104
-            'DTT_ID',
105
-            $this->datetime_id,
106
-            'int'
107
-        );
108
-    }
109
-
110
-
111
-    /**
112
-     * @throws EE_Error
113
-     */
114
-    protected function _setup_data()
115
-    {
116
-        $this->_data = $this->_view !== 'trash'
117
-            ? $this->_admin_page->get_event_attendees($this->_per_page)
118
-            : $this->_admin_page->get_event_attendees($this->_per_page, false, true);
119
-
120
-        $this->_all_data_count = $this->_view !== 'trash'
121
-            ? $this->_admin_page->get_event_attendees($this->_per_page, true)
122
-            : $this->_admin_page->get_event_attendees($this->_per_page, true, true);
123
-    }
124
-
125
-
126
-    protected function _set_properties()
127
-    {
128
-        $this->_wp_list_args = [
129
-            'singular' => esc_html__('registrant', 'event_espresso'),
130
-            'plural'   => esc_html__('registrants', 'event_espresso'),
131
-            'ajax'     => true,
132
-            'screen'   => $this->_admin_page->get_current_screen()->id,
133
-        ];
134
-
135
-        $this->_columns      = [
136
-            'cb' => '<input type="checkbox" />', // Render a checkbox instead of text
137
-            '_REG_att_checked_in' => esc_html__('Check In', 'event_espresso'),
138
-            'ATT_name'            => esc_html__('Registrant', 'event_espresso'),
139
-            'ATT_email'           => esc_html__('Email Address', 'event_espresso'),
140
-            'Event'               => esc_html__('Event', 'event_espresso'),
141
-            'PRC_name'            => esc_html__('TKT Option', 'event_espresso'),
142
-            '_REG_final_price'    => esc_html__('Price', 'event_espresso'),
143
-            'TXN_paid'            => esc_html__('Paid', 'event_espresso'),
144
-            'TXN_total'           => esc_html__('Total', 'event_espresso'),
145
-        ];
146
-        $this->_primary_column = '_REG_att_checked_in';
147
-
148
-        // Add/remove columns when an event has been selected
149
-        if ($this->event_id) {
150
-            // Render a checkbox column
151
-            $this->_columns['cb'] = '<input type="checkbox" />';
152
-            $this->_has_checkbox_column = true;
153
-            // Remove the 'Event' column
154
-            unset($this->_columns['Event']);
155
-            $this->setBottomButtons();
156
-        }
157
-
158
-        $this->_sortable_columns = [
159
-            /**
160
-             * Allows users to change the default sort if they wish.
161
-             * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name.
162
-             *
163
-             * Note: usual naming conventions for filters aren't followed here so that just one filter can be used to
164
-             * change the sorts on any list table involving registration contacts.  If you want to only change the filter
165
-             * for a specific list table you can use the provided reference to this object instance.
166
-             */
167
-            'ATT_name' => [
168
-                'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
169
-                true,
170
-                $this,
171
-            ]
172
-                ? ['ATT_lname' => true]
173
-                : ['ATT_fname' => true],
174
-            'Event'    => ['Event.EVT_name' => false],
175
-        ];
176
-
177
-        $this->_hidden_columns = [];
178
-    }
179
-
180
-
181
-    private function setBottomButtons()
182
-    {
183
-        if (
184
-            ! EE_Registry::instance()->CAP->current_user_can(
185
-                'ee_read_registrations',
186
-                'espresso_registrations_registrations_reports',
187
-                $this->event_id
188
-            )
189
-        ) {
190
-            return;
191
-        }
192
-
193
-        $return_url = $this->getReturnUrl();
194
-        $this->_bottom_buttons = [
195
-            'report' => [
196
-                'route'         => 'registrations_report',
197
-                'extra_request' =>
198
-                    [
199
-                        'EVT_ID'     => $this->event_id,
200
-                        'return_url' => $return_url,
201
-                    ],
202
-            ],
203
-        ];
204
-
205
-        $request_params = $this->request->requestParams();
206
-
207
-        $this->_bottom_buttons['report_filtered'] = [
208
-            'route'         => 'registrations_checkin_report',
209
-            'extra_request' => [
210
-                'use_filters' => true,
211
-                'filters'     => array_merge(
212
-                    [
213
-                        'EVT_ID' => $this->event_id,
214
-                    ],
215
-                    array_diff_key(
216
-                        $request_params,
217
-                        array_flip(
218
-                            [
219
-                                'page',
220
-                                'action',
221
-                                'default_nonce',
222
-                            ]
223
-                        )
224
-                    )
225
-                ),
226
-                'return_url'  => $return_url,
227
-            ],
228
-        ];
229
-    }
230
-
231
-
232
-    /**
233
-     * @param EE_Registration $item
234
-     * @return string
235
-     */
236
-    protected function _get_row_class($item): string
237
-    {
238
-        $class = parent::_get_row_class($item);
239
-        if ($this->_has_checkbox_column) {
240
-            $class .= ' has-checkbox-column';
241
-        }
242
-        return $class;
243
-    }
244
-
245
-
246
-    /**
247
-     * @return array
248
-     * @throws EE_Error
249
-     * @throws ReflectionException
250
-     */
251
-    protected function _get_table_filters(): array
252
-    {
253
-        $filters = [];
254
-        $this->hide_expired = $this->request->getRequestParam('hide_expired', false, 'bool');
255
-        $this->hide_upcoming = $this->request->getRequestParam('hide_upcoming', false, 'bool');
256
-        $hide_expired_checked = $this->hide_expired ? 'checked' : '';
257
-        $hide_upcoming_checked = $this->hide_upcoming ? 'checked' : '';
258
-        // get datetimes for ALL active events (note possible capability restrictions)
259
-        $events   = $this->datetimes_for_event->getAllDatetimesForAllEvents();
260
-        $event_options[] = [
261
-            'id'   => 0,
262
-            'text' => esc_html__(' - select an event - ', 'event_espresso'),
263
-        ];
264
-        /** @var EE_Event $event */
265
-        foreach ($events as $event) {
266
-            // any registrations for this event?
267
-            if (! $event instanceof EE_Event/* || ! $event->get_count_of_all_registrations()*/) {
268
-                continue;
269
-            }
270
-            $expired_class = $event->is_expired() ? 'ee-expired-event' : '';
271
-            $upcoming_class  = $event->is_upcoming() ? ' ee-upcoming-event' : '';
272
-
273
-            $event_options[] = [
274
-                'id'    => $event->ID(),
275
-                'text'  => apply_filters(
276
-                    'FHEE__EE_Event_Registrations___get_table_filters__event_name',
277
-                    $event->name(),
278
-                    $event
279
-                ),
280
-                'class' => $expired_class . $upcoming_class,
281
-            ];
282
-            if ($event->ID() === $this->event_id) {
283
-                $this->hide_expired = $expired_class === '' ? $this->hide_expired : false;
284
-                $hide_expired_checked  = $expired_class === '' ? $hide_expired_checked : '';
285
-                $this->hide_upcoming = $upcoming_class === '' ? $this->hide_upcoming : false;
286
-                $hide_upcoming_checked = $upcoming_class === '' ? $hide_upcoming_checked : '';
287
-            }
288
-        }
289
-
290
-        $select_class = $this->hide_expired ? 'ee-hide-expired-events' : '';
291
-        $select_class .= $this->hide_upcoming ? ' ee-hide-upcoming-events' : '';
292
-
293
-        $filters[] = '
18
+	/**
19
+	 * @var RequestInterface
20
+	 */
21
+	protected $request;
22
+
23
+	/**
24
+	 * @var Extend_Registrations_Admin_Page
25
+	 */
26
+	protected $_admin_page;
27
+
28
+	/**
29
+	 * The event ID if one is specified in the request
30
+	 *
31
+	 * @var int
32
+	 */
33
+	protected $event_id = 0;
34
+
35
+	/**
36
+	 * This property will hold the related Datetimes on an event IF the event id is included in the request.
37
+	 *
38
+	 * @var DatetimesForEventCheckIn
39
+	 */
40
+	protected $datetimes_for_event = [];
41
+
42
+	/**
43
+	 * The DTT_ID if the current view has a specified datetime.
44
+	 *
45
+	 * @var int
46
+	 */
47
+	protected $datetime_id = 0;
48
+
49
+	/**
50
+	 * @var EE_Datetime
51
+	 */
52
+	protected $datetime;
53
+
54
+	/**
55
+	 * @var EE_Event
56
+	 */
57
+	protected $event;
58
+
59
+	/**
60
+	 * @var DatetimesForEventCheckIn
61
+	 */
62
+	protected $datetimes_for_current_row;
63
+
64
+	/**
65
+	 * @var bool
66
+	 */
67
+	protected $hide_expired;
68
+
69
+	/**
70
+	 * @var bool
71
+	 */
72
+	protected $hide_upcoming;
73
+
74
+
75
+	/**
76
+	 * EE_Event_Registrations_List_Table constructor.
77
+	 *
78
+	 * @param Registrations_Admin_Page $admin_page
79
+	 * @throws EE_Error
80
+	 * @throws ReflectionException
81
+	 */
82
+	public function __construct($admin_page)
83
+	{
84
+		$this->request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
85
+		$this->resolveRequestVars();
86
+		parent::__construct($admin_page);
87
+	}
88
+
89
+
90
+	/**
91
+	 * @throws EE_Error
92
+	 * @throws ReflectionException
93
+	 * @since $VID:$
94
+	 */
95
+	private function resolveRequestVars()
96
+	{
97
+		$this->event_id = $this->request->getRequestParam('event_id', 0, 'int');
98
+		$this->datetimes_for_event = DatetimesForEventCheckIn::fromEventID($this->event_id);
99
+		// if we're filtering for a specific event and it only has one datetime, then grab its ID
100
+		$datetime          = $this->datetimes_for_event->getOneDatetimeForEvent();
101
+		$this->datetime_id = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
102
+		// else check the request, but use the above as the default (and hope they match if BOTH exist, LOLZ)
103
+		$this->datetime_id = $this->request->getRequestParam(
104
+			'DTT_ID',
105
+			$this->datetime_id,
106
+			'int'
107
+		);
108
+	}
109
+
110
+
111
+	/**
112
+	 * @throws EE_Error
113
+	 */
114
+	protected function _setup_data()
115
+	{
116
+		$this->_data = $this->_view !== 'trash'
117
+			? $this->_admin_page->get_event_attendees($this->_per_page)
118
+			: $this->_admin_page->get_event_attendees($this->_per_page, false, true);
119
+
120
+		$this->_all_data_count = $this->_view !== 'trash'
121
+			? $this->_admin_page->get_event_attendees($this->_per_page, true)
122
+			: $this->_admin_page->get_event_attendees($this->_per_page, true, true);
123
+	}
124
+
125
+
126
+	protected function _set_properties()
127
+	{
128
+		$this->_wp_list_args = [
129
+			'singular' => esc_html__('registrant', 'event_espresso'),
130
+			'plural'   => esc_html__('registrants', 'event_espresso'),
131
+			'ajax'     => true,
132
+			'screen'   => $this->_admin_page->get_current_screen()->id,
133
+		];
134
+
135
+		$this->_columns      = [
136
+			'cb' => '<input type="checkbox" />', // Render a checkbox instead of text
137
+			'_REG_att_checked_in' => esc_html__('Check In', 'event_espresso'),
138
+			'ATT_name'            => esc_html__('Registrant', 'event_espresso'),
139
+			'ATT_email'           => esc_html__('Email Address', 'event_espresso'),
140
+			'Event'               => esc_html__('Event', 'event_espresso'),
141
+			'PRC_name'            => esc_html__('TKT Option', 'event_espresso'),
142
+			'_REG_final_price'    => esc_html__('Price', 'event_espresso'),
143
+			'TXN_paid'            => esc_html__('Paid', 'event_espresso'),
144
+			'TXN_total'           => esc_html__('Total', 'event_espresso'),
145
+		];
146
+		$this->_primary_column = '_REG_att_checked_in';
147
+
148
+		// Add/remove columns when an event has been selected
149
+		if ($this->event_id) {
150
+			// Render a checkbox column
151
+			$this->_columns['cb'] = '<input type="checkbox" />';
152
+			$this->_has_checkbox_column = true;
153
+			// Remove the 'Event' column
154
+			unset($this->_columns['Event']);
155
+			$this->setBottomButtons();
156
+		}
157
+
158
+		$this->_sortable_columns = [
159
+			/**
160
+			 * Allows users to change the default sort if they wish.
161
+			 * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name.
162
+			 *
163
+			 * Note: usual naming conventions for filters aren't followed here so that just one filter can be used to
164
+			 * change the sorts on any list table involving registration contacts.  If you want to only change the filter
165
+			 * for a specific list table you can use the provided reference to this object instance.
166
+			 */
167
+			'ATT_name' => [
168
+				'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
169
+				true,
170
+				$this,
171
+			]
172
+				? ['ATT_lname' => true]
173
+				: ['ATT_fname' => true],
174
+			'Event'    => ['Event.EVT_name' => false],
175
+		];
176
+
177
+		$this->_hidden_columns = [];
178
+	}
179
+
180
+
181
+	private function setBottomButtons()
182
+	{
183
+		if (
184
+			! EE_Registry::instance()->CAP->current_user_can(
185
+				'ee_read_registrations',
186
+				'espresso_registrations_registrations_reports',
187
+				$this->event_id
188
+			)
189
+		) {
190
+			return;
191
+		}
192
+
193
+		$return_url = $this->getReturnUrl();
194
+		$this->_bottom_buttons = [
195
+			'report' => [
196
+				'route'         => 'registrations_report',
197
+				'extra_request' =>
198
+					[
199
+						'EVT_ID'     => $this->event_id,
200
+						'return_url' => $return_url,
201
+					],
202
+			],
203
+		];
204
+
205
+		$request_params = $this->request->requestParams();
206
+
207
+		$this->_bottom_buttons['report_filtered'] = [
208
+			'route'         => 'registrations_checkin_report',
209
+			'extra_request' => [
210
+				'use_filters' => true,
211
+				'filters'     => array_merge(
212
+					[
213
+						'EVT_ID' => $this->event_id,
214
+					],
215
+					array_diff_key(
216
+						$request_params,
217
+						array_flip(
218
+							[
219
+								'page',
220
+								'action',
221
+								'default_nonce',
222
+							]
223
+						)
224
+					)
225
+				),
226
+				'return_url'  => $return_url,
227
+			],
228
+		];
229
+	}
230
+
231
+
232
+	/**
233
+	 * @param EE_Registration $item
234
+	 * @return string
235
+	 */
236
+	protected function _get_row_class($item): string
237
+	{
238
+		$class = parent::_get_row_class($item);
239
+		if ($this->_has_checkbox_column) {
240
+			$class .= ' has-checkbox-column';
241
+		}
242
+		return $class;
243
+	}
244
+
245
+
246
+	/**
247
+	 * @return array
248
+	 * @throws EE_Error
249
+	 * @throws ReflectionException
250
+	 */
251
+	protected function _get_table_filters(): array
252
+	{
253
+		$filters = [];
254
+		$this->hide_expired = $this->request->getRequestParam('hide_expired', false, 'bool');
255
+		$this->hide_upcoming = $this->request->getRequestParam('hide_upcoming', false, 'bool');
256
+		$hide_expired_checked = $this->hide_expired ? 'checked' : '';
257
+		$hide_upcoming_checked = $this->hide_upcoming ? 'checked' : '';
258
+		// get datetimes for ALL active events (note possible capability restrictions)
259
+		$events   = $this->datetimes_for_event->getAllDatetimesForAllEvents();
260
+		$event_options[] = [
261
+			'id'   => 0,
262
+			'text' => esc_html__(' - select an event - ', 'event_espresso'),
263
+		];
264
+		/** @var EE_Event $event */
265
+		foreach ($events as $event) {
266
+			// any registrations for this event?
267
+			if (! $event instanceof EE_Event/* || ! $event->get_count_of_all_registrations()*/) {
268
+				continue;
269
+			}
270
+			$expired_class = $event->is_expired() ? 'ee-expired-event' : '';
271
+			$upcoming_class  = $event->is_upcoming() ? ' ee-upcoming-event' : '';
272
+
273
+			$event_options[] = [
274
+				'id'    => $event->ID(),
275
+				'text'  => apply_filters(
276
+					'FHEE__EE_Event_Registrations___get_table_filters__event_name',
277
+					$event->name(),
278
+					$event
279
+				),
280
+				'class' => $expired_class . $upcoming_class,
281
+			];
282
+			if ($event->ID() === $this->event_id) {
283
+				$this->hide_expired = $expired_class === '' ? $this->hide_expired : false;
284
+				$hide_expired_checked  = $expired_class === '' ? $hide_expired_checked : '';
285
+				$this->hide_upcoming = $upcoming_class === '' ? $this->hide_upcoming : false;
286
+				$hide_upcoming_checked = $upcoming_class === '' ? $hide_upcoming_checked : '';
287
+			}
288
+		}
289
+
290
+		$select_class = $this->hide_expired ? 'ee-hide-expired-events' : '';
291
+		$select_class .= $this->hide_upcoming ? ' ee-hide-upcoming-events' : '';
292
+
293
+		$filters[] = '
294 294
         <div class="ee-event-filter__wrapper">
295 295
             <label class="ee-event-filter-main-label">' . esc_html__('Check-in Status for', 'event_espresso') . '</label>
296 296
             <div class="ee-event-filter">
297 297
                 <span class="ee-event-selector">
298 298
                     <label for="event_id">' . esc_html__('Event', 'event_espresso') . '</label>
299 299
                     ' . EEH_Form_Fields::select_input(
300
-                        'event_id',
301
-                        $event_options,
302
-                        $this->event_id,
303
-                        '',
304
-                        $select_class
305
-                    ) . '
300
+						'event_id',
301
+						$event_options,
302
+						$this->event_id,
303
+						'',
304
+						$select_class
305
+					) . '
306 306
                 </span>';
307
-        // DTT datetimes filter
308
-        $datetimes_for_event = $this->datetimes_for_event->getAllDatetimesForEvent($hide_upcoming_checked === 'checked');
309
-        if (count($datetimes_for_event) > 1) {
310
-            $datetimes[0] = esc_html__(' - select a datetime - ', 'event_espresso');
311
-            foreach ($datetimes_for_event as $datetime) {
312
-                if ($datetime instanceof EE_Datetime) {
313
-                    $datetime_string = $datetime->name();
314
-                    $datetime_string = ! empty($datetime_string) ? $datetime_string . ': ' : '';
315
-                    $datetime_string .= $datetime->date_and_time_range();
316
-                    $datetime_string .= $datetime->is_active() ? ' ∗' : '';
317
-                    $datetime_string .= $datetime->is_expired() ? ' «' : '';
318
-                    $datetime_string .= $datetime->is_upcoming() ? ' »' : '';
319
-                    // now put it all together
320
-                    $datetimes[ $datetime->ID() ] = $datetime_string;
321
-                }
322
-            }
323
-            $filters[] = '
307
+		// DTT datetimes filter
308
+		$datetimes_for_event = $this->datetimes_for_event->getAllDatetimesForEvent($hide_upcoming_checked === 'checked');
309
+		if (count($datetimes_for_event) > 1) {
310
+			$datetimes[0] = esc_html__(' - select a datetime - ', 'event_espresso');
311
+			foreach ($datetimes_for_event as $datetime) {
312
+				if ($datetime instanceof EE_Datetime) {
313
+					$datetime_string = $datetime->name();
314
+					$datetime_string = ! empty($datetime_string) ? $datetime_string . ': ' : '';
315
+					$datetime_string .= $datetime->date_and_time_range();
316
+					$datetime_string .= $datetime->is_active() ? ' ∗' : '';
317
+					$datetime_string .= $datetime->is_expired() ? ' «' : '';
318
+					$datetime_string .= $datetime->is_upcoming() ? ' »' : '';
319
+					// now put it all together
320
+					$datetimes[ $datetime->ID() ] = $datetime_string;
321
+				}
322
+			}
323
+			$filters[] = '
324 324
                 <span class="ee-datetime-selector">
325 325
                     <label for="DTT_ID">' . esc_html__('Datetime', 'event_espresso') . '</label>
326 326
                     ' . EEH_Form_Fields::select_input(
327
-                        'DTT_ID',
328
-                        $datetimes,
329
-                        $this->datetime_id
330
-                    ) . '
327
+						'DTT_ID',
328
+						$datetimes,
329
+						$this->datetime_id
330
+					) . '
331 331
                 </span>';
332
-        }
333
-        $filters[] = '
332
+		}
333
+		$filters[] = '
334 334
                 <span class="ee-hide-upcoming-check">
335 335
                     <label for="js-ee-hide-upcoming-events">
336 336
                         <input type="checkbox" id="js-ee-hide-upcoming-events" name="hide_upcoming" '
337
-                         . $hide_upcoming_checked
338
-                         . '>
337
+						 . $hide_upcoming_checked
338
+						 . '>
339 339
                         '
340
-                         . esc_html__('Hide Upcoming Events', 'event_espresso')
341
-                         . '
340
+						 . esc_html__('Hide Upcoming Events', 'event_espresso')
341
+						 . '
342 342
                     </label>
343 343
                     <span class="ee-help-btn dashicons dashicons-editor-help ee-aria-tooltip" aria-label="'
344
-                         . esc_html__(
345
-                             'Will not display events with start dates in the future (ie: have not yet begun)',
346
-                             'event_espresso'
347
-                         )
348
-                         . '"></span>
344
+						 . esc_html__(
345
+							 'Will not display events with start dates in the future (ie: have not yet begun)',
346
+							 'event_espresso'
347
+						 )
348
+						 . '"></span>
349 349
                 </span>
350 350
                 <span class="ee-hide-expired-check">
351 351
                     <label for="js-ee-hide-expired-events">
352 352
                         <input type="checkbox" id="js-ee-hide-expired-events" name="hide_expired" '
353
-                         . $hide_expired_checked
354
-                         . '>
353
+						 . $hide_expired_checked
354
+						 . '>
355 355
                         '
356
-                         . esc_html__('Hide Expired Events', 'event_espresso')
357
-                         . '
356
+						 . esc_html__('Hide Expired Events', 'event_espresso')
357
+						 . '
358 358
                     </label>
359 359
                     <span class="ee-help-btn dashicons dashicons-editor-help ee-aria-tooltip" aria-label="'
360
-                         . esc_html__(
361
-                             'Will not display events with end dates in the past (ie: have already finished)',
362
-                             'event_espresso'
363
-                         )
364
-                         . '"></span>
360
+						 . esc_html__(
361
+							 'Will not display events with end dates in the past (ie: have already finished)',
362
+							 'event_espresso'
363
+						 )
364
+						 . '"></span>
365 365
                 </span>
366 366
             </div>
367 367
         </div>';
368
-        return $filters;
369
-    }
370
-
371
-
372
-    /**
373
-     * @throws EE_Error
374
-     * @throws ReflectionException
375
-     */
376
-    protected function _add_view_counts()
377
-    {
378
-        $this->_views['all']['count'] = $this->_get_total_event_attendees();
379
-    }
380
-
381
-
382
-    /**
383
-     * @return int
384
-     * @throws EE_Error
385
-     * @throws ReflectionException
386
-     */
387
-    protected function _get_total_event_attendees(): int
388
-    {
389
-        $query_params      = [];
390
-        if ($this->event_id) {
391
-            $query_params[0]['EVT_ID'] = $this->event_id;
392
-        }
393
-        // if DTT is included we only show for that datetime.  Otherwise we're showing for all datetimes (the event).
394
-        if ($this->datetime_id) {
395
-            $query_params[0]['Ticket.Datetime.DTT_ID'] = $this->datetime_id;
396
-        }
397
-        $status_ids_array          = apply_filters(
398
-            'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
399
-            [EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved]
400
-        );
401
-        $query_params[0]['STS_ID'] = ['IN', $status_ids_array];
402
-        return EEM_Registration::instance()->count($query_params);
403
-    }
404
-
405
-
406
-    /**
407
-     * @param EE_Registration $item
408
-     * @return string
409
-     * @throws EE_Error
410
-     * @throws ReflectionException
411
-     */
412
-    public function column_cb($item): string
413
-    {
414
-        return sprintf('<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID());
415
-    }
416
-
417
-
418
-    /**
419
-     * column_REG_att_checked_in
420
-     *
421
-     * @param EE_Registration $registration
422
-     * @return string
423
-     * @throws EE_Error
424
-     * @throws InvalidArgumentException
425
-     * @throws InvalidDataTypeException
426
-     * @throws InvalidInterfaceException
427
-     * @throws ReflectionException
428
-     */
429
-    public function column__REG_att_checked_in(EE_Registration $registration): string
430
-    {
431
-        // we need a local variable for the datetime for each row
432
-        // (so that we don't pollute state for the entire table)
433
-        // so let's try to get it from the registration's event
434
-        $DTT_ID = $this->datetime_id;
435
-        if (! $DTT_ID) {
436
-            $reg_ticket_datetimes = $registration->ticket()->datetimes();
437
-            if (count($reg_ticket_datetimes) === 1) {
438
-                $reg_ticket_datetime = reset($reg_ticket_datetimes);
439
-                $DTT_ID = $reg_ticket_datetime instanceof EE_Datetime ? $reg_ticket_datetime->ID() : 0;
440
-            }
441
-        }
442
-
443
-        if (! $DTT_ID) {
444
-            $this->datetimes_for_current_row = DatetimesForEventCheckIn::fromRegistration($registration);
445
-            $datetime = $this->datetimes_for_current_row->getOneDatetimeForEvent($DTT_ID);
446
-            $DTT_ID = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
447
-        }
448
-
449
-        $checkin_status_dashicon = CheckinStatusDashicon::fromRegistrationAndDatetimeId(
450
-            $registration,
451
-            $DTT_ID
452
-        );
453
-
454
-        $aria_label = $checkin_status_dashicon->ariaLabel();
455
-        $dashicon_class = $checkin_status_dashicon->cssClasses();
456
-        $attributes = ' onClick="return false"';
457
-        $button_class = 'button button--secondary button--icon-only ee-aria-tooltip ee-aria-tooltip--big-box';
458
-
459
-        if (
460
-            $DTT_ID
461
-            && EE_Registry::instance()->CAP->current_user_can(
462
-                'ee_edit_checkin',
463
-                'espresso_registrations_toggle_checkin_status',
464
-                $registration->ID()
465
-            )
466
-        ) {
467
-            // overwrite the disabled attribute with data attributes for performing checkin
468
-            $attributes = 'data-_regid="' . $registration->ID() . '"';
469
-            $attributes .= ' data-dttid="' . $DTT_ID . '"';
470
-            $attributes .= ' data-nonce="' . wp_create_nonce('checkin_nonce') . '"';
471
-            $button_class .= ' clickable trigger-checkin';
472
-        }
473
-
474
-        $content = '
368
+		return $filters;
369
+	}
370
+
371
+
372
+	/**
373
+	 * @throws EE_Error
374
+	 * @throws ReflectionException
375
+	 */
376
+	protected function _add_view_counts()
377
+	{
378
+		$this->_views['all']['count'] = $this->_get_total_event_attendees();
379
+	}
380
+
381
+
382
+	/**
383
+	 * @return int
384
+	 * @throws EE_Error
385
+	 * @throws ReflectionException
386
+	 */
387
+	protected function _get_total_event_attendees(): int
388
+	{
389
+		$query_params      = [];
390
+		if ($this->event_id) {
391
+			$query_params[0]['EVT_ID'] = $this->event_id;
392
+		}
393
+		// if DTT is included we only show for that datetime.  Otherwise we're showing for all datetimes (the event).
394
+		if ($this->datetime_id) {
395
+			$query_params[0]['Ticket.Datetime.DTT_ID'] = $this->datetime_id;
396
+		}
397
+		$status_ids_array          = apply_filters(
398
+			'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
399
+			[EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved]
400
+		);
401
+		$query_params[0]['STS_ID'] = ['IN', $status_ids_array];
402
+		return EEM_Registration::instance()->count($query_params);
403
+	}
404
+
405
+
406
+	/**
407
+	 * @param EE_Registration $item
408
+	 * @return string
409
+	 * @throws EE_Error
410
+	 * @throws ReflectionException
411
+	 */
412
+	public function column_cb($item): string
413
+	{
414
+		return sprintf('<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID());
415
+	}
416
+
417
+
418
+	/**
419
+	 * column_REG_att_checked_in
420
+	 *
421
+	 * @param EE_Registration $registration
422
+	 * @return string
423
+	 * @throws EE_Error
424
+	 * @throws InvalidArgumentException
425
+	 * @throws InvalidDataTypeException
426
+	 * @throws InvalidInterfaceException
427
+	 * @throws ReflectionException
428
+	 */
429
+	public function column__REG_att_checked_in(EE_Registration $registration): string
430
+	{
431
+		// we need a local variable for the datetime for each row
432
+		// (so that we don't pollute state for the entire table)
433
+		// so let's try to get it from the registration's event
434
+		$DTT_ID = $this->datetime_id;
435
+		if (! $DTT_ID) {
436
+			$reg_ticket_datetimes = $registration->ticket()->datetimes();
437
+			if (count($reg_ticket_datetimes) === 1) {
438
+				$reg_ticket_datetime = reset($reg_ticket_datetimes);
439
+				$DTT_ID = $reg_ticket_datetime instanceof EE_Datetime ? $reg_ticket_datetime->ID() : 0;
440
+			}
441
+		}
442
+
443
+		if (! $DTT_ID) {
444
+			$this->datetimes_for_current_row = DatetimesForEventCheckIn::fromRegistration($registration);
445
+			$datetime = $this->datetimes_for_current_row->getOneDatetimeForEvent($DTT_ID);
446
+			$DTT_ID = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
447
+		}
448
+
449
+		$checkin_status_dashicon = CheckinStatusDashicon::fromRegistrationAndDatetimeId(
450
+			$registration,
451
+			$DTT_ID
452
+		);
453
+
454
+		$aria_label = $checkin_status_dashicon->ariaLabel();
455
+		$dashicon_class = $checkin_status_dashicon->cssClasses();
456
+		$attributes = ' onClick="return false"';
457
+		$button_class = 'button button--secondary button--icon-only ee-aria-tooltip ee-aria-tooltip--big-box';
458
+
459
+		if (
460
+			$DTT_ID
461
+			&& EE_Registry::instance()->CAP->current_user_can(
462
+				'ee_edit_checkin',
463
+				'espresso_registrations_toggle_checkin_status',
464
+				$registration->ID()
465
+			)
466
+		) {
467
+			// overwrite the disabled attribute with data attributes for performing checkin
468
+			$attributes = 'data-_regid="' . $registration->ID() . '"';
469
+			$attributes .= ' data-dttid="' . $DTT_ID . '"';
470
+			$attributes .= ' data-nonce="' . wp_create_nonce('checkin_nonce') . '"';
471
+			$button_class .= ' clickable trigger-checkin';
472
+		}
473
+
474
+		$content = '
475 475
         <button aria-label="' . $aria_label . '" class="' . $button_class . '" ' . $attributes . '>
476 476
             <span class="' . $dashicon_class . '" ></span>
477 477
         </button>
478 478
         <span class="show-on-mobile-view-only">' . $this->column_ATT_name($registration) . '</span>';
479
-        return $this->columnContent('_REG_att_checked_in', $content, 'center');
480
-    }
481
-
482
-
483
-    /**
484
-     * @param EE_Registration $registration
485
-     * @return string
486
-     * @throws EE_Error
487
-     * @throws ReflectionException
488
-     */
489
-    public function column_ATT_name(EE_Registration $registration): string
490
-    {
491
-        $attendee = $registration->attendee();
492
-        if (! $attendee instanceof EE_Attendee) {
493
-            return esc_html__('No contact record for this registration.', 'event_espresso');
494
-        }
495
-        // edit attendee link
496
-        $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
497
-            ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
498
-            REG_ADMIN_URL
499
-        );
500
-        $name_link    = '
479
+		return $this->columnContent('_REG_att_checked_in', $content, 'center');
480
+	}
481
+
482
+
483
+	/**
484
+	 * @param EE_Registration $registration
485
+	 * @return string
486
+	 * @throws EE_Error
487
+	 * @throws ReflectionException
488
+	 */
489
+	public function column_ATT_name(EE_Registration $registration): string
490
+	{
491
+		$attendee = $registration->attendee();
492
+		if (! $attendee instanceof EE_Attendee) {
493
+			return esc_html__('No contact record for this registration.', 'event_espresso');
494
+		}
495
+		// edit attendee link
496
+		$edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
497
+			['action' => 'view_registration', '_REG_ID' => $registration->ID()],
498
+			REG_ADMIN_URL
499
+		);
500
+		$name_link    = '
501 501
             <span class="ee-status-dot ee-status-bg--' . esc_attr($registration->status_ID()) . ' ee-aria-tooltip"
502 502
             aria-label="' . EEH_Template::pretty_status($registration->status_ID(), false, 'sentence') . '">
503 503
             </span>';
504
-        $name_link    .= EE_Registry::instance()->CAP->current_user_can(
505
-            'ee_edit_contacts',
506
-            'espresso_registrations_edit_attendee'
507
-        )
508
-            ? '<a class="ee-aria-tooltip" href="' . $edit_lnk_url . '" aria-label="' . esc_attr__(
509
-                'View Registration Details',
510
-                'event_espresso'
511
-            ) . '">'
512
-              . $registration->attendee()->full_name()
513
-              . '</a>'
514
-            : $registration->attendee()->full_name();
515
-        $name_link    .= $registration->count() === 1
516
-            ? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon"></div></sup>	'
517
-            : '';
518
-        // add group details
519
-        $name_link .= '&nbsp;' . sprintf(
520
-            esc_html__('(%s of %s)', 'event_espresso'),
521
-            $registration->count(),
522
-            $registration->group_size()
523
-        );
524
-        // add regcode
525
-        $link      = EE_Admin_Page::add_query_args_and_nonce(
526
-            ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
527
-            REG_ADMIN_URL
528
-        );
529
-        $name_link .= '<br>';
530
-        $name_link .= EE_Registry::instance()->instance()->CAP->current_user_can(
531
-            'ee_read_registration',
532
-            'view_registration',
533
-            $registration->ID()
534
-        )
535
-            ? '<a class="ee-aria-tooltip" href="' . $link . '" aria-label="' . esc_attr__(
536
-                'View Registration Details',
537
-                'event_espresso'
538
-            ) . '">'
539
-              . $registration->reg_code()
540
-              . '</a>'
541
-            : $registration->reg_code();
542
-
543
-        $actions                 = [];
544
-        if (
545
-            $this->datetime_id
546
-            && EE_Registry::instance()->CAP->current_user_can(
547
-                'ee_read_checkins',
548
-                'espresso_registrations_registration_checkins'
549
-            )
550
-        ) {
551
-            $checkin_list_url = EE_Admin_Page::add_query_args_and_nonce(
552
-                ['action' => 'registration_checkins', '_REG_ID' => $registration->ID(), 'DTT_ID' => $this->datetime_id],
553
-                REG_ADMIN_URL
554
-            );
555
-            // get the timestamps for this registration's checkins, related to the selected datetime
556
-            /** @var EE_Checkin[] $checkins */
557
-            $checkins = $registration->get_many_related('Checkin', [['DTT_ID' => $this->datetime_id]]);
558
-            if (! empty($checkins)) {
559
-                // get the last timestamp
560
-                $last_checkin = end($checkins);
561
-                // get timestamp string
562
-                $timestamp_string   = $last_checkin->get_datetime('CHK_timestamp');
563
-                $actions['checkin'] = '
504
+		$name_link    .= EE_Registry::instance()->CAP->current_user_can(
505
+			'ee_edit_contacts',
506
+			'espresso_registrations_edit_attendee'
507
+		)
508
+			? '<a class="ee-aria-tooltip" href="' . $edit_lnk_url . '" aria-label="' . esc_attr__(
509
+				'View Registration Details',
510
+				'event_espresso'
511
+			) . '">'
512
+			  . $registration->attendee()->full_name()
513
+			  . '</a>'
514
+			: $registration->attendee()->full_name();
515
+		$name_link    .= $registration->count() === 1
516
+			? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon"></div></sup>	'
517
+			: '';
518
+		// add group details
519
+		$name_link .= '&nbsp;' . sprintf(
520
+			esc_html__('(%s of %s)', 'event_espresso'),
521
+			$registration->count(),
522
+			$registration->group_size()
523
+		);
524
+		// add regcode
525
+		$link      = EE_Admin_Page::add_query_args_and_nonce(
526
+			['action' => 'view_registration', '_REG_ID' => $registration->ID()],
527
+			REG_ADMIN_URL
528
+		);
529
+		$name_link .= '<br>';
530
+		$name_link .= EE_Registry::instance()->instance()->CAP->current_user_can(
531
+			'ee_read_registration',
532
+			'view_registration',
533
+			$registration->ID()
534
+		)
535
+			? '<a class="ee-aria-tooltip" href="' . $link . '" aria-label="' . esc_attr__(
536
+				'View Registration Details',
537
+				'event_espresso'
538
+			) . '">'
539
+			  . $registration->reg_code()
540
+			  . '</a>'
541
+			: $registration->reg_code();
542
+
543
+		$actions                 = [];
544
+		if (
545
+			$this->datetime_id
546
+			&& EE_Registry::instance()->CAP->current_user_can(
547
+				'ee_read_checkins',
548
+				'espresso_registrations_registration_checkins'
549
+			)
550
+		) {
551
+			$checkin_list_url = EE_Admin_Page::add_query_args_and_nonce(
552
+				['action' => 'registration_checkins', '_REG_ID' => $registration->ID(), 'DTT_ID' => $this->datetime_id],
553
+				REG_ADMIN_URL
554
+			);
555
+			// get the timestamps for this registration's checkins, related to the selected datetime
556
+			/** @var EE_Checkin[] $checkins */
557
+			$checkins = $registration->get_many_related('Checkin', [['DTT_ID' => $this->datetime_id]]);
558
+			if (! empty($checkins)) {
559
+				// get the last timestamp
560
+				$last_checkin = end($checkins);
561
+				// get timestamp string
562
+				$timestamp_string   = $last_checkin->get_datetime('CHK_timestamp');
563
+				$actions['checkin'] = '
564 564
                     <a  class="ee-aria-tooltip"
565 565
                         href="' . $checkin_list_url . '"
566 566
                         aria-label="' . esc_attr__(
567
-                            'View this registrant\'s check-ins/checkouts for the datetime',
568
-                            'event_espresso'
569
-                        ) . '"
567
+							'View this registrant\'s check-ins/checkouts for the datetime',
568
+							'event_espresso'
569
+						) . '"
570 570
                     >
571 571
                         ' . $last_checkin->getCheckInText() . ': ' . $timestamp_string . '
572 572
                     </a>';
573
-            }
574
-        }
575
-        $content = (! empty($this->datetime_id) && ! empty($checkins))
576
-            ? sprintf('%1$s %2$s', $name_link, $this->row_actions($actions, true))
577
-            : $name_link;
578
-        return $this->columnContent('ATT_name', $content);
579
-    }
580
-
581
-
582
-    /**
583
-     * @param EE_Registration $registration
584
-     * @return string
585
-     * @throws EE_Error
586
-     * @throws EE_Error
587
-     */
588
-    public function column_ATT_email(EE_Registration $registration): string
589
-    {
590
-        $attendee = $registration->attendee();
591
-        $content = $attendee instanceof EE_Attendee ? $attendee->email() : '';
592
-        return $this->columnContent('ATT_email', $content);
593
-    }
594
-
595
-
596
-    /**
597
-     * @param EE_Registration $registration
598
-     * @return string
599
-     * @throws EE_Error
600
-     * @throws ReflectionException
601
-     */
602
-    public function column_Event(EE_Registration $registration): string
603
-    {
604
-        try {
605
-            $event            = $this->event instanceof EE_Event ? $this->event : $registration->event();
606
-            $checkin_link_url = EE_Admin_Page::add_query_args_and_nonce(
607
-                ['action' => 'event_registrations', 'event_id' => $event->ID()],
608
-                REG_ADMIN_URL
609
-            );
610
-            $content      = EE_Registry::instance()->CAP->current_user_can(
611
-                'ee_read_checkins',
612
-                'espresso_registrations_registration_checkins'
613
-            ) ? '<a class="ee-aria-tooltip" href="' . $checkin_link_url . '" aria-label="'
614
-                . esc_attr__(
615
-                    'View Checkins for this Event',
616
-                    'event_espresso'
617
-                ) . '">' . $event->name() . '</a>' : $event->name();
618
-        } catch (EntityNotFoundException $e) {
619
-            $content = esc_html__('Unknown', 'event_espresso');
620
-        }
621
-        return $this->columnContent('Event', $content);
622
-    }
623
-
624
-
625
-    /**
626
-     * @param EE_Registration $registration
627
-     * @return string
628
-     * @throws EE_Error
629
-     * @throws ReflectionException
630
-     */
631
-    public function column_PRC_name(EE_Registration $registration): string
632
-    {
633
-        $content = $registration->ticket() instanceof EE_Ticket
634
-            ? $registration->ticket()->name()
635
-            : esc_html__(
636
-                "Unknown",
637
-                "event_espresso"
638
-            );
639
-        return $this->columnContent('PRC_name', $content);
640
-    }
641
-
642
-
643
-    /**
644
-     * column_REG_final_price
645
-     *
646
-     * @param EE_Registration $registration
647
-     * @return string
648
-     * @throws EE_Error
649
-     */
650
-    public function column__REG_final_price(EE_Registration $registration): string
651
-    {
652
-        return $this->columnContent('_REG_final_price', $registration->pretty_final_price(), 'end');
653
-    }
654
-
655
-
656
-    /**
657
-     * column_TXN_paid
658
-     *
659
-     * @param EE_Registration $registration
660
-     * @return string
661
-     * @throws EE_Error
662
-     * @throws ReflectionException
663
-     */
664
-    public function column_TXN_paid(EE_Registration $registration): string
665
-    {
666
-        $content = '';
667
-        if ($registration->count() === 1) {
668
-            if ($registration->transaction()->paid() >= $registration->transaction()->total()) {
669
-                return '<div class="dashicons dashicons-yes green-icon"></div>';
670
-            } else {
671
-                $view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
672
-                    ['action' => 'view_transaction', 'TXN_ID' => $registration->transaction_ID()],
673
-                    TXN_ADMIN_URL
674
-                );
675
-                $content = EE_Registry::instance()->CAP->current_user_can(
676
-                    'ee_read_transaction',
677
-                    'espresso_transactions_view_transaction'
678
-                ) ? '
573
+			}
574
+		}
575
+		$content = (! empty($this->datetime_id) && ! empty($checkins))
576
+			? sprintf('%1$s %2$s', $name_link, $this->row_actions($actions, true))
577
+			: $name_link;
578
+		return $this->columnContent('ATT_name', $content);
579
+	}
580
+
581
+
582
+	/**
583
+	 * @param EE_Registration $registration
584
+	 * @return string
585
+	 * @throws EE_Error
586
+	 * @throws EE_Error
587
+	 */
588
+	public function column_ATT_email(EE_Registration $registration): string
589
+	{
590
+		$attendee = $registration->attendee();
591
+		$content = $attendee instanceof EE_Attendee ? $attendee->email() : '';
592
+		return $this->columnContent('ATT_email', $content);
593
+	}
594
+
595
+
596
+	/**
597
+	 * @param EE_Registration $registration
598
+	 * @return string
599
+	 * @throws EE_Error
600
+	 * @throws ReflectionException
601
+	 */
602
+	public function column_Event(EE_Registration $registration): string
603
+	{
604
+		try {
605
+			$event            = $this->event instanceof EE_Event ? $this->event : $registration->event();
606
+			$checkin_link_url = EE_Admin_Page::add_query_args_and_nonce(
607
+				['action' => 'event_registrations', 'event_id' => $event->ID()],
608
+				REG_ADMIN_URL
609
+			);
610
+			$content      = EE_Registry::instance()->CAP->current_user_can(
611
+				'ee_read_checkins',
612
+				'espresso_registrations_registration_checkins'
613
+			) ? '<a class="ee-aria-tooltip" href="' . $checkin_link_url . '" aria-label="'
614
+				. esc_attr__(
615
+					'View Checkins for this Event',
616
+					'event_espresso'
617
+				) . '">' . $event->name() . '</a>' : $event->name();
618
+		} catch (EntityNotFoundException $e) {
619
+			$content = esc_html__('Unknown', 'event_espresso');
620
+		}
621
+		return $this->columnContent('Event', $content);
622
+	}
623
+
624
+
625
+	/**
626
+	 * @param EE_Registration $registration
627
+	 * @return string
628
+	 * @throws EE_Error
629
+	 * @throws ReflectionException
630
+	 */
631
+	public function column_PRC_name(EE_Registration $registration): string
632
+	{
633
+		$content = $registration->ticket() instanceof EE_Ticket
634
+			? $registration->ticket()->name()
635
+			: esc_html__(
636
+				"Unknown",
637
+				"event_espresso"
638
+			);
639
+		return $this->columnContent('PRC_name', $content);
640
+	}
641
+
642
+
643
+	/**
644
+	 * column_REG_final_price
645
+	 *
646
+	 * @param EE_Registration $registration
647
+	 * @return string
648
+	 * @throws EE_Error
649
+	 */
650
+	public function column__REG_final_price(EE_Registration $registration): string
651
+	{
652
+		return $this->columnContent('_REG_final_price', $registration->pretty_final_price(), 'end');
653
+	}
654
+
655
+
656
+	/**
657
+	 * column_TXN_paid
658
+	 *
659
+	 * @param EE_Registration $registration
660
+	 * @return string
661
+	 * @throws EE_Error
662
+	 * @throws ReflectionException
663
+	 */
664
+	public function column_TXN_paid(EE_Registration $registration): string
665
+	{
666
+		$content = '';
667
+		if ($registration->count() === 1) {
668
+			if ($registration->transaction()->paid() >= $registration->transaction()->total()) {
669
+				return '<div class="dashicons dashicons-yes green-icon"></div>';
670
+			} else {
671
+				$view_txn_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
672
+					['action' => 'view_transaction', 'TXN_ID' => $registration->transaction_ID()],
673
+					TXN_ADMIN_URL
674
+				);
675
+				$content = EE_Registry::instance()->CAP->current_user_can(
676
+					'ee_read_transaction',
677
+					'espresso_transactions_view_transaction'
678
+				) ? '
679 679
 				<a class="ee-aria-tooltip ee-status-color--'
680
-                    . $registration->transaction()->status_ID()
681
-                    . '" href="'
682
-                    . $view_txn_lnk_url
683
-                    . '"  aria-label="'
684
-                    . esc_attr__('View Transaction', 'event_espresso')
685
-                    . '">
680
+					. $registration->transaction()->status_ID()
681
+					. '" href="'
682
+					. $view_txn_lnk_url
683
+					. '"  aria-label="'
684
+					. esc_attr__('View Transaction', 'event_espresso')
685
+					. '">
686 686
 						'
687
-                    . $registration->transaction()->pretty_paid()
688
-                    . '
687
+					. $registration->transaction()->pretty_paid()
688
+					. '
689 689
 					</a>
690 690
 				' : $registration->transaction()->pretty_paid();
691
-            }
692
-        }
693
-        return $this->columnContent('TXN_paid', $content, 'end');
694
-    }
695
-
696
-
697
-    /**
698
-     *        column_TXN_total
699
-     *
700
-     * @param EE_Registration $registration
701
-     * @return string
702
-     * @throws EE_Error
703
-     * @throws ReflectionException
704
-     */
705
-    public function column_TXN_total(EE_Registration $registration): string
706
-    {
707
-        $content = '';
708
-        $txn = $registration->transaction();
709
-        $view_txn_url = add_query_arg(['action' => 'view_transaction', 'TXN_ID' => $txn->ID()], TXN_ADMIN_URL);
710
-        if ($registration->get('REG_count') === 1) {
711
-            $line_total_obj = $txn->total_line_item();
712
-            $txn_total      = $line_total_obj instanceof EE_Line_Item
713
-                ? $line_total_obj->get_pretty('LIN_total')
714
-                : esc_html__(
715
-                    'View Transaction',
716
-                    'event_espresso'
717
-                );
718
-            $content = EE_Registry::instance()->CAP->current_user_can(
719
-                'ee_read_transaction',
720
-                'espresso_transactions_view_transaction'
721
-            ) ? '<a class="ee-aria-tooltip" href="'
722
-                . $view_txn_url
723
-                . '" aria-label="'
724
-                . esc_attr__('View Transaction', 'event_espresso')
725
-                . '">'
726
-                . $txn_total
727
-                . '</a>'
728
-                : $txn_total;
729
-        }
730
-        return $this->columnContent('TXN_total', $content, 'end');
731
-    }
691
+			}
692
+		}
693
+		return $this->columnContent('TXN_paid', $content, 'end');
694
+	}
695
+
696
+
697
+	/**
698
+	 *        column_TXN_total
699
+	 *
700
+	 * @param EE_Registration $registration
701
+	 * @return string
702
+	 * @throws EE_Error
703
+	 * @throws ReflectionException
704
+	 */
705
+	public function column_TXN_total(EE_Registration $registration): string
706
+	{
707
+		$content = '';
708
+		$txn = $registration->transaction();
709
+		$view_txn_url = add_query_arg(['action' => 'view_transaction', 'TXN_ID' => $txn->ID()], TXN_ADMIN_URL);
710
+		if ($registration->get('REG_count') === 1) {
711
+			$line_total_obj = $txn->total_line_item();
712
+			$txn_total      = $line_total_obj instanceof EE_Line_Item
713
+				? $line_total_obj->get_pretty('LIN_total')
714
+				: esc_html__(
715
+					'View Transaction',
716
+					'event_espresso'
717
+				);
718
+			$content = EE_Registry::instance()->CAP->current_user_can(
719
+				'ee_read_transaction',
720
+				'espresso_transactions_view_transaction'
721
+			) ? '<a class="ee-aria-tooltip" href="'
722
+				. $view_txn_url
723
+				. '" aria-label="'
724
+				. esc_attr__('View Transaction', 'event_espresso')
725
+				. '">'
726
+				. $txn_total
727
+				. '</a>'
728
+				: $txn_total;
729
+		}
730
+		return $this->columnContent('TXN_total', $content, 'end');
731
+	}
732 732
 }
Please login to merge, or discard this patch.
Spacing   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -132,7 +132,7 @@  discard block
 block discarded – undo
132 132
             'screen'   => $this->_admin_page->get_current_screen()->id,
133 133
         ];
134 134
 
135
-        $this->_columns      = [
135
+        $this->_columns = [
136 136
             'cb' => '<input type="checkbox" />', // Render a checkbox instead of text
137 137
             '_REG_att_checked_in' => esc_html__('Check In', 'event_espresso'),
138 138
             'ATT_name'            => esc_html__('Registrant', 'event_espresso'),
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
         $hide_expired_checked = $this->hide_expired ? 'checked' : '';
257 257
         $hide_upcoming_checked = $this->hide_upcoming ? 'checked' : '';
258 258
         // get datetimes for ALL active events (note possible capability restrictions)
259
-        $events   = $this->datetimes_for_event->getAllDatetimesForAllEvents();
259
+        $events = $this->datetimes_for_event->getAllDatetimesForAllEvents();
260 260
         $event_options[] = [
261 261
             'id'   => 0,
262 262
             'text' => esc_html__(' - select an event - ', 'event_espresso'),
@@ -264,7 +264,7 @@  discard block
 block discarded – undo
264 264
         /** @var EE_Event $event */
265 265
         foreach ($events as $event) {
266 266
             // any registrations for this event?
267
-            if (! $event instanceof EE_Event/* || ! $event->get_count_of_all_registrations()*/) {
267
+            if ( ! $event instanceof EE_Event/* || ! $event->get_count_of_all_registrations()*/) {
268 268
                 continue;
269 269
             }
270 270
             $expired_class = $event->is_expired() ? 'ee-expired-event' : '';
@@ -277,7 +277,7 @@  discard block
 block discarded – undo
277 277
                     $event->name(),
278 278
                     $event
279 279
                 ),
280
-                'class' => $expired_class . $upcoming_class,
280
+                'class' => $expired_class.$upcoming_class,
281 281
             ];
282 282
             if ($event->ID() === $this->event_id) {
283 283
                 $this->hide_expired = $expired_class === '' ? $this->hide_expired : false;
@@ -292,17 +292,17 @@  discard block
 block discarded – undo
292 292
 
293 293
         $filters[] = '
294 294
         <div class="ee-event-filter__wrapper">
295
-            <label class="ee-event-filter-main-label">' . esc_html__('Check-in Status for', 'event_espresso') . '</label>
295
+            <label class="ee-event-filter-main-label">' . esc_html__('Check-in Status for', 'event_espresso').'</label>
296 296
             <div class="ee-event-filter">
297 297
                 <span class="ee-event-selector">
298
-                    <label for="event_id">' . esc_html__('Event', 'event_espresso') . '</label>
298
+                    <label for="event_id">' . esc_html__('Event', 'event_espresso').'</label>
299 299
                     ' . EEH_Form_Fields::select_input(
300 300
                         'event_id',
301 301
                         $event_options,
302 302
                         $this->event_id,
303 303
                         '',
304 304
                         $select_class
305
-                    ) . '
305
+                    ).'
306 306
                 </span>';
307 307
         // DTT datetimes filter
308 308
         $datetimes_for_event = $this->datetimes_for_event->getAllDatetimesForEvent($hide_upcoming_checked === 'checked');
@@ -311,23 +311,23 @@  discard block
 block discarded – undo
311 311
             foreach ($datetimes_for_event as $datetime) {
312 312
                 if ($datetime instanceof EE_Datetime) {
313 313
                     $datetime_string = $datetime->name();
314
-                    $datetime_string = ! empty($datetime_string) ? $datetime_string . ': ' : '';
314
+                    $datetime_string = ! empty($datetime_string) ? $datetime_string.': ' : '';
315 315
                     $datetime_string .= $datetime->date_and_time_range();
316 316
                     $datetime_string .= $datetime->is_active() ? ' ∗' : '';
317 317
                     $datetime_string .= $datetime->is_expired() ? ' «' : '';
318 318
                     $datetime_string .= $datetime->is_upcoming() ? ' »' : '';
319 319
                     // now put it all together
320
-                    $datetimes[ $datetime->ID() ] = $datetime_string;
320
+                    $datetimes[$datetime->ID()] = $datetime_string;
321 321
                 }
322 322
             }
323 323
             $filters[] = '
324 324
                 <span class="ee-datetime-selector">
325
-                    <label for="DTT_ID">' . esc_html__('Datetime', 'event_espresso') . '</label>
325
+                    <label for="DTT_ID">' . esc_html__('Datetime', 'event_espresso').'</label>
326 326
                     ' . EEH_Form_Fields::select_input(
327 327
                         'DTT_ID',
328 328
                         $datetimes,
329 329
                         $this->datetime_id
330
-                    ) . '
330
+                    ).'
331 331
                 </span>';
332 332
         }
333 333
         $filters[] = '
@@ -386,7 +386,7 @@  discard block
 block discarded – undo
386 386
      */
387 387
     protected function _get_total_event_attendees(): int
388 388
     {
389
-        $query_params      = [];
389
+        $query_params = [];
390 390
         if ($this->event_id) {
391 391
             $query_params[0]['EVT_ID'] = $this->event_id;
392 392
         }
@@ -394,7 +394,7 @@  discard block
 block discarded – undo
394 394
         if ($this->datetime_id) {
395 395
             $query_params[0]['Ticket.Datetime.DTT_ID'] = $this->datetime_id;
396 396
         }
397
-        $status_ids_array          = apply_filters(
397
+        $status_ids_array = apply_filters(
398 398
             'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
399 399
             [EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved]
400 400
         );
@@ -432,7 +432,7 @@  discard block
 block discarded – undo
432 432
         // (so that we don't pollute state for the entire table)
433 433
         // so let's try to get it from the registration's event
434 434
         $DTT_ID = $this->datetime_id;
435
-        if (! $DTT_ID) {
435
+        if ( ! $DTT_ID) {
436 436
             $reg_ticket_datetimes = $registration->ticket()->datetimes();
437 437
             if (count($reg_ticket_datetimes) === 1) {
438 438
                 $reg_ticket_datetime = reset($reg_ticket_datetimes);
@@ -440,7 +440,7 @@  discard block
 block discarded – undo
440 440
             }
441 441
         }
442 442
 
443
-        if (! $DTT_ID) {
443
+        if ( ! $DTT_ID) {
444 444
             $this->datetimes_for_current_row = DatetimesForEventCheckIn::fromRegistration($registration);
445 445
             $datetime = $this->datetimes_for_current_row->getOneDatetimeForEvent($DTT_ID);
446 446
             $DTT_ID = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
@@ -465,17 +465,17 @@  discard block
 block discarded – undo
465 465
             )
466 466
         ) {
467 467
             // overwrite the disabled attribute with data attributes for performing checkin
468
-            $attributes = 'data-_regid="' . $registration->ID() . '"';
469
-            $attributes .= ' data-dttid="' . $DTT_ID . '"';
470
-            $attributes .= ' data-nonce="' . wp_create_nonce('checkin_nonce') . '"';
468
+            $attributes = 'data-_regid="'.$registration->ID().'"';
469
+            $attributes .= ' data-dttid="'.$DTT_ID.'"';
470
+            $attributes .= ' data-nonce="'.wp_create_nonce('checkin_nonce').'"';
471 471
             $button_class .= ' clickable trigger-checkin';
472 472
         }
473 473
 
474 474
         $content = '
475
-        <button aria-label="' . $aria_label . '" class="' . $button_class . '" ' . $attributes . '>
476
-            <span class="' . $dashicon_class . '" ></span>
475
+        <button aria-label="' . $aria_label.'" class="'.$button_class.'" '.$attributes.'>
476
+            <span class="' . $dashicon_class.'" ></span>
477 477
         </button>
478
-        <span class="show-on-mobile-view-only">' . $this->column_ATT_name($registration) . '</span>';
478
+        <span class="show-on-mobile-view-only">' . $this->column_ATT_name($registration).'</span>';
479 479
         return $this->columnContent('_REG_att_checked_in', $content, 'center');
480 480
     }
481 481
 
@@ -489,7 +489,7 @@  discard block
 block discarded – undo
489 489
     public function column_ATT_name(EE_Registration $registration): string
490 490
     {
491 491
         $attendee = $registration->attendee();
492
-        if (! $attendee instanceof EE_Attendee) {
492
+        if ( ! $attendee instanceof EE_Attendee) {
493 493
             return esc_html__('No contact record for this registration.', 'event_espresso');
494 494
         }
495 495
         // edit attendee link
@@ -497,32 +497,32 @@  discard block
 block discarded – undo
497 497
             ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
498 498
             REG_ADMIN_URL
499 499
         );
500
-        $name_link    = '
501
-            <span class="ee-status-dot ee-status-bg--' . esc_attr($registration->status_ID()) . ' ee-aria-tooltip"
502
-            aria-label="' . EEH_Template::pretty_status($registration->status_ID(), false, 'sentence') . '">
500
+        $name_link = '
501
+            <span class="ee-status-dot ee-status-bg--' . esc_attr($registration->status_ID()).' ee-aria-tooltip"
502
+            aria-label="' . EEH_Template::pretty_status($registration->status_ID(), false, 'sentence').'">
503 503
             </span>';
504
-        $name_link    .= EE_Registry::instance()->CAP->current_user_can(
504
+        $name_link .= EE_Registry::instance()->CAP->current_user_can(
505 505
             'ee_edit_contacts',
506 506
             'espresso_registrations_edit_attendee'
507 507
         )
508
-            ? '<a class="ee-aria-tooltip" href="' . $edit_lnk_url . '" aria-label="' . esc_attr__(
508
+            ? '<a class="ee-aria-tooltip" href="'.$edit_lnk_url.'" aria-label="'.esc_attr__(
509 509
                 'View Registration Details',
510 510
                 'event_espresso'
511
-            ) . '">'
511
+            ).'">'
512 512
               . $registration->attendee()->full_name()
513 513
               . '</a>'
514 514
             : $registration->attendee()->full_name();
515
-        $name_link    .= $registration->count() === 1
515
+        $name_link .= $registration->count() === 1
516 516
             ? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon"></div></sup>	'
517 517
             : '';
518 518
         // add group details
519
-        $name_link .= '&nbsp;' . sprintf(
519
+        $name_link .= '&nbsp;'.sprintf(
520 520
             esc_html__('(%s of %s)', 'event_espresso'),
521 521
             $registration->count(),
522 522
             $registration->group_size()
523 523
         );
524 524
         // add regcode
525
-        $link      = EE_Admin_Page::add_query_args_and_nonce(
525
+        $link = EE_Admin_Page::add_query_args_and_nonce(
526 526
             ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
527 527
             REG_ADMIN_URL
528 528
         );
@@ -532,15 +532,15 @@  discard block
 block discarded – undo
532 532
             'view_registration',
533 533
             $registration->ID()
534 534
         )
535
-            ? '<a class="ee-aria-tooltip" href="' . $link . '" aria-label="' . esc_attr__(
535
+            ? '<a class="ee-aria-tooltip" href="'.$link.'" aria-label="'.esc_attr__(
536 536
                 'View Registration Details',
537 537
                 'event_espresso'
538
-            ) . '">'
538
+            ).'">'
539 539
               . $registration->reg_code()
540 540
               . '</a>'
541 541
             : $registration->reg_code();
542 542
 
543
-        $actions                 = [];
543
+        $actions = [];
544 544
         if (
545 545
             $this->datetime_id
546 546
             && EE_Registry::instance()->CAP->current_user_can(
@@ -555,24 +555,24 @@  discard block
 block discarded – undo
555 555
             // get the timestamps for this registration's checkins, related to the selected datetime
556 556
             /** @var EE_Checkin[] $checkins */
557 557
             $checkins = $registration->get_many_related('Checkin', [['DTT_ID' => $this->datetime_id]]);
558
-            if (! empty($checkins)) {
558
+            if ( ! empty($checkins)) {
559 559
                 // get the last timestamp
560 560
                 $last_checkin = end($checkins);
561 561
                 // get timestamp string
562 562
                 $timestamp_string   = $last_checkin->get_datetime('CHK_timestamp');
563 563
                 $actions['checkin'] = '
564 564
                     <a  class="ee-aria-tooltip"
565
-                        href="' . $checkin_list_url . '"
565
+                        href="' . $checkin_list_url.'"
566 566
                         aria-label="' . esc_attr__(
567 567
                             'View this registrant\'s check-ins/checkouts for the datetime',
568 568
                             'event_espresso'
569
-                        ) . '"
569
+                        ).'"
570 570
                     >
571
-                        ' . $last_checkin->getCheckInText() . ': ' . $timestamp_string . '
571
+                        ' . $last_checkin->getCheckInText().': '.$timestamp_string.'
572 572
                     </a>';
573 573
             }
574 574
         }
575
-        $content = (! empty($this->datetime_id) && ! empty($checkins))
575
+        $content = ( ! empty($this->datetime_id) && ! empty($checkins))
576 576
             ? sprintf('%1$s %2$s', $name_link, $this->row_actions($actions, true))
577 577
             : $name_link;
578 578
         return $this->columnContent('ATT_name', $content);
@@ -607,14 +607,14 @@  discard block
 block discarded – undo
607 607
                 ['action' => 'event_registrations', 'event_id' => $event->ID()],
608 608
                 REG_ADMIN_URL
609 609
             );
610
-            $content      = EE_Registry::instance()->CAP->current_user_can(
610
+            $content = EE_Registry::instance()->CAP->current_user_can(
611 611
                 'ee_read_checkins',
612 612
                 'espresso_registrations_registration_checkins'
613
-            ) ? '<a class="ee-aria-tooltip" href="' . $checkin_link_url . '" aria-label="'
613
+            ) ? '<a class="ee-aria-tooltip" href="'.$checkin_link_url.'" aria-label="'
614 614
                 . esc_attr__(
615 615
                     'View Checkins for this Event',
616 616
                     'event_espresso'
617
-                ) . '">' . $event->name() . '</a>' : $event->name();
617
+                ).'">'.$event->name().'</a>' : $event->name();
618 618
         } catch (EntityNotFoundException $e) {
619 619
             $content = esc_html__('Unknown', 'event_espresso');
620 620
         }
Please login to merge, or discard this patch.