Completed
Branch FET-8284-automagic-dependency-... (a299cf)
by
unknown
556:45 queued 543:10
created

EEH_Template::locate_template()   F

Complexity

Conditions 22
Paths 1306

Size

Total Lines 103
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 22
eloc 53
nc 1306
nop 5
dl 0
loc 103
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
			EE_Registry::instance()->load_helper('File');
239
			// loop through $templates
240
			foreach ( $templates as $template ) {
241
				// normalize directory separators
242
				$template = EEH_File::standardise_directory_separators( $template );
243
				$file_name = basename( $template );
244
				$template_path_minus_file_name = substr( $template, 0, ( strlen( $file_name ) * -1 ) );
245
				// while looping through all template folder paths
246
				foreach ( $template_folder_paths as $template_folder_path ) {
247
					// normalize directory separators
248
					$template_folder_path = EEH_File::standardise_directory_separators( $template_folder_path );
249
					// determine if any common base path exists between the two paths
250
					$common_base_path = EEH_Template::_find_common_base_path(
251
						array( $template_folder_path, $template_path_minus_file_name )
252
					);
253
					if ( $common_base_path !== '' ) {
254
						// both paths have a common base, so just tack the filename onto our search path
255
						$resolved_path = EEH_File::end_with_directory_separator( $template_folder_path ) . $file_name;
256
					} else {
257
						// no common base path, so let's just concatenate
258
						$resolved_path = EEH_File::end_with_directory_separator( $template_folder_path ) . $template;
259
					}
260
					// build up our template locations array by adding our resolved paths
261
					$full_template_paths[] = $resolved_path;
262
				}
263
				// if $template is an absolute path, then we'll tack it onto the start of our array so that it gets searched first
264
				array_unshift( $full_template_paths, $template );
265
				// path to the directory of the current theme: /wp-content/themes/(current WP theme)/
266
				array_unshift( $full_template_paths, get_stylesheet_directory() . DS . $file_name );
267
			}
268
			// filter final array of full template paths
269
			$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...
270
			// now loop through our final array of template location paths and check each location
271
			foreach ( (array)$full_template_paths as $full_template_path ) {
272
				if ( is_readable( $full_template_path )) {
273
					$template_path = str_replace( array( '\\', '/' ), DIRECTORY_SEPARATOR, $full_template_path );
274
					break;
275
				}
276
			}
277
		}
278
		// if we got it and you want to see it...
279
		if ( $template_path && $load && ! $check_if_custom  ) {
280
			if ( $return_string ) {
281
				return EEH_Template::display_template( $template_path, $template_args, TRUE );
282
			} else {
283
				EEH_Template::display_template( $template_path, $template_args, FALSE );
284
			}
285
		}
286
		return $check_if_custom && ! empty( $template_path ) ? TRUE : $template_path;
287
	}
288
289
290
291
	/**
292
	 * _find_common_base_path
293
	 *
294
	 * given two paths, this determines if there is a common base path between the two
295
	 *
296
	 * @param array $paths
297
	 * @return string
298
	 */
299
	protected static function _find_common_base_path( $paths ) {
300
		$last_offset = 0;
301
		$common_base_path = '';
302
		while ( ( $index = strpos( $paths[ 0 ], DS, $last_offset ) ) !== false ) {
303
			$dir_length = $index - $last_offset + 1;
304
			$directory = substr( $paths[ 0 ], $last_offset, $dir_length );
305
			foreach ( $paths as $path ) {
306
				if ( substr( $path, $last_offset, $dir_length ) != $directory ) {
307
					return $common_base_path;
308
				}
309
			}
310
			$common_base_path .= $directory;
311
			$last_offset = $index + 1;
312
		}
313
		return substr( $common_base_path, 0, -1 );
314
	}
315
316
317
318
	/**
319
	 * load and display a template
320
	 * @param bool|string $template_path server path to the file to be loaded, including file name and extension
321
	 * @param  array      $template_args an array of arguments to be extracted for use in the template
322
	 * @param  boolean    $return_string whether to send output immediately to screen, or capture and return as a string
323
	 * @return mixed string
324
	 */
