Completed
Branch BUG-8957-add-countries (d46858)
by
unknown
31:05 queued 15:34
created

EEH_Template::pretty_status()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 3
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
if ( ! defined('EVENT_ESPRESSO_VERSION')) { exit('NO direct script access allowed'); }
3
/**
4
 * Event Espresso
5
 *
6
 * Event Registration and Management Plugin for WordPress
7
 *
8
 * @package     Event Espresso
9
 * @author      Event Espresso
10
 * @copyright	  (c)2009-2012 Event Espresso All Rights Reserved.
11
 * @license     http://eventespresso.com/support/terms-conditions/  ** see Plugin Licensing **
12
 * @link        http://www.eventespresso.com
13
 * @version		4.0
14
 */
15
16
17
18
if ( ! function_exists( 'espresso_get_template_part' )) {
19
	/**
20
	 * espresso_get_template_part
21
	 * basically a copy of the WordPress get_template_part() function but uses EEH_Template::locate_template() instead, and doesn't add base versions of files
22
	 * so not a very useful function at all except that it adds familiarity PLUS filtering based off of the entire template part name
23
	 *
24
	 * @param string $slug The slug name for the generic template.
25
	 * @param string $name The name of the specialised template.
26
	 * @return string        the html output for the formatted money value
27
	 */
28
	function espresso_get_template_part( $slug = NULL, $name = NULL ) {
29
		EEH_Template::get_template_part( $slug, $name );
30
	}
31
}
32
33
34
35
if ( ! function_exists( 'espresso_get_object_css_class' )) {
36
	/**
37
	 * espresso_get_object_css_class - attempts to generate a css class based on the type of EE object passed
38
	 *
39
	 *
40
	 * @param EE_Base_Class $object the EE object the css class is being generated for
41
	 * @param  string $prefix added to the beginning of the generated class
42
	 * @param  string $suffix added to the end of the generated class
43
	 * @return string
44
	 */
45
	function espresso_get_object_css_class( $object = NULL, $prefix = '', $suffix = '' ) {
46
		return EEH_Template::get_object_css_class( $object, $prefix, $suffix );
47
	}
48
}
49
50
51
52
/**
53
 * class EEH_Template
54
 *
55
 * This is a helper utility class that provides different helpers related to template files.
56
 *
57
 * @package		Event Espresso
58
 * @subpackage	/helpers/EEH_Template.helper.php
59
 * @author		    Darren Ethier, Brent Christensen
60
 *
61
 */
62
class EEH_Template {
63
64
	private static $_espresso_themes = array();
65
66
67
	/**
68
	 * 	is_espresso_theme - returns TRUE or FALSE on whether the currently active WP theme is an espresso theme
69
	 *
70
	 * 	@return boolean
71
	 */
72
	public static function is_espresso_theme() {
73
		return wp_get_theme()->get( 'TextDomain' ) == 'event_espresso' ? TRUE : FALSE;
74
	}
75
76
	/**
77
	 * 	load_espresso_theme_functions - if current theme is an espresso theme, or uses ee theme template parts, then load it's functions.php file ( if not already loaded )
78
	 *
79
	 * 	@return void
80
	 */
81
	public static function load_espresso_theme_functions() {
82
		if ( ! defined( 'EE_THEME_FUNCTIONS_LOADED' )) {
83
			if ( is_readable( EE_PUBLIC . EE_Config::get_current_theme() . DS . 'functions.php' )) {
84
				require_once( EE_PUBLIC . EE_Config::get_current_theme() . DS . 'functions.php' );
85
			}
86
		}
87
	}
88
89
90
	/**
91
	 * 	get_espresso_themes - returns an array of Espresso Child themes located in the /templates/ directory
92
	 *
93
	 * 	@return array
94
	 */
95
	public static function get_espresso_themes() {
96
		if ( empty( EEH_Template::$_espresso_themes )) {
97
			$espresso_themes =  glob( EE_PUBLIC . '*', GLOB_ONLYDIR );
98
			if ( empty( $espresso_themes ) ) {
99
				return array();
100
			}
101
			if (( $key = array_search( 'global_assets', $espresso_themes )) !== FALSE ) {
102
			    unset( $espresso_themes[ $key ] );
103
			}
104
			EEH_Template::$_espresso_themes = array();
105
			foreach ( $espresso_themes as $espresso_theme ) {
106
				EEH_Template::$_espresso_themes[ basename( $espresso_theme ) ] = $espresso_theme;
107
			}
108
		}
109
		return EEH_Template::$_espresso_themes;
110
	}
111
112
113
114
	/**
115
	 * EEH_Template::get_template_part
116
	 * 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
117
	 * so not a very useful function at all except that it adds familiarity PLUS filtering based off of the entire template part name
118
	 *
119
	 * @param string $slug The slug name for the generic template.
120
	 * @param string $name The name of the specialised template.
121
	 * @param array  $template_args
122
	 * @param bool   $return_string
123
	 * @return string        the html output for the formatted money value
124
	 */
125
	public static function get_template_part( $slug = NULL, $name = NULL, $template_args = array(), $return_string = FALSE  ) {
126
		do_action( "get_template_part_{$slug}-{$name}", $slug, $name );
127
		$templates = array();
128
		$name = (string) $name;
129
		if ( $name != '' ) {
130
			$templates[] = "{$slug}-{$name}.php";
131
		}
132
		// allow template parts to be turned off via something like: 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
			EEH_Template::locate_template( $templates, $template_args, TRUE, $return_string );
135
		}
136
	}
