Completed
Push — master ( cf9740...0c1274 )
by Zack
19:03 queued 03:33
created

helper-functions.php ➔ gv_empty()   D

Complexity

Conditions 18
Paths 12

Size

Total Lines 47
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 18.0265

Importance

Changes 0
Metric Value
cc 18
eloc 25
nc 12
nop 3
dl 0
loc 47
ccs 22
cts 23
cp 0.9565
crap 18.0265
rs 4.9205
c 0
b 0
f 0

How to fix   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
/**
3
 * Functions that don't require GravityView or Gravity Forms API access but are used in the plugin to extend PHP and WP functions
4
 * @since 1.12
5
 */
6
7
8
/**
9
 * Get the URL for a CSS file
10
 * 
11
 * If there's a CSS file with the same name as a GravityView CSS file in the current theme directory, it will be used.
12
 * Place the CSS file in a `/gravityview/css/` sub-directory. 
13
 * 
14
 * Example: /twentysixteen/gravityview/css/gv-default-styles.css
15
 *
16
 * Will use, in order:
17
 * 1) [theme directory]/gravityview/css/
18
 * 2) [gravityview plugin]/css/ (no check performed)
19
 *
20
 * @since 1.17
21
 *
22
 * @uses get_stylesheet_directory()
23
 * @uses get_stylesheet_directory_uri()
24
 *
25
 * @param string $css_file Filename of the CSS file (like gv-default-styles.css)
26
 * @param string $dir_path Absolute path to the directory where the CSS file is stored. If empty, uses default GravityView templates CSS folder.
27
 *
28
 * @return string URL path to the file.
29
 */
30
function gravityview_css_url( $css_file = '', $dir_path = '' ) {
31
32
	// If there's an overriding CSS file in the current template folder, use it.
33
	$template_css_path = trailingslashit( get_stylesheet_directory() ) . 'gravityview/css/' . $css_file;
34
35
	if( file_exists( $template_css_path ) ) {
36
		$path = trailingslashit( get_stylesheet_directory_uri() ) . 'gravityview/css/' . $css_file;
37
		do_action( 'gravityview_log_debug', __FUNCTION__ . ': Stylesheet override ('. esc_attr( $css_file ) .')' );
38
	} else {
39
		// Default: use GravityView CSS file
40
41
		// If no path is provided, assume default plugin templates CSS folder
42
		if( '' === $dir_path ) {
43
			$dir_path = GRAVITYVIEW_DIR . 'templates/css/';
44
		}
45
		
46
		// plugins_url() expects a path to a file, not directory. We append a file to be stripped.
47
		$path = plugins_url( $css_file, trailingslashit( $dir_path )  . 'stripped-by-plugin_basename.php' );
48
	}
49
50
	return $path;
51
}
52
53
/**
54
 * Check whether a variable is not an empty string
55
 *
56
 * @see /templates/fields/product.php Used to check whether the product array is empty or not
57
 *
58
 * @since 1.12
59
 *
60
 * @param mixed $mixed Variable to check
61
 *
62
 * @return bool true: $mixed is *not* an empty string; false: $mixed *is* an empty string
63
 */
64
function gravityview_is_not_empty_string( $mixed = '' ) {
65 1
	return ( $mixed !== '' );
66
}
67
68
/**
69
 * Get `get_permalink()` without the home_url() prepended to it.
70
 *
71
 * get_permalink() does a lot of good stuff: it gets the correct permalink structure for custom post types, pages,
72
 * posts, etc. Instead of using `?p={id}`, `?page_id={id}`, or `?p={id}&post_type={post_type}`, by using
73
 * get_permalink(), we can use `?p=slug` or `?gravityview={slug}`
74
 *
75
 * We could do this in a cleaner fashion, but this prevents a lot of code duplication, checking for URL structure, etc.
76
 *
77
 * @param int|WP_Post $id        Optional. Post ID or post object. Default current post.
78
 *
79
 * @return array URL args, if exists. Empty array if not.
80
 */