325
	public static function display_template( $template_path = FALSE, $template_args = array(), $return_string = FALSE ) {
326
		//require the template validator for verifying variables are set according to how the template requires
327
		EE_Registry::instance()->load_helper( 'Template_Validator' );
328
329
		/**
330
		 * These two filters are intended for last minute changes to templates being loaded and/or template arg
331
		 * modifications.  NOTE... modifying these things can cause breakage as most templates running through
332
		 * the display_template method are templates we DON'T want modified (usually because of js
333
		 * dependencies etc).  So unless you know what you are doing, do NOT filter templates or template args
334
		 * using this.
335
		 *
336
		 * @since 4.6.0
337
		 */
338
		$template_path = apply_filters( 'FHEE__EEH_Template__display_template__template_path', $template_path );
339
		$template_args = apply_filters( 'FHEE__EEH_Template__display_template__template_args', $template_args );
340
341
		// you gimme nuttin - YOU GET NUTTIN !!
342
		if ( ! $template_path || ! is_readable( $template_path )) {
343
			return '';
344
		}
345
		// if $template_args are not in an array, then make it so
346
		if ( ! is_array( $template_args ) && ! is_object( $template_args )) {
347
			$template_args = array( $template_args );
348
		}
349
		extract( (array) $template_args);
350
351
		if ( $return_string ) {
352
			// because we want to return a string, we are going to capture the output
353
			ob_start();
354
			include( $template_path );
355
			return ob_get_clean();
356
		} else {
357
			include( $template_path );
358
		}
359
		return '';
360
	}
361
362
363
364
365
366
	/**
367
	 * get_object_css_class - attempts to generate a css class based on the type of EE object passed
368
	 *
369
	 *
370
	 * @param EE_Base_Class $object the EE object the css class is being generated for
371
	 * @param  string $prefix added to the beginning of the generated class
372
	 * @param  string $suffix added to the end of the generated class
373
	 * @return string
374
	 */
375
	public static function get_object_css_class( $object = NULL, $prefix = '', $suffix = '' ) {
376
		// in the beginning...
377
		$prefix = ! empty( $prefix ) ? rtrim( $prefix, '-' ) . '-' : '';
378
		// da muddle
379
		$class = '';
380
		// the end
381
		$suffix = ! empty( $suffix ) ? '-' . ltrim( $suffix, '-' ) : '';
382
		// is the passed object an EE object ?
383
		if ( $object instanceof EE_Base_Class ) {
384
			// grab the exact type of object
385
			$obj_class = get_class( $object );
386
			// depending on the type of object...
387
			switch ( $obj_class ) {
388
				// no specifics just yet...
389
				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...
390
					$class = strtolower( str_replace( '_', '-', $obj_class ));
391
					$class .= method_exists( $obj_class, 'name' ) ? '-' . sanitize_title( $object->name() ) : '';
392
393
			}
394
		}
395
		return $prefix . $class . $suffix;
396
	}
397
398
399
400
	/**
401
	 * EEH_Template::format_currency
402
	 * 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
403
	 *
404
	 * @param  float      $amount       raw money value
405
	 * @param  boolean    $return_raw   whether to return the formatted float value only with no currency sign or code
406
	 * @param  boolean    $display_code whether to display the country code (USD). Default = TRUE
407
	 * @param string $CNT_ISO      2 letter ISO code for a country
408
	 * @param string      $cur_code_span_class
409
	 * @return string        the html output for the formatted money value
410
	 */
411
	public static function format_currency( $amount = NULL, $return_raw = FALSE, $display_code = TRUE, $CNT_ISO = '', $cur_code_span_class = 'currency-code' ) {
412
		// ensure amount was received
413
		if ( is_null( $amount ) ) {
414
			$msg = __( 'In order to format currency, an amount needs to be passed.', 'event_espresso' );
415
			EE_Error::add_error( $msg, __FILE__, __FUNCTION__, __LINE__ );
416
			return '';
417
		}
418
		//ensure amount is float
419
		$amount = (float) $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
				// add currency code ?
448
				$amount_formatted = $display_code ? $amount_formatted . ' <span class="' . $cur_code_span_class . '">(' . $mny->code . ')</span>' : $amount_formatted;
449
			}
