Completed
Branch BUG/11288/fix-datepicker (d15367)
by
unknown
108:07 queued 94:31
created

EEH_Template   F

Complexity

Total Complexity 121

Size/Duplication

Total Lines 861
Duplicated Lines 0.46 %

Coupling/Cohesion

Components 2
Dependencies 11

Importance

Changes 0
Metric Value
dl 4
loc 861
rs 3.9999
c 0
b 0
f 0
wmc 121
lcom 2
cbo 11

18 Methods

Rating   Name   Duplication   Size   Complexity  
A is_espresso_theme() 0 4 2
A load_espresso_theme_functions() 0 8 3
B get_espresso_themes() 0 17 5
A get_template_part() 0 17 3
F locate_template() 0 115 22
A _find_common_base_path() 0 17 4
C display_template() 0 49 8
B get_object_css_class() 0 23 5
A format_currency() 0 15 1
A pretty_status() 0 8 1
B get_button_or_link() 0 18 7
D get_help_tab_link() 4 25 10
F help_tour_stops_generator() 0 39 13
B status_legend() 0 30 5
C layout_array_as_table() 0 45 7
A paging_html() 0 12 1
D get_paging_html() 0 118 13
C powered_by_event_espresso() 0 47 11

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like EEH_Template often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EEH_Template, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
use EventEspresso\core\exceptions\InvalidDataTypeException;
4
use EventEspresso\core\exceptions\InvalidInterfaceException;
5
6
if (! defined('EVENT_ESPRESSO_VERSION')) {
7
    exit('NO direct script access allowed');
8
}
9
/**
10
 * Event Espresso
11
 * Event Registration and Management Plugin for WordPress
12
 *
13
 * @package           Event Espresso
14
 * @author            Event Espresso
15
 * @copyright      (c)2009-2012 Event Espresso All Rights Reserved.
16
 * @license           http://eventespresso.com/support/terms-conditions/  ** see Plugin Licensing **
17
 * @link              http://www.eventespresso.com
18
 * @version           4.0
19
 */
20
21
22
if ( ! function_exists('espresso_get_template_part')) {
23
    /**
24
     * espresso_get_template_part
25
     * 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
26
     * so not a very useful function at all except that it adds familiarity PLUS filtering based off of the entire template part name
27
     *
28
     * @param string $slug The slug name for the generic template.
29
     * @param string $name The name of the specialised template.
30
     * @return string        the html output for the formatted money value
31
     */
32
    function espresso_get_template_part($slug = null, $name = null)
33
    {
34
        EEH_Template::get_template_part($slug, $name);
35
    }
36
}
37
38
39
if ( ! function_exists('espresso_get_object_css_class')) {
40
    /**
41
     * espresso_get_object_css_class - attempts to generate a css class based on the type of EE object passed
42
     *
43
     * @param EE_Base_Class $object the EE object the css class is being generated for
44
     * @param  string       $prefix added to the beginning of the generated class
45
     * @param  string       $suffix added to the end of the generated class
46
     * @return string
47
     */
48
    function espresso_get_object_css_class($object = null, $prefix = '', $suffix = '')
49
    {
50
        return EEH_Template::get_object_css_class($object, $prefix, $suffix);
51
    }
52
}
53
54
55
/**
56
 * class EEH_Template
57
 * This is a helper utility class that provides different helpers related to template files.
58
 *
59
 * @package           Event Espresso
60
 * @subpackage        /helpers/EEH_Template.helper.php
61
 * @author            Darren Ethier, Brent Christensen
62
 */