81
function gravityview_get_permalink_query_args( $id = 0 ) {
82
83
	$parsed_permalink = parse_url( get_permalink( $id ) );
84
85
	$permalink_args =  isset( $parsed_permalink['query'] ) ? $parsed_permalink['query'] : false;
0 ignored issues
show
introduced by
Expected 1 space after "="; 2 found
Loading history...
86
87
	if( empty( $permalink_args ) ) {
88
		return array();
89
	}
90
91
	parse_str( $permalink_args, $args );
92
93
	return $args;
94
}
95
96
97
/**
98
 * Similar to the WordPress `selected()`, `checked()`, and `disabled()` functions, except it allows arrays to be passed as current value
99
 *
100
 * @see selected() WordPress core function
101
 *
102
 * @param string $value One of the values to compare
103
 * @param mixed $current (true) The other value to compare if not just true
104
 * @param bool $echo Whether to echo or just return the string
105
 * @param string $type The type of checked|selected|disabled we are doing
106
 *
107
 * @return string html attribute or empty string
108
 */
109
function gv_selected( $value, $current, $echo = true, $type = 'selected' ) {
110
111
	$output = '';
112
	if( is_array( $current ) ) {
113
		if( in_array( $value, $current ) ) {
114
			$output = __checked_selected_helper( true, true, false, $type );
115
		}
116
	} else {
117
		$output = __checked_selected_helper( $value, $current, false, $type );
118
	}
119
120
	if( $echo ) {
121
		echo $output;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$output'
Loading history...
122
	}
123
124
	return $output;
125
}
126
127
128
if( ! function_exists( 'gravityview_sanitize_html_class' ) ) {
129
130
	/**
131
	 * sanitize_html_class doesn't handle spaces (multiple classes). We remedy that.
132
	 *
133
	 * @uses sanitize_html_class
134
	 *
135
	 * @param  string|array $classes Text or array of classes to sanitize
136
	 *
137
	 * @return string            Sanitized CSS string
138
	 */
139
	function gravityview_sanitize_html_class( $classes ) {
140
141 1
		if ( is_string( $classes ) ) {
142 1
			$classes = explode( ' ', $classes );
143
		}
144
145
		// If someone passes something not string or array, we get outta here.
146 1
		if ( ! is_array( $classes ) ) {
147
			return $classes;
148
		}
149
150 1
		$classes = array_map( 'trim', $classes );
151 1
		$classes = array_map( 'sanitize_html_class', $classes );
152 1
		$classes = array_filter( $classes );
153
154 1
		return implode( ' ', $classes );
155
	}
156
}
157
158
/**
159
 * Replace multiple newlines, tabs, and spaces with a single space
160
 *
161
 * First, runs normalize_whitespace() on a string. This replaces multiple lines with a single line, and tabs with spaces.
162
 * We then strip any tabs or newlines and replace *those* with a single space.
163
 *
164
 * @see normalize_whitespace()
165
 * @see GravityView_Helper_Functions_Test::test_gravityview_strip_whitespace
166
 * @since 1.13
167
 *
168
 * @param string $string String to strip whitespace from
169
 *
170
 * @return string Stripped string!
171
 */
172
function gravityview_strip_whitespace( $string ) {
173 4
	$string = normalize_whitespace( $string );
174 4
	return preg_replace('/[\r\n\t ]+/', ' ', $string );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
175
}
176
177
/**
178
 * Get the contents of a file using `include()` and `ob_start()`
179
 *
180
 * @since 1.13
181
 * @since 1.15 Added $object param
182
 *
183
 * @param string $file_path Full path to a file
184
 * @param mixed $object Pass pseudo-global to the included file
185
 * @return string Included file contents
186
 */
187
function gravityview_ob_include( $file_path, $object = NULL ) {
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
188 3
	if( ! file_exists( $file_path ) ) {
189
		do_action( 'gravityview_log_error', __FUNCTION__ . ': File path does not exist. ', $file_path );
190
		return '';
191
	}
192 3
	ob_start();
193 3
	include( $file_path );
194 3
	return ob_get_clean();
195
}
196
197
/**
198
 * Get an image of our intrepid explorer friend
199
 * @since 1.12
200
 * @return string HTML image tag with floaty's cute mug on it
201
 */