450
			// filter results
451
			$amount_formatted = apply_filters( 'FHEE__EEH_Template__format_currency__amount_formatted', $amount_formatted, $mny, $return_raw );
452
		}
453
		// clean up vars
454
		unset( $mny );
455
		// return formatted currency amount
456
		return $amount_formatted;
457
	}
458
459
460
461
462
	/**
463
	 * 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.)
464
	 * @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.
465
	 * @param  boolean $plural    Whether to return plural or not
466
	 * @param  string  $schema    'UPPER', 'lower', or 'Sentence'
467
	 * @return string             The localized label for the status id.
468
	 */
469
	public static function pretty_status( $status_id, $plural = FALSE, $schema = 'upper' ) {
470
		/** @type EEM_Status $EEM_Status */
471
		$EEM_Status = EE_Registry::instance()->load_model( 'Status' );
472
		$status = $EEM_Status->localized_status( array( $status_id => __( 'unknown', 'event_espresso' )), $plural, $schema );
473
		return $status[ $status_id ];
474
	}
475
476
477
478
	/**
479
	 * This helper just returns a button or link for the given parameters
480
	 * @param  string $url   the url for the link
481
	 * @param  string $label What is the label you want displayed for the button
482
	 * @param  string $class what class is used for the button (defaults to 'button-primary')
483
	 * @param string  $icon
484
	 * @return string 	the html output for the button
485
	 */
486
	public static function get_button_or_link( $url, $label, $class = 'button-primary', $icon = '' ) {
487
		$label = ! empty( $icon ) ? '<span class="' . $icon . '"></span>' . $label : $label;
488
		$button = '<a id="' . sanitize_title_with_dashes($label) . '" href="' . $url . '" class="' . $class . '">' . $label . '</a>';
489
		return $button;
490
	}
491
492
493
494
	/**
495
	 * This returns a generated link that will load the related help tab on admin pages.
496
	 *
497
	 *
498
	 * @param  string     $help_tab_id the id for the connected help tab
499
	 * @param bool|string $page        The page identifier for the page the help tab is on
500
	 * @param bool|string $action      The action (route) for the admin page the help tab is on.
501
	 * @param bool|string $icon_style  (optional) include css class for the style you want to use for the help icon.
502
	 * @param bool|string $help_text   (optional) send help text you want to use for the link if default not to be used
503
	 * @return string              generated link
504
	 */
505
	public static function get_help_tab_link( $help_tab_id, $page = FALSE, $action = FALSE, $icon_style = FALSE, $help_text = FALSE ) {
506
507 View Code Duplication
		if ( ! $page )
508
			$page = isset( $_REQUEST['page'] ) && ! empty( $_REQUEST['page'] ) ? sanitize_key( $_REQUEST['page'] ) : $page;
509
510 View Code Duplication
		if ( ! $action )
511
			$action = isset( $_REQUEST['action'] ) && ! empty( $_REQUEST['action'] ) ? sanitize_key( $_REQUEST['action'] ) : $action;
512
513
		$action = empty($action) ? 'default' : $action;
514
515
516
		$help_tab_lnk = $page . '-' . $action . '-' . $help_tab_id;
517
		$icon = !$icon_style ? ' dashicons-editor-help' : $icon_style;
518
		$help_text = !$help_text ? '' : $help_text;
519
		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>';
520
	}
521
522
523
524
	/**
525
	 * This helper generates the html structure for the jquery joyride plugin with the given params.
526
	 * @link http://zurb.com/playground/jquery-joyride-feature-tour-plugin
527
	 * @see EE_Admin_Page->_stop_callback() for the construct expected for the $stops param.
528
	 * @param EE_Help_Tour
529
	 * @return string         html
530
	 */