63
class EEH_Template
64
{
65
66
    private static $_espresso_themes = array();
67
68
69
    /**
70
     *    is_espresso_theme - returns TRUE or FALSE on whether the currently active WP theme is an espresso theme
71
     *
72
     * @return boolean
73
     */
74
    public static function is_espresso_theme()
75
    {
76
        return wp_get_theme()->get('TextDomain') == 'event_espresso' ? true : false;
77
    }
78
79
    /**
80
     *    load_espresso_theme_functions - if current theme is an espresso theme, or uses ee theme template parts, then
81
     *    load it's functions.php file ( if not already loaded )
82
     *
83
     * @return void
84
     */
85
    public static function load_espresso_theme_functions()
86
    {
87
        if ( ! defined('EE_THEME_FUNCTIONS_LOADED')) {
88
            if (is_readable(EE_PUBLIC . EE_Config::get_current_theme() . DS . 'functions.php')) {
89
                require_once(EE_PUBLIC . EE_Config::get_current_theme() . DS . 'functions.php');
90
            }
91
        }
92
    }
93
94
95
    /**
96
     *    get_espresso_themes - returns an array of Espresso Child themes located in the /templates/ directory
97
     *
98
     * @return array
99
     */
100
    public static function get_espresso_themes()
101
    {
102
        if (empty(EEH_Template::$_espresso_themes)) {
103
            $espresso_themes = glob(EE_PUBLIC . '*', GLOB_ONLYDIR);
104
            if (empty($espresso_themes)) {
105
                return array();
106
            }
107
            if (($key = array_search('global_assets', $espresso_themes)) !== false) {
108
                unset($espresso_themes[$key]);
109
            }
110
            EEH_Template::$_espresso_themes = array();
111
            foreach ($espresso_themes as $espresso_theme) {
112
                EEH_Template::$_espresso_themes[basename($espresso_theme)] = $espresso_theme;
113
            }
114
        }
115
        return EEH_Template::$_espresso_themes;
116
    }
117
118
119
    /**
120
     * EEH_Template::get_template_part
121
     * basically a copy of the WordPress get_template_part() function but uses EEH_Template::locate_template() instead,
122
     * and doesn't add base versions of files so not a very useful function at all except that it adds familiarity PLUS
123
     * filtering based off of the entire template part name
124
     *
125
     * @param string $slug The slug name for the generic template.
126
     * @param string $name The name of the specialised template.
127
     * @param array  $template_args
128
     * @param bool   $return_string
129
     * @return string        the html output for the formatted money value
130
     */
131
    public static function get_template_part(
132
        $slug = null,
133
        $name = null,
134
        $template_args = array(),
135
        $return_string = false
136
    ) {
137
        do_action("get_template_part_{$slug}-{$name}", $slug, $name);
138
        $templates = array();
139
        $name      = (string)$name;
140
        if ($name != '') {
141
            $templates[] = "{$slug}-{$name}.php";
142
        }
143
        // allow template parts to be turned off via something like: add_filter( 'FHEE__content_espresso_events_tickets_template__display_datetimes', '__return_false' );
144
        if (apply_filters("FHEE__EEH_Template__get_template_part__display__{$slug}_{$name}", true)) {
145
            EEH_Template::locate_template($templates, $template_args, true, $return_string);
146
        }
147
    }
148
149
150
    /**
151
     *    locate_template
152
     *    locate a template file by looking in the following places, in the following order:
153
     *        <server path up to>/wp-content/themes/<current active WordPress theme>/
154
     *        <assumed full absolute server path>
155
     *        <server path up to>/wp-content/uploads/espresso/templates/<current EE theme>/
156
     *        <server path up to>/wp-content/uploads/espresso/templates/
157
     *        <server path up to>/wp-content/plugins/<EE4 folder>/public/<current EE theme>/
158
     *        <server path up to>/wp-content/plugins/<EE4 folder>/core/templates/<current EE theme>/
159
     *        <server path up to>/wp-content/plugins/<EE4 folder>/
160
     *    as soon as the template is found in one of these locations, it will be returned or loaded
161
     *        Example:
162
     *          You are using the WordPress Twenty Sixteen theme,
163
     *        and you want to customize the "some-event.template.php" template,
164
     *          which is located in the "/relative/path/to/" folder relative to the main EE plugin folder.
165
     *          Assuming WP is installed on your server in the "/home/public_html/" folder,
166
     *        EEH_Template::locate_template() will look at the following paths in order until the template is found:
167
     *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
168
     *        /relative/path/to/some-event.template.php
169
     *        /home/public_html/wp-content/uploads/espresso/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
170
     *        /home/public_html/wp-content/uploads/espresso/templates/relative/path/to/some-event.template.php
171
     *        /home/public_html/wp-content/plugins/event-espresso-core-reg/public/Espresso_Arabica_2014/relative/path/to/some-event.template.php
172
     *        /home/public_html/wp-content/plugins/event-espresso-core-reg/core/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
173
     *        /home/public_html/wp-content/plugins/event-espresso-core-reg/relative/path/to/some-event.template.php
174
     *          Had you passed an absolute path to your template that was in some other location,
175
     *        ie: "/absolute/path/to/some-event.template.php"
176
     *          then the search would have been :
177
     *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
178
     *        /absolute/path/to/some-event.template.php
179
     *          and stopped there upon finding it in the second location
180
     *
181
     * @param array|string $templates       array of template file names including extension (or just a single string)
182
     * @param  array       $template_args   an array of arguments to be extracted for use in the template
183
     * @param  boolean     $load            whether to pass the located template path on to the
184
     *                                      EEH_Template::display_template() method or simply return it
185
     * @param  boolean     $return_string   whether to send output immediately to screen, or capture and return as a
186
     *                                      string
187
     * @param boolean      $check_if_custom If TRUE, this flags this method to return boolean for whether this will
188
     *                                      generate a custom template or not. Used in places where you don't actually
189
     *                                      load the template, you just want to know if there's a custom version of it.
190
     * @return mixed
191
     */
192
    public static function locate_template(
193
        $templates = array(),
194
        $template_args = array(),
195
        $load = true,
196
        $return_string = true,
197
        $check_if_custom = false
198
    ) {
199
        // first use WP locate_template to check for template in the current theme folder
200
        $template_path = locate_template($templates);
201
202
        if ($check_if_custom && ! empty($template_path)) {
203
            return true;
204
        }
205
206
        // not in the theme
207
        if (empty($template_path)) {
208
            // not even a template to look for ?
209
            if (empty($templates)) {
210
                // get post_type
211
                $post_type = EE_Registry::instance()->REQ->get('post_type');
212
                // get array of EE Custom Post Types
213
                $EE_CPTs = EE_Register_CPTs::get_CPTs();
214
                // build template name based on request
215
                if (isset($EE_CPTs[$post_type])) {
216
                    $archive_or_single = is_archive() ? 'archive' : '';
217
                    $archive_or_single = is_single() ? 'single' : $archive_or_single;
218
                    $templates         = $archive_or_single . '-' . $post_type . '.php';
219
                }
220
            }
221
            // currently active EE template theme
222
            $current_theme = EE_Config::get_current_theme();
223
224
            // array of paths to folders that may contain templates
225
            $template_folder_paths = array(
226
                // first check the /wp-content/uploads/espresso/templates/(current EE theme)/  folder for an EE theme template file
227
                EVENT_ESPRESSO_TEMPLATE_DIR . $current_theme,
228
                // then in the root of the /wp-content/uploads/espresso/templates/ folder
229
                EVENT_ESPRESSO_TEMPLATE_DIR,
230
            );
231
232
            //add core plugin folders for checking only if we're not $check_if_custom
233
            if ( ! $check_if_custom) {
234
                $core_paths            = array(
235
                    // in the  /wp-content/plugins/(EE4 folder)/public/(current EE theme)/ folder within the plugin
236
                    EE_PUBLIC . $current_theme,
237
                    // in the  /wp-content/plugins/(EE4 folder)/core/templates/(current EE theme)/ folder within the plugin
238
                    EE_TEMPLATES . $current_theme,
239
                    // or maybe relative from the plugin root: /wp-content/plugins/(EE4 folder)/
240
                    EE_PLUGIN_DIR_PATH,
241
                );
242
                $template_folder_paths = array_merge($template_folder_paths, $core_paths);
243
            }
244
245
            // now filter that array
246
            $template_folder_paths = apply_filters('FHEE__EEH_Template__locate_template__template_folder_paths',
247
                $template_folder_paths);
248
            $templates             = is_array($templates) ? $templates : array($templates);
249
            $template_folder_paths = is_array($template_folder_paths) ? $template_folder_paths : array($template_folder_paths);
250
            // array to hold all possible template paths
251
            $full_template_paths = array();
252
253
            // loop through $templates
254
            foreach ($templates as $template) {
255
                // normalize directory separators
256
                $template                      = EEH_File::standardise_directory_separators($template);
257
                $file_name                     = basename($template);
258
                $template_path_minus_file_name = substr($template, 0, (strlen($file_name) * -1));
259
                // while looping through all template folder paths
260
                foreach ($template_folder_paths as $template_folder_path) {
261
                    // normalize directory separators
262
                    $template_folder_path = EEH_File::standardise_directory_separators($template_folder_path);
263
                    // determine if any common base path exists between the two paths
264
                    $common_base_path = EEH_Template::_find_common_base_path(
265
                        array($template_folder_path, $template_path_minus_file_name)
266
                    );
267
                    if ($common_base_path !== '') {
268
                        // both paths have a common base, so just tack the filename onto our search path
269
                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $file_name;
270
                    } else {
271
                        // no common base path, so let's just concatenate
272
                        $resolved_path = EEH_File::end_with_directory_separator($template_folder_path) . $template;
273
                    }
274
                    // build up our template locations array by adding our resolved paths
275
                    $full_template_paths[] = $resolved_path;
276
                }
277
                // if $template is an absolute path, then we'll tack it onto the start of our array so that it gets searched first
278
                array_unshift($full_template_paths, $template);
279
                // path to the directory of the current theme: /wp-content/themes/(current WP theme)/
280
                array_unshift($full_template_paths, get_stylesheet_directory() . DS . $file_name);
281
            }
282
            // filter final array of full template paths
283
            $full_template_paths = apply_filters('FHEE__EEH_Template__locate_template__full_template_paths',
284
                $full_template_paths, $file_name);
285
            // now loop through our final array of template location paths and check each location
286
            foreach ((array)$full_template_paths as $full_template_path) {
287
                if (is_readable($full_template_path)) {
288
                    $template_path = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $full_template_path);
289
                    break;
290
                }
291
            }
292
        }
293
294
        // hook that can be used to display the full template path that will be used
295
        do_action('AHEE__EEH_Template__locate_template__full_template_path', $template_path);
296
297
        // if we got it and you want to see it...
298
        if ($template_path && $load && ! $check_if_custom) {
299
            if ($return_string) {
300
                return EEH_Template::display_template($template_path, $template_args, true);
301
            } else {
302
                EEH_Template::display_template($template_path, $template_args, false);
303
            }
304
        }
305
        return $check_if_custom && ! empty($template_path) ? true : $template_path;
306
    }