137
138
139
140
	/**
141
	 *    locate_template
142
	 *
143
	 *    locate a template file by looking in the following places, in the following order:
144
	 *        <server path up to>/wp-content/themes/<current active WordPress theme>/
145
	 *        <assumed full absolute server path>
146
	 *        <server path up to>/wp-content/uploads/espresso/templates/<current EE theme>/
147
	 *        <server path up to>/wp-content/uploads/espresso/templates/
148
	 *        <server path up to>/wp-content/plugins/<EE4 folder>/public/<current EE theme>/
149
	 *        <server path up to>/wp-content/plugins/<EE4 folder>/core/templates/<current EE theme>/
150
	 *        <server path up to>/wp-content/plugins/<EE4 folder>/
151
	 *    as soon as the template is found in one of these locations, it will be returned or loaded
152
	 *
153
	 * 		Example:
154
	 * 		  You are using the WordPress Twenty Sixteen theme,
155
	 *        and you want to customize the "some-event.template.php" template,
156
	 * 		  which is located in the "/relative/path/to/" folder relative to the main EE plugin folder.
157
	 * 		  Assuming WP is installed on your server in the "/home/public_html/" folder,
158
	 *        EEH_Template::locate_template() will look at the following paths in order until the template is found:
159
	 *
160
	 *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
161
	 *        /relative/path/to/some-event.template.php
162
	 *        /home/public_html/wp-content/uploads/espresso/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
163
	 *        /home/public_html/wp-content/uploads/espresso/templates/relative/path/to/some-event.template.php
164
	 *        /home/public_html/wp-content/plugins/event-espresso-core-reg/public/Espresso_Arabica_2014/relative/path/to/some-event.template.php
165
	 *        /home/public_html/wp-content/plugins/event-espresso-core-reg/core/templates/Espresso_Arabica_2014/relative/path/to/some-event.template.php
166
	 *        /home/public_html/wp-content/plugins/event-espresso-core-reg/relative/path/to/some-event.template.php
167
	 *
168
	 * 		  Had you passed an absolute path to your template that was in some other location,
169
	 *        ie: "/absolute/path/to/some-event.template.php"
170
	 * 		  then the search would have been :
171
	 *
172
	 *        /home/public_html/wp-content/themes/twentysixteen/some-event.template.php
173
	 *        /absolute/path/to/some-event.template.php
174
	 *
175
	 * 		  and stopped there upon finding it in the second location
176
	 *
177
	 * @param array|string $templates array of template file names including extension (or just a single string)
178
	 * @param  array   $template_args an array of arguments to be extracted for use in the template
179
	 * @param  boolean $load          whether to pass the located template path on to the EEH_Template::display_template() method or simply return it
180
	 * @param  boolean $return_string whether to send output immediately to screen, or capture and return as a string
181
	 * @param boolean $check_if_custom If TRUE, this flags this method to return boolean for whether this will generate a custom template or not.
182
	 * 				Used in places where you don't actually load the template, you just want to know if there's a custom version of it.
183
	 * @return mixed
184
	 */