202
function gravityview_get_floaty( $height = 87 ) {
203
204
	$width = $height * 0.7586206897;
205
206
	if( function_exists('is_rtl') && is_rtl() ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
207
		$style = 'margin:10px 10px 10px 0;';
208
		$class = 'alignright';
209
	} else {
210
		$style = 'margin:10px 10px 10px 0;';
211
		$class = 'alignleft';
212
	}
213
214
	return '<img src="'.plugins_url( 'assets/images/astronaut-200x263.png', GRAVITYVIEW_FILE ).'" class="'.$class.'" height="'.intval( $height ).'" width="'.round( $width, 2 ).'" alt="The GravityView Astronaut Says:" style="'.$style.'" />';
215
}
216
217
/**
218
 * Intelligently format a number
219
 *
220
 * If you don't define the number of decimal places, then it will use the existing number of decimal places. This is done
221
 * in a way that respects the localization of the site.
222
 *
223
 * If you do define decimals, it uses number_format_i18n()
224
 *
225
 * @see number_format_i18n()
226
 *
227
 * @since 1.13
228
 *
229
 * @param int|float|string|double $number A number to format
230
 * @param int|string $decimals Optional. Precision of the number of decimal places. Default '' (use existing number of decimals)
231
 *
232
 * @return string Converted number in string format.
233
 */
234
function gravityview_number_format( $number, $decimals = '' ) {
235 11
	global $wp_locale;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
236
237 11
	if( '' === $decimals ) {
238
239 11
		$decimal_point = isset( $wp_locale ) ? $wp_locale->number_format['decimal_point'] : '.';
240
241
		/**
242
		 * Calculate the position of the decimal point in the number
243
		 * @see http://stackoverflow.com/a/2430144/480856
244
		 */
245 11
		$decimals = strlen( substr( strrchr( $number, $decimal_point ), 1 ) );
246
	}
247
248 11
	$number = number_format_i18n( $number, (int)$decimals );
0 ignored issues
show
introduced by
No space after closing casting parenthesis is prohibited
Loading history...
249
250 11
	return $number;
251
}
252
253
254
/**
255
 * Convert a whole link into a shorter link for display
256
 *
257
 * @since 1.1
258
 *
259
 * @param  string $value Existing URL
260
 * @return string        If parse_url doesn't find a 'host', returns original value. Otherwise, returns formatted link.
261
 */