307
308
309
    /**
310
     * _find_common_base_path
311
     * given two paths, this determines if there is a common base path between the two
312
     *
313
     * @param array $paths
314
     * @return string
315
     */
316
    protected static function _find_common_base_path($paths)
317
    {
318
        $last_offset      = 0;
319
        $common_base_path = '';
320
        while (($index = strpos($paths[0], DS, $last_offset)) !== false) {
321
            $dir_length = $index - $last_offset + 1;
322
            $directory  = substr($paths[0], $last_offset, $dir_length);
323
            foreach ($paths as $path) {
324
                if (substr($path, $last_offset, $dir_length) != $directory) {
325
                    return $common_base_path;
326
                }
327
            }
328
            $common_base_path .= $directory;
329
            $last_offset = $index + 1;
330
        }
331
        return substr($common_base_path, 0, -1);
332
    }
333
334
335
    /**
336
     * load and display a template
337
     *
338
     * @param bool|string $template_path server path to the file to be loaded, including file name and extension
339
     * @param  array      $template_args an array of arguments to be extracted for use in the template
340
     * @param  boolean    $return_string whether to send output immediately to screen, or capture and return as a string
341
     * @param bool        $throw_exceptions if set to true, will throw an exception if the template is either
342
     *                                      not found or is not readable
343
     * @return mixed string
344
     * @throws \DomainException
345
     */