185
	public static function locate_template( $templates = array(), $template_args = array(), $load = TRUE, $return_string = TRUE, $check_if_custom = FALSE ) {
186
		// first use WP locate_template to check for template in the current theme folder
187
		$template_path = locate_template( $templates );
188
189
		if ( $check_if_custom && !empty( $template_path ) )
190
			return TRUE;
191
192
		// not in the theme
193
		if ( empty( $template_path )) {
194
			// not even a template to look for ?
195
			if ( empty( $templates )) {
196
				// get post_type
197
				$post_type = EE_Registry::instance()->REQ->get( 'post_type' );
198
				// get array of EE Custom Post Types
199
				$EE_CPTs = EE_Register_CPTs::get_CPTs();
200
				// build template name based on request
201
				if ( isset( $EE_CPTs[ $post_type ] )) {
202
					$archive_or_single =  is_archive() ? 'archive' : '';
203
					$archive_or_single =  is_single() ? 'single' : $archive_or_single;
204
					$templates = $archive_or_single . '-' . $post_type . '.php';
205
				}
206
			}
207
			// currently active EE template theme
208
			$current_theme = EE_Config::get_current_theme();
209
210
			// array of paths to folders that may contain templates
211
			$template_folder_paths = array(
212
				// first check the /wp-content/uploads/espresso/templates/(current EE theme)/  folder for an EE theme template file
213
				EVENT_ESPRESSO_TEMPLATE_DIR . $current_theme,
214
				// then in the root of the /wp-content/uploads/espresso/templates/ folder
215
				EVENT_ESPRESSO_TEMPLATE_DIR
216
			);
217
218
			//add core plugin folders for checking only if we're not $check_if_custom
219
			if ( ! $check_if_custom ) {
220
				$core_paths = array(
221
					// in the  /wp-content/plugins/(EE4 folder)/public/(current EE theme)/ folder within the plugin
222
					EE_PUBLIC . $current_theme,
223
					// in the  /wp-content/plugins/(EE4 folder)/core/templates/(current EE theme)/ folder within the plugin
224
					EE_TEMPLATES . $current_theme,
225
					// or maybe relative from the plugin root: /wp-content/plugins/(EE4 folder)/
226
					EE_PLUGIN_DIR_PATH
227
					);
228
				$template_folder_paths = array_merge( $template_folder_paths, $core_paths );
229
			}
230
231
			// now filter that array
232
			$template_folder_paths = apply_filters( 'FHEE__EEH_Template__locate_template__template_folder_paths', $template_folder_paths );
233
			$templates = is_array( $templates ) ? $templates : array( $templates );
234
			$template_folder_paths = is_array( $template_folder_paths ) ? $template_folder_paths : array( $template_folder_paths );
235
			// array to hold all possible template paths
236
			$full_template_paths = array();
237
238
			// loop through $templates
239
			foreach ( $templates as $template ) {
240
				// normalize directory separators
241
				$template = EEH_File::standardise_directory_separators( $template );
242
				$file_name = basename( $template );
243
				$template_path_minus_file_name = substr( $template, 0, ( strlen( $file_name ) * -1 ) );
244
				// while looping through all template folder paths
245
				foreach ( $template_folder_paths as $template_folder_path ) {
246
					// normalize directory separators
247
					$template_folder_path = EEH_File::standardise_directory_separators( $template_folder_path );
248
					// determine if any common base path exists between the two paths
249
					$common_base_path = EEH_Template::_find_common_base_path(
250
						array( $template_folder_path, $template_path_minus_file_name )
251
					);
252
					if ( $common_base_path !== '' ) {
253
						// both paths have a common base, so just tack the filename onto our search path
254
						$resolved_path = EEH_File::end_with_directory_separator( $template_folder_path ) . $file_name;
255
					} else {
256
						// no common base path, so let's just concatenate
257
						$resolved_path = EEH_File::end_with_directory_separator( $template_folder_path ) . $template;
258
					}
259
					// build up our template locations array by adding our resolved paths
260
					$full_template_paths[] = $resolved_path;
261
				}
262
				// if $template is an absolute path, then we'll tack it onto the start of our array so that it gets searched first
263
				array_unshift( $full_template_paths, $template );
264
				// path to the directory of the current theme: /wp-content/themes/(current WP theme)/
265
				array_unshift( $full_template_paths, get_stylesheet_directory() . DS . $file_name );
266
			}
267
			// filter final array of full template paths
268
			$full_template_paths = apply_filters( 'FHEE__EEH_Template__locate_template__full_template_paths', $full_template_paths, $file_name );
0 ignored issues
show
Bug introduced by
The variable $file_name does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
269
			// now loop through our final array of template location paths and check each location
270
			foreach ( (array)$full_template_paths as $full_template_path ) {
271
				if ( is_readable( $full_template_path )) {
272
					$template_path = str_replace( array( '\\', '/' ), DIRECTORY_SEPARATOR, $full_template_path );
273
					// hook that can be used to display the full template path that will be used
274
					do_action( 'AHEE__EEH_Template__locate_template__full_template_path', $template_path );
275
					break;
276
				}
277
			}
278
		}
279
		// if we got it and you want to see it...
280
		if ( $template_path && $load && ! $check_if_custom  ) {
281
			if ( $return_string ) {
282
				return EEH_Template::display_template( $template_path, $template_args, TRUE );
283
			} else {
284
				EEH_Template::display_template( $template_path, $template_args, FALSE );
285
			}
286
		}
287
		return $check_if_custom && ! empty( $template_path ) ? TRUE : $template_path;
288
	}
289
290
291
292
	/**
293
	 * _find_common_base_path
294
	 *
295
	 * given two paths, this determines if there is a common base path between the two
296
	 *
297
	 * @param array $paths
298
	 * @return string
299
	 */
300
	protected static function _find_common_base_path( $paths ) {
301
		$last_offset = 0;
302
		$common_base_path = '';
303
		while ( ( $index = strpos( $paths[ 0 ], DS, $last_offset ) ) !== false ) {
304
			$dir_length = $index - $last_offset + 1;
305
			$directory = substr( $paths[ 0 ], $last_offset, $dir_length );
306
			foreach ( $paths as $path ) {
307
				if ( substr( $path, $last_offset, $dir_length ) != $directory ) {
308
					return $common_base_path;
309
				}
310
			}
311
			$common_base_path .= $directory;
312
			$last_offset = $index + 1;
313
		}
314
		return substr( $common_base_path, 0, -1 );
315
	}
316
317
318
319
	/**
320
	 * load and display a template
321
	 * @param bool|string $template_path server path to the file to be loaded, including file name and extension
322
	 * @param  array      $template_args an array of arguments to be extracted for use in the template
323
	 * @param  boolean    $return_string whether to send output immediately to screen, or capture and return as a string
324
	 * @return mixed string
325
	 */
