Completed
Branch FET-9784-autopopulate-forms (4bc800)
by
unknown
403:32 queued 388:51
created

EEH_Template::locate_template()   F

Complexity

Conditions 22
Paths 1306

Size

Total Lines 104
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

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