346
	public static function display_template(
347
        $template_path    = false,
348
        $template_args    = array(),
349
        $return_string    = false,
350
        $throw_exceptions = false
351
    ) {
352
353
        /**
354
         * These two filters are intended for last minute changes to templates being loaded and/or template arg
355
         * modifications.  NOTE... modifying these things can cause breakage as most templates running through
356
         * the display_template method are templates we DON'T want modified (usually because of js
357
         * dependencies etc).  So unless you know what you are doing, do NOT filter templates or template args
358
         * using this.
359
         *
360
         * @since 4.6.0
361
         */
362
        $template_path = (string) apply_filters('FHEE__EEH_Template__display_template__template_path', $template_path);
363
        $template_args = (array) apply_filters('FHEE__EEH_Template__display_template__template_args', $template_args);
364
365
        // you gimme nuttin - YOU GET NUTTIN !!
366
        if ( ! $template_path || ! is_readable($template_path)) {
367
            return '';
368
        }
369
        // if $template_args are not in an array, then make it so
370
        if ( ! is_array($template_args) && ! is_object($template_args)) {
371
            $template_args = array($template_args);
372
        }
373
        extract( $template_args, EXTR_SKIP );
374
        // ignore whether template is accessible ?
375
        if ( $throw_exceptions && ! is_readable( $template_path ) ) {
376
            throw new \DomainException(
377
                    esc_html__(
378
                            'Invalid, unreadable, or missing file.',
379
                            'event_espresso'
380
                    )
381
            );
382
        }
383
384
385
        if ($return_string) {
386
            // because we want to return a string, we are going to capture the output
387
            ob_start();
388
            include($template_path);
389
            return ob_get_clean();
390
        } else {
391
            include($template_path);
392
        }
393
        return '';
394
    }
395
396
397
    /**
398
     * get_object_css_class - attempts to generate a css class based on the type of EE object passed
399
     *
400
     * @param EE_Base_Class $object the EE object the css class is being generated for
401
     * @param  string       $prefix added to the beginning of the generated class
402
     * @param  string       $suffix added to the end of the generated class
403
     * @return string
404
     */
405
    public static function get_object_css_class($object = null, $prefix = '', $suffix = '')
406
    {
407
        // in the beginning...
408
        $prefix = ! empty($prefix) ? rtrim($prefix, '-') . '-' : '';
409
        // da muddle
410
        $class = '';
411
        // the end
412
        $suffix = ! empty($suffix) ? '-' . ltrim($suffix, '-') : '';
413
        // is the passed object an EE object ?
414
        if ($object instanceof EE_Base_Class) {
415
            // grab the exact type of object
416
            $obj_class = get_class($object);
417
            // depending on the type of object...
418
            switch ($obj_class) {
419
                // no specifics just yet...
420
                default :
421
                    $class = strtolower(str_replace('_', '-', $obj_class));
422
                    $class .= method_exists($obj_class, 'name') ? '-' . sanitize_title($object->name()) : '';
423
424
            }
425
        }
426
        return $prefix . $class . $suffix;
427
    }
428
429
430
431
    /**
432
     * EEH_Template::format_currency
433
     * This helper takes a raw float value and formats it according to the default config country currency settings, or
434
     * the country currency settings from the supplied country ISO code
435
     *
436
     * @deprecated $VID:$
437
     * @param  float   $amount       raw money value
438
     * @param  boolean $return_raw   whether to return the formatted float value only with no currency sign or code
439
     * @param  boolean $display_code whether to display the country code (USD). Default = TRUE
440
     * @param string   $CNT_ISO      2 letter ISO code for a country
441
     * @param string   $cur_code_span_class
442
     * @return string        the html output for the formatted money value
443
     * @throws EE_Error
444
     * @throws InvalidArgumentException
445
     * @throws ReflectionException
446
     * @throws InvalidDataTypeException
447
     * @throws InvalidInterfaceException
448
     */