326
	public static function display_template( $template_path = FALSE, $template_args = array(), $return_string = FALSE ) {
327
328
		/**
329
		 * These two filters are intended for last minute changes to templates being loaded and/or template arg
330
		 * modifications.  NOTE... modifying these things can cause breakage as most templates running through
331
		 * the display_template method are templates we DON'T want modified (usually because of js
332
		 * dependencies etc).  So unless you know what you are doing, do NOT filter templates or template args
333
		 * using this.
334
		 *
335
		 * @since 4.6.0
336
		 */
337
		$template_path = apply_filters( 'FHEE__EEH_Template__display_template__template_path', $template_path );
338
		$template_args = apply_filters( 'FHEE__EEH_Template__display_template__template_args', $template_args );
339
340
		// you gimme nuttin - YOU GET NUTTIN !!
341
		if ( ! $template_path || ! is_readable( $template_path )) {
342
			return '';
343
		}
344
		// if $template_args are not in an array, then make it so
345
		if ( ! is_array( $template_args ) && ! is_object( $template_args )) {
346
			$template_args = array( $template_args );
347
		}
348
		extract( (array) $template_args);
349
350
		if ( $return_string ) {
351
			// because we want to return a string, we are going to capture the output
352
			ob_start();
353
			include( $template_path );
354
			return ob_get_clean();
355
		} else {
356
			include( $template_path );
357
		}
358
		return '';
359
	}
360
361
362
363
364
365
	/**
366
	 * get_object_css_class - attempts to generate a css class based on the type of EE object passed
367
	 *
368
	 *
369
	 * @param EE_Base_Class $object the EE object the css class is being generated for
370
	 * @param  string $prefix added to the beginning of the generated class
371
	 * @param  string $suffix added to the end of the generated class
372
	 * @return string
373
	 */
374
	public static function get_object_css_class( $object = NULL, $prefix = '', $suffix = '' ) {
375
		// in the beginning...
376
		$prefix = ! empty( $prefix ) ? rtrim( $prefix, '-' ) . '-' : '';
377
		// da muddle
378
		$class = '';
379
		// the end
380
		$suffix = ! empty( $suffix ) ? '-' . ltrim( $suffix, '-' ) : '';
381
		// is the passed object an EE object ?
382
		if ( $object instanceof EE_Base_Class ) {
383
			// grab the exact type of object
384
			$obj_class = get_class( $object );
385
			// depending on the type of object...
386
			switch ( $obj_class ) {
387
				// no specifics just yet...
388
				default :
0 ignored issues
show
Unused Code introduced by
// no specifics just yet...($object->name()) : ''; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
389
					$class = strtolower( str_replace( '_', '-', $obj_class ));
390
					$class .= method_exists( $obj_class, 'name' ) ? '-' . sanitize_title( $object->name() ) : '';
391
392
			}
393
		}
394
		return $prefix . $class . $suffix;
395
	}
396
397
398
399
	/**
400
	 * EEH_Template::format_currency
401
	 * This helper takes a raw float value and formats it according to the default config country currency settings, or the country currency settings from the supplied country ISO code
402
	 *
403
	 * @param  float      $amount       raw money value
404
	 * @param  boolean    $return_raw   whether to return the formatted float value only with no currency sign or code
405
	 * @param  boolean    $display_code whether to display the country code (USD). Default = TRUE
406
	 * @param string $CNT_ISO      2 letter ISO code for a country
407
	 * @param string      $cur_code_span_class
408
	 * @return string        the html output for the formatted money value
409
	 */
410
	public static function format_currency( $amount = NULL, $return_raw = FALSE, $display_code = TRUE, $CNT_ISO = '', $cur_code_span_class = 'currency-code' ) {
411
		// ensure amount was received
412
		if ( is_null( $amount ) ) {
413
			$msg = __( 'In order to format currency, an amount needs to be passed.', 'event_espresso' );
414
			EE_Error::add_error( $msg, __FILE__, __FUNCTION__, __LINE__ );
415
			return '';
416
		}
417
		//ensure amount is float
418
		$amount = apply_filters( 'FHEE__EEH_Template__format_currency__raw_amount', (float) $amount );
419
		$CNT_ISO = apply_filters( 'FHEE__EEH_Template__format_currency__CNT_ISO', $CNT_ISO, $amount );
420
		// filter raw amount (allows 0.00 to be changed to "free" for example)
421
		$amount_formatted = apply_filters( 'FHEE__EEH_Template__format_currency__amount', $amount, $return_raw );
422
		// still a number or was amount converted to a string like "free" ?
423
		if ( is_float( $amount_formatted )) {
424
			// was a country ISO code passed ? if so generate currency config object for that country
425
			$mny = $CNT_ISO !== '' ? new EE_Currency_Config( $CNT_ISO ) : NULL;
426
			// verify results
427 View Code Duplication
			if ( ! $mny instanceof EE_Currency_Config ) {
428
				// set default config country currency settings
429
				$mny = EE_Registry::instance()->CFG->currency instanceof EE_Currency_Config ? EE_Registry::instance()->CFG->currency : new EE_Currency_Config();
430
			}
431
			// format float
432
			$amount_formatted = number_format( $amount, $mny->dec_plc, $mny->dec_mrk, $mny->thsnds );
433
			// add formatting ?
434
			if ( ! $return_raw ) {
435
				// add currency sign
436
				if( $mny->sign_b4 ){
437
					if( $amount >= 0 ){
438
						$amount_formatted = $mny->sign . $amount_formatted;
439
					}else{
440
						$amount_formatted = '-' . $mny->sign . str_replace( '-', '', $amount_formatted );
441
					}
442
443
				}else{
444
					$amount_formatted =  $amount_formatted . $mny->sign;
445
				}
446
447
				// filter to allow global setting of display_code
448
				$display_code = apply_filters( 'FHEE__EEH_Template__format_currency__display_code', $display_code );
449
450
				// add currency code ?
451
				$amount_formatted = $display_code ? $amount_formatted . ' <span class="' . $cur_code_span_class . '">(' . $mny->code . ')</span>' : $amount_formatted;
452
			}
453
			// filter results
454
			$amount_formatted = apply_filters( 'FHEE__EEH_Template__format_currency__amount_formatted', $amount_formatted, $mny, $return_raw );
455
		}
456
		// clean up vars
457
		unset( $mny );
458
		// return formatted currency amount
459
		return $amount_formatted;
460
	}