262
function gravityview_format_link( $value = null ) {
263
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
264
265 4
	$parts = parse_url( $value );
266
267
	// No domain? Strange...show the original text.
268 4
	if( empty( $parts['host'] ) ) {
269 2
		return $value;
270
	}
271
272
	// Start with empty value for the return URL
273 4
	$return = '';
274
275
	/**
276
	 * @filter `gravityview_anchor_text_striphttp` Strip scheme from the displayed URL?
277
	 * @since 1.5.1
278
	 * @param boolean $enable Whether to strip the scheme. Return false to show scheme. (default: true)\n
279
	 * If true: `http://example.com => example.com`
280
	 */
281 4
	if( false === apply_filters('gravityview_anchor_text_striphttp', true) ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
282
283
		if( isset( $parts['scheme'] ) ) {
284
			$return .= $parts['scheme'];
285
		}
286
287
	}
288
289
	// The domain, which may contain a subdomain
290 4
	$domain = $parts['host'];
291
292
	/**
293
	 * @filter `gravityview_anchor_text_stripwww` Strip www from the domain?
294
	 * @since 1.5.1
295
	 * @param boolean $enable Whether to strip www. Return false to show www. (default: true)\n
296
	 * If true: `www.example.com => example.com`
297
	 */
298 4
	$strip_www = apply_filters('gravityview_anchor_text_stripwww', true );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
299
300 4
	if( $strip_www ) {
301 4
		$domain = str_replace('www.', '', $domain );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
302
	}
303
304
	/**
305
	 * @filter `gravityview_anchor_text_nosubdomain` Strip subdomains from the domain?
306
	 * @since 1.5.1
307
	 * @param boolean $enable Whether to strip subdomains. Return false to show subdomains. (default: true)\n
308
	 * If true: `http://demo.example.com => example.com` \n
309
	 * If false: `http://demo.example.com => demo.example.com`
310
	 */
311 4
	$strip_subdomains = apply_filters('gravityview_anchor_text_nosubdomain', true);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
312
313 4
	if( $strip_subdomains ) {
314
315 3
		$domain = _gravityview_strip_subdomain( $parts['host'] );
316
317
	}
318
319
	// Add the domain
320 4
	$return .= $domain;
321
322
	/**
323
	 * @filter `gravityview_anchor_text_rootonly` Display link path going only to the base directory, not a sub-directory or file?
324
	 * @since 1.5.1
325
	 * @param boolean $enable Whether to enable "root only". Return false to show full path. (default: true)\n
326
	 * If true: `http://example.com/sub/directory/page.html => example.com`  \n
327
	 * If false: `http://example.com/sub/directory/page.html => example.com/sub/directory/page.html`
328
	 */
329 4
	$root_only = apply_filters('gravityview_anchor_text_rootonly', true);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
330
331 4
	if( empty( $root_only ) ) {
332
333 1
		if( isset( $parts['path'] ) ) {
334 1
			$return .= $parts['path'];
335
		}
336
	}
337
338
	/**
339
	 * @filter `gravityview_anchor_text_noquerystring` Strip the query string from the end of the URL?
340
	 * @since 1.5.1
341
	 * @param boolean $enable Whether to enable "root only". Return false to show full path. (default: true)\n
342
	 * If true: `http://example.com/?query=example => example.com`
343
	 */
344 4
	$strip_query_string = apply_filters('gravityview_anchor_text_noquerystring', true );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
345
346 4
	if( empty( $strip_query_string ) ) {
347
348 1
		if( isset( $parts['query'] ) ) {
349 1
			$return .= '?'.$parts['query'];
350
		}
351
352
	}
353
354 4
	return $return;
355
}
356
357
/**
358
 * Do a _very_ basic match for second-level TLD domains, like `.co.uk`
359
 *
360
 * Ideally, we'd use https://github.com/jeremykendall/php-domain-parser to check for this, but it's too much work for such a basic functionality. Maybe if it's needed more in the future. So instead, we use [Basic matching regex](http://stackoverflow.com/a/12372310).
361
 * @param  string $domain Domain to check if it's a TLD or subdomain
0 ignored issues
show
Documentation introduced by
There is no parameter named $domain. Did you maybe mean $string_maybe_has_subdomain?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
362
 * @return string         Extracted domain if it has a subdomain
363
 */
364
function _gravityview_strip_subdomain( $string_maybe_has_subdomain ) {
365
366 1
	if( preg_match("/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.(?:com\.|co\.|net\.|org\.|firm\.|me\.|school\.|law\.|gov\.|mod\.|msk\.|irkutsks\.|sa\.|act\.|police\.|plc\.|ac\.|tm\.|asso\.|biz\.|pro\.|cg\.|telememo\.)?[a-z\.]{2,6})$/i", $string_maybe_has_subdomain, $matches ) ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style Comprehensibility introduced by
The string literal /(?P<domain>[a-z0-9][a-z...emo\.)?[a-z\.]{2,6})$/i does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
367 1
		return $matches['domain'];
368
	} else {
369
		return $string_maybe_has_subdomain;
370
	}
371
}
372
373
/**
374
 * Is the value empty?
375
 *
376
 * Allows you to pass a function instead of just a variable, like the empty() function insists upon (until PHP 5.5)
377
 *
378
 * Checks whether `false`, `null`, empty string, empty array, object with no vars defined
379
 *
380
 * @since 1.15.1
381
 * @param  mixed  $value Check whether this is empty
382
 * @param boolean $zero_is_empty Should the number zero be treated as an empty value?
383
 * @param boolean $allow_string_booleans Whether to check if 'yes', 'true' => `true` and 'no', 'false' => `false`
384
 * @return boolean        True: empty; false: not empty
385
 */