449
    public static function format_currency(
450
        $amount = null,
451
        $return_raw = false,
452
        $display_code = true,
453
        $CNT_ISO = '',
454
        $cur_code_span_class = 'currency-code'
455
    ) {
456
        return EEH_Money::format_currency(
457
            $amount,
458
            $return_raw,
459
            $display_code,
460
            $CNT_ISO,
461
            $cur_code_span_class
462
        );
463
    }
464
465
466
    /**
467
     * This function is used for outputting the localized label for a given status id in the schema requested (and
468
     * possibly plural).  The intended use of this function is only for cases where wanting a label outside of a
469
     * related status model or model object (i.e. in documentation etc.)
470
     *
471
     * @param  string  $status_id Status ID matching a registered status in the esp_status table.  If there is no
472
     *                            match, then 'Unknown' will be returned.
473
     * @param  boolean $plural    Whether to return plural or not
474
     * @param  string  $schema    'UPPER', 'lower', or 'Sentence'
475
     * @return string             The localized label for the status id.
476
     */
477
    public static function pretty_status($status_id, $plural = false, $schema = 'upper')
478
    {
479
        /** @type EEM_Status $EEM_Status */
480
        $EEM_Status = EE_Registry::instance()->load_model('Status');
481
        $status     = $EEM_Status->localized_status(array($status_id => __('unknown', 'event_espresso')), $plural,
482
            $schema);
483
        return $status[$status_id];
484
    }
485
486
487
    /**
488
     * This helper just returns a button or link for the given parameters
489
     *
490
     * @param  string $url   the url for the link, note that `esc_url` will be called on it
491
     * @param  string $label What is the label you want displayed for the button
492
     * @param  string $class what class is used for the button (defaults to 'button-primary')
493
     * @param string  $icon
494
     * @param string  $title
495
     * @return string the html output for the button
496
     */
497
    public static function get_button_or_link($url, $label, $class = 'button-primary', $icon = '', $title = '')
498
    {
499
        $icon_html = '';
500
        if ( ! empty($icon)) {
501
            $dashicons = preg_split("(ee-icon |dashicons )", $icon);
502
            $dashicons = array_filter($dashicons);
503
            $count     = count($dashicons);
504
            $icon_html .= $count > 1 ? '<span class="ee-composite-dashicon">' : '';
505
            foreach ($dashicons as $dashicon) {
506
                $type = strpos($dashicon, 'ee-icon') !== false ? 'ee-icon ' : 'dashicons ';
507
                $icon_html .= '<span class="' . $type . $dashicon . '"></span>';
508
            }
509
            $icon_html .= $count > 1 ? '</span>' : '';
510
        }
511
        $label  = ! empty($icon) ? $icon_html . $label : $label;
512
        $button = '<a id="' . sanitize_title_with_dashes($label) . '" href="' . esc_url($url) . '" class="' . $class . '" title="' . $title . '">' . $label . '</a>';
513
        return $button;
514
    }
515
516
517
    /**
518
     * This returns a generated link that will load the related help tab on admin pages.
519
     *
520
     * @param  string     $help_tab_id the id for the connected help tab
521
     * @param bool|string $page        The page identifier for the page the help tab is on
522
     * @param bool|string $action      The action (route) for the admin page the help tab is on.
523
     * @param bool|string $icon_style  (optional) include css class for the style you want to use for the help icon.
524
     * @param bool|string $help_text   (optional) send help text you want to use for the link if default not to be used
525
     * @return string              generated link
526
     */
527
    public static function get_help_tab_link(
528
        $help_tab_id,
529
        $page = false,
530
        $action = false,
531
        $icon_style = false,
532
        $help_text = false
533
    ) {
534
535 View Code Duplication
        if ( ! $page) {
536
            $page = isset($_REQUEST['page']) && ! empty($_REQUEST['page']) ? sanitize_key($_REQUEST['page']) : $page;
537
        }
538
539 View Code Duplication
        if ( ! $action) {
540
            $action = isset($_REQUEST['action']) && ! empty($_REQUEST['action']) ? sanitize_key($_REQUEST['action']) : $action;
541
        }
542
543
        $action = empty($action) ? 'default' : $action;
544
545
546
        $help_tab_lnk = $page . '-' . $action . '-' . $help_tab_id;
547
        $icon         = ! $icon_style ? ' dashicons-editor-help' : $icon_style;
548
        $help_text    = ! $help_text ? '' : $help_text;
549
        return '<a id="' . $help_tab_lnk . '" class="ee-clickable dashicons espresso-help-tab-lnk ee-icon-size-22' . $icon . '" title="' . esc_attr__('Click to open the \'Help\' tab for more information about this feature.',
550
                'event_espresso') . '" > ' . $help_text . ' </a>';
551
    }
552
553
554
    /**
555
     * This helper generates the html structure for the jquery joyride plugin with the given params.
556
     *
557
     * @link http://zurb.com/playground/jquery-joyride-feature-tour-plugin
558
     * @see  EE_Admin_Page->_stop_callback() for the construct expected for the $stops param.
559
     * @param EE_Help_Tour
560
     * @return string         html
561
     */