461
462
463
464
465
	/**
466
	 * This function is used for outputting the localized label for a given status id in the schema requested (and possibly plural).  The intended use of this function is only for cases where wanting a label outside of a related status model or model object (i.e. in documentation etc.)
467
	 * @param  string  $status_id Status ID matching a registered status in the esp_status table.  If there is no match, then 'Unknown' will be returned.
468
	 * @param  boolean $plural    Whether to return plural or not
469
	 * @param  string  $schema    'UPPER', 'lower', or 'Sentence'
470
	 * @return string             The localized label for the status id.
471
	 */
472
	public static function pretty_status( $status_id, $plural = FALSE, $schema = 'upper' ) {
473
		/** @type EEM_Status $EEM_Status */
474
		$EEM_Status = EE_Registry::instance()->load_model( 'Status' );
475
		$status = $EEM_Status->localized_status( array( $status_id => __( 'unknown', 'event_espresso' )), $plural, $schema );
476
		return $status[ $status_id ];
477
	}
478
479
480
481
	/**
482
	 * This helper just returns a button or link for the given parameters
483
	 *
484
	 * @param  string $url   the url for the link
485
	 * @param  string $label What is the label you want displayed for the button
486
	 * @param  string $class what class is used for the button (defaults to 'button-primary')
487
	 * @param string  $icon
488
	 * @param string  $title
489
	 * @return string the html output for the button
490
	 */
491
	public static function get_button_or_link( $url, $label, $class = 'button-primary', $icon = '', $title = '' ) {
492
		$icon_html = '';
493
		if ( ! empty( $icon ) ) {
494
			$dashicons = preg_split( "(ee-icon |dashicons )", $icon );
495
			$dashicons = array_filter( $dashicons );
496
			$count = count( $dashicons );
497
			$icon_html .= $count > 1 ? '<span class="ee-composite-dashicon">' : '';
498
			foreach ( $dashicons as $dashicon ) {
499
				$type = strpos( $dashicon, 'ee-icon' ) !== false ? 'ee-icon ' : 'dashicons ';
500
				$icon_html .= '<span class="' . $type . $dashicon . '"></span>';
501
			}
502
			$icon_html .= $count > 1 ? '</span>' : '';
503
		}
504
		$label = ! empty( $icon ) ? $icon_html . $label : $label;
505
		$button = '<a id="' . sanitize_title_with_dashes($label) . '" href="' . $url . '" class="' . $class . '" title="' . $title . '">' . $label . '</a>';
506
		return $button;
507
	}
508
509
510
511
	/**
512
	 * This returns a generated link that will load the related help tab on admin pages.
513
	 *
514
	 *
515
	 * @param  string     $help_tab_id the id for the connected help tab
516
	 * @param bool|string $page        The page identifier for the page the help tab is on
517
	 * @param bool|string $action      The action (route) for the admin page the help tab is on.
518
	 * @param bool|string $icon_style  (optional) include css class for the style you want to use for the help icon.
519
	 * @param bool|string $help_text   (optional) send help text you want to use for the link if default not to be used
520
	 * @return string              generated link
521
	 */
522
	public static function get_help_tab_link( $help_tab_id, $page = FALSE, $action = FALSE, $icon_style = FALSE, $help_text = FALSE ) {
523
524 View Code Duplication
		if ( ! $page )
525
			$page = isset( $_REQUEST['page'] ) && ! empty( $_REQUEST['page'] ) ? sanitize_key( $_REQUEST['page'] ) : $page;
526
527 View Code Duplication
		if ( ! $action )
528
			$action = isset( $_REQUEST['action'] ) && ! empty( $_REQUEST['action'] ) ? sanitize_key( $_REQUEST['action'] ) : $action;
529
530
		$action = empty($action) ? 'default' : $action;
531
532
533
		$help_tab_lnk = $page . '-' . $action . '-' . $help_tab_id;
534
		$icon = !$icon_style ? ' dashicons-editor-help' : $icon_style;
535
		$help_text = !$help_text ? '' : $help_text;
536
		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.', 'event_espresso') . '" > ' . $help_text . ' </a>';
537
	}