531
	public static function help_tour_stops_generator( EE_Help_Tour $tour ) {
532
		$id = $tour->get_slug();
533
		$stops = $tour->get_stops();
534
535
		$content = '<ol style="display:none" id="' . $id . '">';
536
537
		foreach ( $stops as $stop ) {
538
			$data_id = !empty( $stop['id'] ) ? ' data-id="' . $stop['id'] . '"' : '';
539
			$data_class = empty( $data_id ) && !empty( $stop['class'] ) ? ' data-class="' . $stop['class'] . '"' : '';
540
541
			//if container is set to modal then let's make sure we set the options accordingly
542
			if ( empty( $data_id ) && empty( $data_class ) ) {
543
				$stop['options']['modal'] = true;
544
				$stop['options']['expose'] = true;
545
			}
546
547
			$custom_class = !empty( $stop['custom_class'] ) ? ' class="' . $stop['custom_class'] . '"' : '';
548
			$button_text = !empty( $stop['button_text'] ) ? ' data-button="' . $stop['button_text'] . '"' : '';
549
			$inner_content = isset($stop['content']) ? $stop['content'] : '';
550
551
			//options
552
			if ( isset( $stop['options'] ) && is_array( $stop['options'] ) ) {
553
				$options = ' data-options="';
554
				foreach ( $stop['options'] as $option => $value ) {
555
					$options .= $option . ':' . $value . ';';
556
				}
557
				$options .= '"';
558
			} else {
559
				$options = '';
560
			}
561
562
			//let's put all together
563
			$content .= '<li' . $data_id . $data_class . $custom_class . $button_text . $options . '>' . $inner_content . '</li>';
564
		}
565
566
		$content .= '</ol>';
567
		return $content;
568
	}
569
570
571
572
	/**
573
	 * This is a helper method to generate a status legend for a given status array.
574
	 * Note this will only work if the incoming statuses have a key in the EEM_Status->localized_status() methods status_array.
575
	 *
576
	 * @param  array  $status_array  array of statuses that will make up the legend. In format:
577
	 *      array(
578
	 *          'status_item' => 'status_name'
579
	 *       )
580
	 * @param  string $active_status This is used to indicate what the active status is IF that is to be highlighted in the legend.
581
	 * @throws EE_Error
582
	 * @return string               html structure for status.
583
	 */
584
	public static function status_legend( $status_array, $active_status = '' ) {
585
		if ( !is_array( $status_array ) )
586
			throw new EE_Error( __('The EEH_Template::status_legend helper required the incoming status_array argument to be an array!', 'event_espresso') );
587
588
		$setup_array = array();
589
		foreach ( $status_array as $item => $status ) {
590
			$setup_array[$item] = array(
591
					'class' => 'ee-status-legend ee-status-legend-' . $status,
592
					'desc' => EEH_Template::pretty_status( $status, FALSE, 'sentence' ),
593
					'status' => $status
594
				);
595
		}
596
597
		$content = '<div class="ee-list-table-legend-container">' . "\n";
598
		$content .= '<h3>' . __('Status Legend', 'event_espresso') . '</h3>' . "\n";
599
		$content .= '<dl class="ee-list-table-legend">' . "\n\t";
600
		foreach ( $setup_array as $item => $details ) {
601
			$active_class = $active_status == $details['status'] ? ' class="ee-is-active-status"' : '';
602
			$content .= '<dt id="ee-legend-item-tooltip-' . $item . '"' . $active_class . '>' . "\n\t\t";
603
			$content .= '<span class="' . $details['class'] . '"></span>' . "\n\t\t";
604
			$content .= '<span class="ee-legend-description">' . $details['desc'] . '</span>' . "\n\t";
605
			$content .= '</dt>' . "\n";
606
		}
607
		$content .= '</dl>' . "\n";
608
		$content .= '</div>' . "\n";
609
		return $content;
610
	}