562
    public static function help_tour_stops_generator(EE_Help_Tour $tour)
563
    {
564
        $id    = $tour->get_slug();
565
        $stops = $tour->get_stops();
566
567
        $content = '<ol style="display:none" id="' . $id . '">';
568
569
        foreach ($stops as $stop) {
570
            $data_id    = ! empty($stop['id']) ? ' data-id="' . $stop['id'] . '"' : '';
571
            $data_class = empty($data_id) && ! empty($stop['class']) ? ' data-class="' . $stop['class'] . '"' : '';
572
573
            //if container is set to modal then let's make sure we set the options accordingly
574
            if (empty($data_id) && empty($data_class)) {
575
                $stop['options']['modal']  = true;
576
                $stop['options']['expose'] = true;
577
            }
578
579
            $custom_class  = ! empty($stop['custom_class']) ? ' class="' . $stop['custom_class'] . '"' : '';
580
            $button_text   = ! empty($stop['button_text']) ? ' data-button="' . $stop['button_text'] . '"' : '';
581
            $inner_content = isset($stop['content']) ? $stop['content'] : '';
582
583
            //options
584
            if (isset($stop['options']) && is_array($stop['options'])) {
585
                $options = ' data-options="';
586
                foreach ($stop['options'] as $option => $value) {
587
                    $options .= $option . ':' . $value . ';';
588
                }
589
                $options .= '"';
590
            } else {
591
                $options = '';
592
            }
593
594
            //let's put all together
595
            $content .= '<li' . $data_id . $data_class . $custom_class . $button_text . $options . '>' . $inner_content . '</li>';
596
        }
597
598
        $content .= '</ol>';
599
        return $content;
600
    }
601
602
603
    /**
604
     * This is a helper method to generate a status legend for a given status array.
605
     * Note this will only work if the incoming statuses have a key in the EEM_Status->localized_status() methods
606
     * status_array.
607
     *
608
     * @param  array  $status_array  array of statuses that will make up the legend. In format:
609
     *                               array(
610
     *                               'status_item' => 'status_name'
611
     *                               )
612
     * @param  string $active_status This is used to indicate what the active status is IF that is to be highlighted in
613
     *                               the legend.
614
     * @throws EE_Error
615
     * @return string               html structure for status.
616
     */
617
    public static function status_legend($status_array, $active_status = '')
618
    {
619
        if ( ! is_array($status_array)) {
620
            throw new EE_Error(esc_html__('The EEH_Template::status_legend helper required the incoming status_array argument to be an array!',
621
                'event_espresso'));
622
        }
623
624
        $setup_array = array();
625
        foreach ($status_array as $item => $status) {
626
            $setup_array[$item] = array(
627
                'class'  => 'ee-status-legend ee-status-legend-' . $status,
628
                'desc'   => EEH_Template::pretty_status($status, false, 'sentence'),
629
                'status' => $status,
630
            );
631
        }
632
633
        $content = '<div class="ee-list-table-legend-container">' . "\n";
634
        $content .= '<h4 class="status-legend-title">' . esc_html__('Status Legend', 'event_espresso') . '</h4>' . "\n";
635
        $content .= '<dl class="ee-list-table-legend">' . "\n\t";
636
        foreach ($setup_array as $item => $details) {
637
            $active_class = $active_status == $details['status'] ? ' class="ee-is-active-status"' : '';
638
            $content .= '<dt id="ee-legend-item-tooltip-' . $item . '"' . $active_class . '>' . "\n\t\t";
639
            $content .= '<span class="' . $details['class'] . '"></span>' . "\n\t\t";
640
            $content .= '<span class="ee-legend-description">' . $details['desc'] . '</span>' . "\n\t";
641
            $content .= '</dt>' . "\n";
642
        }
643
        $content .= '</dl>' . "\n";
644
        $content .= '</div>' . "\n";
645
        return $content;
646
    }
647
648
649
    /**
650
     * Gets HTML for laying out a deeply-nested array (and objects) in a format
651
     * that's nice for presenting in the wp admin
652
     *
653
     * @param mixed $data
654
     * @return string
655
     */
656
    public static function layout_array_as_table($data)
657
    {
658
        if (is_object($data) || $data instanceof __PHP_Incomplete_Class) {
659
            $data = (array)$data;
660
        }
661
        ob_start();
662
        if (is_array($data)) {
663
            if (EEH_Array::is_associative_array($data)) {
664
                ?>
665
                <table class="widefat">
666
                    <tbody>
667
                    <?php
668
                    foreach ($data as $data_key => $data_values) {
669
                        ?>
670
                        <tr>
671
                            <td>
672
                                <?php echo $data_key; ?>
673
                            </td>
674
                            <td>
675
                                <?php echo self::layout_array_as_table($data_values); ?>
676
                            </td>
677
                        </tr>
678
                        <?php
679
                    } ?>
680
                    </tbody>
681
                </table>
682
                <?php
683
            } else {
684
                ?>
685
                <ul>
686
                    <?php
687
                    foreach ($data as $datum) {
688
                        echo "<li>";
689
                        echo self::layout_array_as_table($datum);
690
                        echo "</li>";
691
                    } ?>
692
                </ul>
693
                <?php
694
            }
695
        } else {
696
            //simple value
697
            echo esc_html($data);
698
        }
699
        return ob_get_clean();
700
    }