538
539
540
541
	/**
542
	 * This helper generates the html structure for the jquery joyride plugin with the given params.
543
	 * @link http://zurb.com/playground/jquery-joyride-feature-tour-plugin
544
	 * @see EE_Admin_Page->_stop_callback() for the construct expected for the $stops param.
545
	 * @param EE_Help_Tour
546
	 * @return string         html
547
	 */
548
	public static function help_tour_stops_generator( EE_Help_Tour $tour ) {
549
		$id = $tour->get_slug();
550
		$stops = $tour->get_stops();
551
552
		$content = '<ol style="display:none" id="' . $id . '">';
553
554
		foreach ( $stops as $stop ) {
555
			$data_id = !empty( $stop['id'] ) ? ' data-id="' . $stop['id'] . '"' : '';
556
			$data_class = empty( $data_id ) && !empty( $stop['class'] ) ? ' data-class="' . $stop['class'] . '"' : '';
557
558
			//if container is set to modal then let's make sure we set the options accordingly
559
			if ( empty( $data_id ) && empty( $data_class ) ) {
560
				$stop['options']['modal'] = true;
561
				$stop['options']['expose'] = true;
562
			}
563
564
			$custom_class = !empty( $stop['custom_class'] ) ? ' class="' . $stop['custom_class'] . '"' : '';
565
			$button_text = !empty( $stop['button_text'] ) ? ' data-button="' . $stop['button_text'] . '"' : '';
566
			$inner_content = isset($stop['content']) ? $stop['content'] : '';
567
568
			//options
569
			if ( isset( $stop['options'] ) && is_array( $stop['options'] ) ) {
570
				$options = ' data-options="';
571
				foreach ( $stop['options'] as $option => $value ) {
572
					$options .= $option . ':' . $value . ';';
573
				}
574
				$options .= '"';
575
			} else {
576
				$options = '';
577
			}
578
579
			//let's put all together
580
			$content .= '<li' . $data_id . $data_class . $custom_class . $button_text . $options . '>' . $inner_content . '</li>';
581
		}
582
583
		$content .= '</ol>';
584
		return $content;
585
	}
586
587
588
589
	/**
590
	 * This is a helper method to generate a status legend for a given status array.
591
	 * Note this will only work if the incoming statuses have a key in the EEM_Status->localized_status() methods status_array.
592
	 *
593
	 * @param  array  $status_array  array of statuses that will make up the legend. In format:
594
	 *      array(
595
	 *          'status_item' => 'status_name'
596
	 *       )
597
	 * @param  string $active_status This is used to indicate what the active status is IF that is to be highlighted in the legend.
598
	 * @throws EE_Error
599
	 * @return string               html structure for status.
600
	 */
601
	public static function status_legend( $status_array, $active_status = '' ) {
602
		if ( !is_array( $status_array ) )
603
			throw new EE_Error( __('The EEH_Template::status_legend helper required the incoming status_array argument to be an array!', 'event_espresso') );
604
605
		$setup_array = array();
606
		foreach ( $status_array as $item => $status ) {
607
			$setup_array[$item] = array(
608
					'class' => 'ee-status-legend ee-status-legend-' . $status,
609
					'desc' => EEH_Template::pretty_status( $status, FALSE, 'sentence' ),
610
					'status' => $status
611
				);
612
		}
613
614
		$content = '<div class="ee-list-table-legend-container">' . "\n";
615
		$content .= '<h3>' . __('Status Legend', 'event_espresso') . '</h3>' . "\n";
616
		$content .= '<dl class="ee-list-table-legend">' . "\n\t";
617
		foreach ( $setup_array as $item => $details ) {
618
			$active_class = $active_status == $details['status'] ? ' class="ee-is-active-status"' : '';
619
			$content .= '<dt id="ee-legend-item-tooltip-' . $item . '"' . $active_class . '>' . "\n\t\t";
620
			$content .= '<span class="' . $details['class'] . '"></span>' . "\n\t\t";
621
			$content .= '<span class="ee-legend-description">' . $details['desc'] . '</span>' . "\n\t";
622
			$content .= '</dt>' . "\n";
623
		}
624
		$content .= '</dl>' . "\n";
625
		$content .= '</div>' . "\n";
626
		return $content;
627
	}
628
629
630
631
	/**
632
	 * Gets HTML for laying out a deeply-nested array (and objects) in a format
633
	 * that's nice for presenting in the wp admin
634
	 * @param mixed $data
635
	 * @return string
636
	 */