386
function gv_empty( $value, $zero_is_empty = true, $allow_string_booleans = true ) {
387
388
	/**
389
	 * Arrays with empty values are empty.
390
	 *
391
	 * Consider the a missing product field.
392
	 */
393 4
	if ( is_array( $value ) ) {
394 1
		$values = array();
395 1
		foreach ( $value as $v ) {
396 1
			if ( ! gv_empty( $v, $zero_is_empty, $allow_string_booleans ) ) {
397 1
				return false;
398
			}
399
		}
400 1
		return true;
401
	}
402
403
	if (
404 4
		! isset( $value ) // If it's not set, it's empty!
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
405 4
		|| false === $value
406 4
		|| null === $value
407 4
	    || '' === $value // Empty string
408 4
		|| array() === $value // Empty array
409 4
		|| ( is_object( $value ) && ! get_object_vars( $value ) ) // Empty object
410
	) {
411 2
		return true;
412
	}
413
414 4
	if ( is_string( $value ) && $allow_string_booleans ) {
415
416 1
		$value = trim( $value );
417 1
		$value = strtolower( $value );
418
419 1
		if ( in_array( $value, array( 'yes', 'true' ), true ) ) {
420
			$value = true;
421 1
		} else if( in_array( $value, array( 'no', 'false' ), true ) ) {
422 1
			$value = false;
423
		}
424
	}
425
426
	// If zero isn't empty, then if $value is a number and it's empty, it's zero. Thus, return false.
427 4
	if ( ! $zero_is_empty && is_numeric( $value ) && empty( $value ) ) {
428 1
		return false;
429
	}
430
431 4
	return empty( $value );
432
}
433
434
435
/**
436
 * Maps a function to all non-iterable elements of an array or an object.
437
 *
438
 * @see map_deep() This is an alias of the WP core function `map_deep()`, added in 4.4. Here for legacy purposes.
439
 * @since 1.16.3
440
 *
441
 * @param mixed    $value    The array, object, or scalar.
442
 * @param callable $callback The function to map onto $value.
443
 *
444
 * @return mixed The value with the callback applied to all non-arrays and non-objects inside it.
445
 */
446
function gv_map_deep( $value, $callback ) {
447
448
	// Use the original function, if exists.
449
	// Requires WP 4.4+
450
	if( function_exists( 'map_deep') ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
451
		return map_deep( $value, $callback );
452
	}
453
454
	// Exact copy of map_deep() code below:
455
	if ( is_array( $value ) ) {
456
		foreach ( $value as $index => $item ) {
457
			$value[ $index ] = gv_map_deep( $item, $callback );
458
		}
459
	} elseif ( is_object( $value ) ) {
460
		$object_vars = get_object_vars( $value );
461
		foreach ( $object_vars as $property_name => $property_value ) {
462
			$value->$property_name = gv_map_deep( $property_value, $callback );
463
		}
464
	} else {
465
		$value = call_user_func( $callback, $value );
466
	}
467
468
	return $value;
469
}
470
471
/**
472
 * Check whether a string is a expected date format
473
 *
474
 * @since 1.15.2
475
 *
476
 * @param string $datetime The date to check
477
 * @param string $expected_format Check whether the date is formatted as expected. Default: Y-m-d
478
 *
479
 * @return bool True: it's a valid datetime, formatted as expected. False: it's not a date formatted as expected.
480
 */
481
function gravityview_is_valid_datetime( $datetime, $expected_format = 'Y-m-d' ) {
482
483
	/**
484
	 * @var bool|DateTime False if not a valid date, (like a relative date). DateTime if a date was created.
485
	 */
486 1
	$formatted_date = DateTime::createFromFormat( $expected_format, $datetime );
0 ignored issues
show
Bug introduced by
The method createFromFormat() does not exist on DateTime. Did you maybe mean format()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
487
488
	/**
489
	 * @see http://stackoverflow.com/a/19271434/480856
490
	 */
491 1
	return ( $formatted_date && $formatted_date->format( $expected_format ) === $datetime );
492
}
493
494
/**
495
 * Very commonly needed: get the # of the input based on a full field ID.
496
 *
497
 * Example: 12.3 => field #12, input #3. Returns: 3
498
 * Example: 7 => field #7, no input. Returns: 0
499
 *
500
 * @since 1.16.4
501
 *
502
 * @param string $field_id Full ID of field, with or without input ID, like "12.3" or "7".
503
 *
504
 * @return int If field ID has an input, returns that input number. Otherwise, returns false.
505
 */