611
612
613
614
	/**
615
	 * Gets HTML for laying out a deeply-nested array (and objects) in a format
616
	 * that's nice for presenting in the wp admin
617
	 * @param mixed $data
618
	 * @return string
619
	 */
620
	public static function layout_array_as_table($data) {
621
	if (is_object($data) || $data instanceof __PHP_Incomplete_Class ) {
622
		$data = (array)$data;
623
	}
624
	EE_Registry::instance()->load_helper('Array');
625
	ob_start();
626
	if (is_array($data)) {
627
		if (EEH_Array::is_associative_array($data)) {
628
			?>
629
			<table class="widefat">
630
				<tbody>
631
					<?php
632
					foreach ($data as $data_key => $data_values) {
633
						?>
634
						<tr>
635
							<td>
636
								<?php echo $data_key;?>
637
							</td>
638
							<td>
639
								<?php echo self::layout_array_as_table($data_values);?>
640
							</td>
641
						</tr>
642
						<?php
643
					}?>
644
				</tbody>
645
			</table>
646
			<?php
647
		}
648
		else {
649
			?>
650
			<ul>
651
				<?php
652
				foreach ($data as $datum) {
653
					echo "<li>"; echo self::layout_array_as_table($datum);echo "</li>";
654
				}?>
655
			</ul>
656
			<?php
657
		}
658
	}
659
	else {
660
		//simple value
661
		echo $data;
662
	}
663
	return ob_get_clean();
664
}
665
666
667
668
	/**
669
	 * wrapper for self::get_paging_html() that simply echos the generated paging html
670
	 *
671
	 * @since 4.4.0
672
	 * @see   self:get_paging_html() for argument docs.
673
	 * @param      $total_items
674
	 * @param      $current
675
	 * @param      $per_page
676
	 * @param      $url
677
	 * @param bool $show_num_field
678
	 * @param string $paged_arg_name
679
	 * @param array $items_label
680
	 *
681
	 * @return string
682
	 */
683
	public static function paging_html( $total_items, $current, $per_page, $url, $show_num_field = TRUE, $paged_arg_name = 'paged', $items_label = array() ) {
684
		echo self::get_paging_html( $total_items, $current, $per_page, $url, $show_num_field, $paged_arg_name, $items_label );
685
	}
686
687
688
689
	/**
690
	 * A method for generating paging similar to WP_List_Table
691
	 *
692
	 * @since 4.4.0
693
	 * @see      wp-admin/includes/class-wp-list-table.php WP_List_Table::pagination()
694
	 *
695
	 * @param  integer $total_items      	How many total items there are to page.
696
	 * @param  integer $current 	 	What the current page is.
697
	 * @param  integer $per_page 		How many items per page.
698
	 * @param  string   $url                  	What the base url for page links is.
699
	 * @param  boolean $show_num_field  Whether to show the input for changing page number.
700
	 * @param  string   $paged_arg_name     The name of the key for the paged query argument.
701
	 * @param  array   $items_label    An array of singular/plural values for the items label:
702
	 *                                 array(
703
	 *                                  'single' => 'item',
704
	 *                                  'plural' => 'items'
705
	 *                                 )
706
	 * @return  string
707
	 */