637
	public static function layout_array_as_table($data) {
638
	if (is_object($data) || $data instanceof __PHP_Incomplete_Class ) {
639
		$data = (array)$data;
640
	}
641
	ob_start();
642
	if (is_array($data)) {
643
		if (EEH_Array::is_associative_array($data)) {
644
			?>
645
			<table class="widefat">
646
				<tbody>
647
					<?php
648
					foreach ($data as $data_key => $data_values) {
649
						?>
650
						<tr>
651
							<td>
652
								<?php echo $data_key;?>
653
							</td>
654
							<td>
655
								<?php echo self::layout_array_as_table($data_values);?>
656
							</td>
657
						</tr>
658
						<?php
659
					}?>
660
				</tbody>
661
			</table>
662
			<?php
663
		}
664
		else {
665
			?>
666
			<ul>
667
				<?php
668
				foreach ($data as $datum) {
669
					echo "<li>"; echo self::layout_array_as_table($datum);echo "</li>";
670
				}?>
671
			</ul>
672
			<?php
673
		}
674
	}
675
	else {
676
		//simple value
677
		echo $data;
678
	}
679
	return ob_get_clean();
680
}
681
682
683
684
	/**
685
	 * wrapper for self::get_paging_html() that simply echos the generated paging html
686
	 *
687
	 * @since 4.4.0
688
	 * @see   self:get_paging_html() for argument docs.
689
	 * @param      $total_items
690
	 * @param      $current
691
	 * @param      $per_page
692
	 * @param      $url
693
	 * @param bool $show_num_field
694
	 * @param string $paged_arg_name
695
	 * @param array $items_label
696
	 *
697
	 * @return string
698
	 */
699
	public static function paging_html( $total_items, $current, $per_page, $url, $show_num_field = TRUE, $paged_arg_name = 'paged', $items_label = array() ) {
700
		echo self::get_paging_html( $total_items, $current, $per_page, $url, $show_num_field, $paged_arg_name, $items_label );
701
	}
702
703
704
705
	/**
706
	 * A method for generating paging similar to WP_List_Table
707
	 *
708
	 * @since 4.4.0
709
	 * @see      wp-admin/includes/class-wp-list-table.php WP_List_Table::pagination()
710
	 *
711
	 * @param  integer $total_items      	How many total items there are to page.
712
	 * @param  integer $current 	 	What the current page is.
713
	 * @param  integer $per_page 		How many items per page.
714
	 * @param  string   $url                  	What the base url for page links is.
715
	 * @param  boolean $show_num_field  Whether to show the input for changing page number.
716
	 * @param  string   $paged_arg_name     The name of the key for the paged query argument.
717
	 * @param  array   $items_label    An array of singular/plural values for the items label:
718
	 *                                 array(
719
	 *                                  'single' => 'item',
720
	 *                                  'plural' => 'items'
721
	 *                                 )
722
	 * @return  string
723
	 */
724
	public static function get_paging_html( $total_items, $current, $per_page, $url, $show_num_field = TRUE, $paged_arg_name = 'paged', $items_label = array() ) {
725
		$page_links = array();
726
		$disable_first = $disable_last = '';
727
		$total_items = (int) $total_items;
728
		$per_page = (int) $per_page;
729
		$current = (int) $current;
730
		$paged_arg_name = empty( $paged_arg_name ) ? 'paged' : sanitize_key( $paged_arg_name );
731
732
		//filter items_label
733
		$items_label = apply_filters(
734
			'FHEE__EEH_Template__get_paging_html__items_label',
735
			$items_label
736
		);
737
738
		if ( empty( $items_label )
739
		     || ! is_array( $items_label )
740
		     || ! isset( $items_label['single'] )
741
		     || ! isset( $items_label['plural'] ) ) {
742
			$items_label = array(
743
				'single' => __( '1 item', 'event_espresso' ),
744
				'plural' => __( '%s items', 'event_espresso' )
745
			);
746
		} else {
747
			$items_label = array(
748
				'single' => '1 ' . esc_html( $items_label['single'] ),
749
				'plural' => '%s ' . esc_html( $items_label['plural'] )
750
			);
751
		}
752
753
		$total_pages = ceil( $total_items / $per_page );
754
755
		if ( $total_pages <= 1 )
756
			return '';
757
758
		$item_label = $total_items > 1 ? sprintf( $items_label['plural'], $total_items ) : $items_label['single'];
759
760
		$output = '<span class="displaying-num">' . $item_label . '</span>';
761
762
		if ( $current === 1 ) {
763
			$disable_first = ' disabled';
764
		}
765
		if ( $current == $total_pages ) {
766
			$disable_last = ' disabled';
767
		}
768
769
		$page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
770
			'first-page' . $disable_first,
771
			esc_attr__( 'Go to the first page' ),
772
			esc_url( remove_query_arg( $paged_arg_name, $url ) ),
773
			'&laquo;'
774
		);
775
776
		$page_links[] = sprintf(
777
			'<a class="%s" title="%s" href="%s">%s</a>',
778
			'prev-page' . $disable_first,
779
			esc_attr__( 'Go to the previous page' ),
780
			esc_url( add_query_arg( $paged_arg_name, max( 1, $current-1 ), $url ) ),
781
			'&lsaquo;'
782
		);
783
784
		if ( ! $show_num_field ) {
785
			$html_current_page = $current;
786
		} else {
787
			$html_current_page = sprintf( "<input class='current-page' title='%s' type='text' name=$paged_arg_name value='%s' size='%d' />",
788
				esc_attr__( 'Current page' ),
789
				$current,
790
				strlen( $total_pages )
791
			);
792
		}