506
function gravityview_get_input_id_from_id( $field_id = '' ) {
507
508 1
	if ( ! is_numeric( $field_id ) ) {
509 1
		do_action( 'gravityview_log_error', __FUNCTION__ . ': $field_id not numeric', $field_id );
510 1
		return false;
511
	}
512
513 1
	$exploded = explode( '.', "{$field_id}" );
514
515 1
	return isset( $exploded[1] ) ? intval( $exploded[1] ) : false;
516
}
517
518
/**
519
 * Get categories formatted in a way used by GravityView and Gravity Forms input choices
520
 *
521
 * @since 1.15.3
522
 *
523
 * @see get_terms()
524
 *
525
 * @param array $args Arguments array as used by the get_terms() function. Filtered using `gravityview_get_terms_choices_args` filter. Defaults: { \n
526
 *   @type string $taxonomy Used as first argument in get_terms(). Default: "category"
527
 *   @type string $fields Default: 'id=>name' to only fetch term ID and Name \n
528
 *   @type int $number  Limit the total number of terms to fetch. Default: 1000 \n
529
 * }
530
 *
531
 * @return array Multidimensional array with `text` (Category Name) and `value` (Category ID) keys.
532
 */
533
function gravityview_get_terms_choices( $args = array() ) {
534
535
	$defaults = array(
536
		'type'         => 'post',
537
		'child_of'     => 0,
538
		'number'       => 1000, // Set a reasonable max limit
539
		'orderby'      => 'name',
540
		'order'        => 'ASC',
541
		'hide_empty'   => 0,
542
		'hierarchical' => 1,
543
		'taxonomy'     => 'category',
544
		'fields'       => 'id=>name',
545
	);
546
547
	$args = wp_parse_args( $args, $defaults );
548
549
	/**
550
	 * @filter `gravityview_get_terms_choices_args` Modify the arguments passed to `get_terms()`
551
	 * @see get_terms()
552
	 * @since 1.15.3
553
	 */
554
	$args = apply_filters( 'gravityview_get_terms_choices_args', $args );
555
556
	$terms = get_terms( $args['taxonomy'], $args );
557
558
	$choices = array();
559
560
	if ( is_array( $terms ) ) {
561
		foreach ( $terms as $term_id => $term_name ) {
562
			$choices[] = array(
563
				'text'  => $term_name,
564
				'value' => $term_id
0 ignored issues
show
introduced by
Each line in an array declaration must end in a comma
Loading history...
565
			);
566
		}
567
	}
568
569
	return $choices;
570
}
571
572
/**
573
 * Maybe convert jQuery-serialized fields into array, otherwise return $_POST['fields'] array
574
 *
575
 * Fields are passed as a jQuery-serialized array, created in admin-views.js in the serializeForm method.
576
 *
577
 * @since 1.16.5
578
 *
579
 * @uses GVCommon::gv_parse_str
580
 *
581
 * @return array Array of fields
582
 */
583
function _gravityview_process_posted_fields() {
584
	$fields = array();
585
586
	if( !empty( $_POST['gv_fields'] ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
587
		if ( ! is_array( $_POST['gv_fields'] ) ) {
588
589
			// We are not using parse_str() due to max_input_vars limitation with large View configurations
590
			$fields_holder = array();
591
			GVCommon::gv_parse_str( $_POST['gv_fields'], $fields_holder );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
592
593
			if ( isset( $fields_holder['fields'] ) ) {
594
				$fields = $fields_holder['fields'];
595
			} else {
596
				do_action( 'gravityview_log_error', '[save_postdata] No `fields` key was found after parsing $fields string', $fields_holder );
597
			}
598
599
		} else {
600
			$fields = $_POST['gv_fields'];
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
601
		}
602
	}
603
604
	return $fields;
605
}
606