701
702
703
    /**
704
     * wrapper for self::get_paging_html() that simply echos the generated paging html
705
     *
706
     * @since 4.4.0
707
     * @see   self:get_paging_html() for argument docs.
708
     * @param        $total_items
709
     * @param        $current
710
     * @param        $per_page
711
     * @param        $url
712
     * @param bool   $show_num_field
713
     * @param string $paged_arg_name
714
     * @param array  $items_label
715
     * @return string
716
     */
717
    public static function paging_html(
718
        $total_items,
719
        $current,
720
        $per_page,
721
        $url,
722
        $show_num_field = true,
723
        $paged_arg_name = 'paged',
724
        $items_label = array()
725
    ) {
726
        echo self::get_paging_html($total_items, $current, $per_page, $url, $show_num_field, $paged_arg_name,
727
            $items_label);
728
    }
729
730
731
    /**
732
     * A method for generating paging similar to WP_List_Table
733
     *
734
     * @since    4.4.0
735
     * @see      wp-admin/includes/class-wp-list-table.php WP_List_Table::pagination()
736
     * @param  integer $total_items     How many total items there are to page.
737
     * @param  integer $current         What the current page is.
738
     * @param  integer $per_page        How many items per page.
739
     * @param  string  $url             What the base url for page links is.
740
     * @param  boolean $show_num_field  Whether to show the input for changing page number.
741
     * @param  string  $paged_arg_name  The name of the key for the paged query argument.
742
     * @param  array   $items_label     An array of singular/plural values for the items label:
743
     *                                  array(
744
     *                                  'single' => 'item',
745
     *                                  'plural' => 'items'
746
     *                                  )
747
     * @return  string
748
     */
749
    public static function get_paging_html(
750
        $total_items,
751
        $current,
752
        $per_page,
753
        $url,
754
        $show_num_field = true,
755
        $paged_arg_name = 'paged',
756
        $items_label = array()
757
    ) {
758
        $page_links     = array();
759
        $disable_first  = $disable_last = '';
760
        $total_items    = (int)$total_items;
761
        $per_page       = (int)$per_page;
762
        $current        = (int)$current;
763
        $paged_arg_name = empty($paged_arg_name) ? 'paged' : sanitize_key($paged_arg_name);
764
765
        //filter items_label
766
        $items_label = apply_filters(
767
            'FHEE__EEH_Template__get_paging_html__items_label',
768
            $items_label
769
        );
770
771
        if (empty($items_label)
772
            || ! is_array($items_label)
773
            || ! isset($items_label['single'])
774
            || ! isset($items_label['plural'])
775
        ) {
776
            $items_label = array(
777
                'single' => __('1 item', 'event_espresso'),
778
                'plural' => __('%s items', 'event_espresso'),
779
            );
780
        } else {
781
            $items_label = array(
782
                'single' => '1 ' . esc_html($items_label['single']),
783
                'plural' => '%s ' . esc_html($items_label['plural']),
784
            );
785
        }
786
787
        $total_pages = ceil($total_items / $per_page);
788
789
        if ($total_pages <= 1) {
790
            return '';
791
        }
792
793
        $item_label = $total_items > 1 ? sprintf($items_label['plural'], $total_items) : $items_label['single'];
794
795
        $output = '<span class="displaying-num">' . $item_label . '</span>';
796
797
        if ($current === 1) {
798
            $disable_first = ' disabled';
799
        }
800
        if ($current == $total_pages) {
801
            $disable_last = ' disabled';
802
        }
803
804
        $page_links[] = sprintf("<a class='%s' title='%s' href='%s'>%s</a>",
805
            'first-page' . $disable_first,
806
            esc_attr__('Go to the first page'),
807
            esc_url(remove_query_arg($paged_arg_name, $url)),
808
            '&laquo;'
809
        );
810
811
        $page_links[] = sprintf(
812
            '<a class="%s" title="%s" href="%s">%s</a>',
813
            'prev-page' . $disable_first,
814
            esc_attr__('Go to the previous page'),
815
            esc_url(add_query_arg($paged_arg_name, max(1, $current - 1), $url)),
816
            '&lsaquo;'
817
        );
818
819
        if ( ! $show_num_field) {
820
            $html_current_page = $current;
821
        } else {
822
            $html_current_page = sprintf("<input class='current-page' title='%s' type='text' name=$paged_arg_name value='%s' size='%d' />",
823
                esc_attr__('Current page'),
824
                $current,
825
                strlen($total_pages)
826
            );
827
        }
828
829
        $html_total_pages = sprintf(
830
            '<span class="total-pages">%s</span>',
831
            number_format_i18n($total_pages)
832
        );
833
        $page_links[]     = sprintf(
834
            _x('%3$s%1$s of %2$s%4$s', 'paging'),
835
            $html_current_page,
836
            $html_total_pages,
837
            '<span class="paging-input">',
838
            '</span>'
839
        );
840
841
        $page_links[] = sprintf(
842
            '<a class="%s" title="%s" href="%s">%s</a>',
843
            'next-page' . $disable_last,
844
            esc_attr__('Go to the next page'),
845
            esc_url(add_query_arg($paged_arg_name, min($total_pages, $current + 1), $url)),
846
            '&rsaquo;'
847
        );
848
849
        $page_links[] = sprintf(
850
            '<a class="%s" title="%s" href="%s">%s</a>',
851
            'last-page' . $disable_last,
852
            esc_attr__('Go to the last page'),
853
            esc_url(add_query_arg($paged_arg_name, $total_pages, $url)),
854
            '&raquo;'
855
        );
856
857
        $output .= "\n" . '<span class="pagination-links">' . join("\n", $page_links) . '</span>';
858
        // set page class
859
        if ($total_pages) {
860
            $page_class = $total_pages < 2 ? ' one-page' : '';
861
        } else {
862
            $page_class = ' no-pages';
863
        }
864
865
        return '<div class="tablenav"><div class="tablenav-pages' . $page_class . '">' . $output . '</div></div>';
866
    }