793
794
		$html_total_pages = sprintf(
795
			'<span class="total-pages">%s</span>',
796
			number_format_i18n( $total_pages )
797
		);
798
		$page_links[] = sprintf(
799
			_x( '%3$s%1$s of %2$s%4$s', 'paging' ),
800
			$html_current_page,
801
			$html_total_pages,
802
			'<span class="paging-input">',
803
			'</span>'
804
		);
805
806
		$page_links[] = sprintf(
807
			'<a class="%s" title="%s" href="%s">%s</a>',
808
			'next-page' . $disable_last,
809
			esc_attr__( 'Go to the next page' ),
810
			esc_url( add_query_arg( $paged_arg_name, min( $total_pages, $current+1 ), $url ) ),
811
			'&rsaquo;'
812
		);
813
814
		$page_links[] = sprintf(
815
			'<a class="%s" title="%s" href="%s">%s</a>',
816
			'last-page' . $disable_last,
817
			esc_attr__( 'Go to the last page' ),
818
			esc_url( add_query_arg( $paged_arg_name, $total_pages, $url ) ),
819
			'&raquo;'
820
		);
821
822
		$output .= "\n" . '<span class="pagination-links">' . join( "\n", $page_links ) . '</span>';
823
		// set page class
824
		if ( $total_pages ) {
825
			$page_class = $total_pages < 2 ? ' one-page' : '';
826
		} else {
827
			$page_class = ' no-pages';
828
		}
829
830
		return '<div class="tablenav"><div class="tablenav-pages' . $page_class . '">' . $output . '</div></div>';
831
	}
832
833
834
835
	/**
836
	 * @param string $wrap_class
837
	 * @param string $wrap_id
838
	 * @return string
839
	 */
840
	public static function powered_by_event_espresso( $wrap_class = '', $wrap_id = '' ) {
841
		$admin = is_admin() && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX );
842
		if (
843
			! $admin &&
844
			! apply_filters(
845
				'FHEE__EEH_Template__powered_by_event_espresso__show_reg_footer',
846
				EE_Registry::instance()->CFG->admin->show_reg_footer
847
			)
848
		) {
849
			return '';
850
		}
851
		$attributes = ! empty( $wrap_id ) ? " id=\"{$wrap_id}\"" : '';
852
		$wrap_class = $admin ? "{$wrap_class} float-left" : $wrap_class;
853
		$attributes .= ! empty( $wrap_class )
854
			? " class=\"{$wrap_class} powered-by-event-espresso-credit\""
855
			: ' class="powered-by-event-espresso-credit"';
856
		$powered_by = $admin ? EVENT_ESPRESSO_POWERED_BY : 'Event Espresso';
857
		$url = add_query_arg(
858
			array( 'ap_id' => EE_Registry::instance()->CFG->admin->affiliate_id() ),
859
			'https://eventespresso.com/'
860
		);
861
		$url = apply_filters( 'FHEE__EEH_Template__powered_by_event_espresso__url', $url );
862
		return (string) apply_filters(
863
			'FHEE__EEH_Template__powered_by_event_espresso__html',
864
			sprintf(
865
				esc_html_x(
866
					'%1$sOnline event registration and ticketing powered by %2$s',
867
					'Online event registration and ticketing powered by [link to eventespresso.com]',
868
					'event_espresso'
869
				),
870
				"<div{$attributes}>",
871
				"<a href=\"{$url}\" target=\"_blank\">{$powered_by}</a></div>"
872
			)
873
		);
874
	}
875
876
877
878
} //end EEH_Template class
879
880
881
//function convert_zero_to_free( $amount, $return_raw ) {
882
//	// we don't want to mess with requests for unformatted values because those may get used in calculations
883
//	if ( ! $return_raw && ! is_admin() ) {
884
//		$amount = __( 'free', 'event_espresso' );
885
//	}
886
//	return $amount;
887
//}
888
//add_filter( 'FHEE__EEH_Template__format_currency__amount', 'convert_zero_to_free', 10, 2 );
889
890
891 View Code Duplication
if ( ! function_exists( 'espresso_pagination' ) ) {
892
	/**
893
	 *    espresso_pagination
894
	 *
895
	 * @access    public
896
	 * @return    void
897
	 */
898
	function espresso_pagination() {
899
		global $wp_query;
900
		$big = 999999999; // need an unlikely integer
901
		$pagination = paginate_links(
902
		array(
903
		'base'         => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
904
		'format'       => '?paged=%#%',
905
		'current'      => max( 1, get_query_var( 'paged' ) ),
906
		'total'        => $wp_query->max_num_pages,
907
		'show_all'     => true,
908
		'end_size'     => 10,
909
		'mid_size'     => 6,
910
		'prev_next'    => true,
911
		'prev_text'    => __( '&lsaquo; PREV', 'event_espresso' ),
912
		'next_text'    => __( 'NEXT &rsaquo;', 'event_espresso' ),
913
		'type'         => 'plain',
914
		'add_args'     => false,
915
		'add_fragment' => ''
916
		)
917
		);
918
		echo ! empty( $pagination ) ? '<div class="ee-pagination-dv clear">' . $pagination . '</div>' : '';
919
	}
920
}