708
	public static function get_paging_html( $total_items, $current, $per_page, $url, $show_num_field = TRUE, $paged_arg_name = 'paged', $items_label = array() ) {
709
		$page_links = array();
710
		$disable_first = $disable_last = '';
711
		$total_items = (int) $total_items;
712
		$per_page = (int) $per_page;
713
		$current = (int) $current;
714
		$paged_arg_name = empty( $paged_arg_name ) ? 'paged' : sanitize_key( $paged_arg_name );
715
716
		//filter items_label
717
		$items_label = apply_filters(
718
			'FHEE__EEH_Template__get_paging_html__items_label',
719
			$items_label
720
		);
721
722
		if ( empty( $items_label )
723
		     || ! is_array( $items_label )
724
		     || ! isset( $items_label['single'] )
725
		     || ! isset( $items_label['plural'] ) ) {
726
			$items_label = array(
727
				'single' => __( '1 item', 'event_espresso' ),
728
				'plural' => __( '%s items', 'event_espresso' )
729
			);
730
		} else {
731
			$items_label = array(
732
				'single' => '1 ' . esc_html( $items_label['single'] ),
733
				'plural' => '%s ' . esc_html( $items_label['plural'] )
734
			);
735
		}
736
737
		$total_pages = ceil( $total_items / $per_page );
738
739
		if ( $total_pages <= 1 )
740
			return '';
741
742
		$item_label = $total_items > 1 ? sprintf( $items_label['plural'], $total_items ) : $items_label['single'];
743
744
		$output = '<span class="displaying-num">' . $item_label . '</span>';
745
746
		if ( $current === 1 ) {
747
			$disable_first = ' disabled';
748
		}
749
		if ( $current == $total_pages ) {
750
			$disable_last = ' disabled';
751
		}
752
753
		$page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
754
			'first-page' . $disable_first,
755
			esc_attr__( 'Go to the first page' ),
756
			esc_url( remove_query_arg( $paged_arg_name, $url ) ),
757
			'&laquo;'
758
		);
759
760
		$page_links[] = sprintf(
761
			'<a class="%s" title="%s" href="%s">%s</a>',
762
			'prev-page' . $disable_first,
763
			esc_attr__( 'Go to the previous page' ),
764
			esc_url( add_query_arg( $paged_arg_name, max( 1, $current-1 ), $url ) ),
765
			'&lsaquo;'
766
		);
767
768
		if ( ! $show_num_field ) {
769
			$html_current_page = $current;
770
		} else {
771
			$html_current_page = sprintf( "<input class='current-page' title='%s' type='text' name=$paged_arg_name value='%s' size='%d' />",
772
				esc_attr__( 'Current page' ),
773
				$current,
774
				strlen( $total_pages )
775
			);
776
		}
777
778
		$html_total_pages = sprintf(
779
			'<span class="total-pages">%s</span>',
780
			number_format_i18n( $total_pages )
781
		);
782
		$page_links[] = sprintf(
783
			_x( '%3$s%1$s of %2$s%4$s', 'paging' ),
784
			$html_current_page,
785
			$html_total_pages,
786
			'<span class="paging-input">',
787
			'</span>'
788
		);
789
790
		$page_links[] = sprintf(
791
			'<a class="%s" title="%s" href="%s">%s</a>',
792
			'next-page' . $disable_last,
793
			esc_attr__( 'Go to the next page' ),
794
			esc_url( add_query_arg( $paged_arg_name, min( $total_pages, $current+1 ), $url ) ),
795
			'&rsaquo;'
796
		);
797
798
		$page_links[] = sprintf(
799
			'<a class="%s" title="%s" href="%s">%s</a>',
800
			'last-page' . $disable_last,
801
			esc_attr__( 'Go to the last page' ),
802
			esc_url( add_query_arg( $paged_arg_name, $total_pages, $url ) ),
803
			'&raquo;'
804
		);
805
806
		$output .= "\n" . '<span class="pagination-links">' . join( "\n", $page_links ) . '</span>';
807
		// set page class
808
		if ( $total_pages ) {
809
			$page_class = $total_pages < 2 ? ' one-page' : '';
810
		} else {
811
			$page_class = ' no-pages';
812
		}
813
814
		return '<div class="tablenav"><div class="tablenav-pages' . $page_class . '">' . $output . '</div></div>';
815
	}
816
817
818
} //end EEH_Template class
819
820
//function convert_zero_to_free( $amount, $return_raw ) {
821
//	// we don't want to mess with requests for unformatted values because those may get used in calculations
822
//	if ( ! $return_raw && ! is_admin() ) {
823
//		$amount = __( 'free', 'event_espresso' );
824
//	}
825
//	return $amount;
826
//}
827
//add_filter( 'FHEE__EEH_Template__format_currency__amount', 'convert_zero_to_free', 10, 2 );
828