867
868
869
    /**
870
     * @param string $wrap_class
871
     * @param string $wrap_id
872
     * @return string
873
     */
874
    public static function powered_by_event_espresso($wrap_class = '', $wrap_id = '', array $query_args = array())
875
    {
876
        $admin = is_admin() && ! (defined('DOING_AJAX') && DOING_AJAX);
877
        if (
878
            ! $admin &&
879
            ! apply_filters(
880
                'FHEE__EEH_Template__powered_by_event_espresso__show_reg_footer',
881
                EE_Registry::instance()->CFG->admin->show_reg_footer
882
            )
883
        ) {
884
            return '';
885
        }
886
        $tag        = $admin ? 'span' : 'div';
887
        $attributes = ! empty($wrap_id) ? " id=\"{$wrap_id}\"" : '';
888
        $wrap_class = $admin ? "{$wrap_class} float-left" : $wrap_class;
889
        $attributes .= ! empty($wrap_class)
890
            ? " class=\"{$wrap_class} powered-by-event-espresso-credit\""
891
            : ' class="powered-by-event-espresso-credit"';
892
        $query_args = array_merge(
893
            array(
894
                'ap_id'        => EE_Registry::instance()->CFG->admin->affiliate_id(),
895
                'utm_source'   => 'powered_by_event_espresso',
896
                'utm_medium'   => 'link',
897
                'utm_campaign' => 'powered_by',
898
            ),
899
            $query_args
900
        );
901
        $powered_by = apply_filters('FHEE__EEH_Template__powered_by_event_espresso_text',
902
            $admin ? 'Event Espresso - ' . EVENT_ESPRESSO_VERSION : 'Event Espresso');
903
        $url        = add_query_arg($query_args, 'https://eventespresso.com/');
904
        $url        = apply_filters('FHEE__EEH_Template__powered_by_event_espresso__url', $url);
905
        return (string)apply_filters(
906
            'FHEE__EEH_Template__powered_by_event_espresso__html',
907
            sprintf(
908
                esc_html_x(
909
                    '%3$s%1$sOnline event registration and ticketing powered by %2$s%3$s',
910
                    'Online event registration and ticketing powered by [link to eventespresso.com]',
911
                    'event_espresso'
912
                ),
913
                "<{$tag}{$attributes}>",
914
                "<a href=\"{$url}\" target=\"_blank\" rel=\"nofollow\">{$powered_by}</a></{$tag}>",
915
                $admin ? '' : '<br />'
916
            ),
917
            $wrap_class,
918
            $wrap_id
919
        );
920
    }
921
922
923
} //end EEH_Template class
924
925
926
927
928 View Code Duplication
if ( ! function_exists('espresso_pagination')) {
929
    /**
930
     *    espresso_pagination
931
     *
932
     * @access    public
933
     * @return    void
934
     */
935
    function espresso_pagination()
936
    {
937
        global $wp_query;
938
        $big        = 999999999; // need an unlikely integer
939
        $pagination = paginate_links(
940
            array(
941
                'base'         => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
942
                'format'       => '?paged=%#%',
943
                'current'      => max(1, get_query_var('paged')),
944
                'total'        => $wp_query->max_num_pages,
945
                'show_all'     => true,
946
                'end_size'     => 10,
947
                'mid_size'     => 6,
948
                'prev_next'    => true,
949
                'prev_text'    => __('&lsaquo; PREV', 'event_espresso'),
950
                'next_text'    => __('NEXT &rsaquo;', 'event_espresso'),
951
                'type'         => 'plain',
952
                'add_args'     => false,
953
                'add_fragment' => '',
954
            )
955
        );
956
        echo ! empty($pagination) ? '<div class="ee-pagination-dv ee-clear-float">' . $pagination . '</div>' : '';
957
    }
958
}
959