Completed
Pull Request — develop (#1433)
by Zack
07:05
created

helper-functions.php ➔ gravityview_format_date()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 7.9297

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 2
dl 0
loc 21
ccs 2
cts 11
cp 0.1818
crap 7.9297
rs 9.584
c 0
b 0
f 0
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
		gravityview()->log->debug( 'Stylesheet override ({css_file})', array( 'css_file' => 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 5
	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 4
	$parsed_permalink = parse_url( get_permalink( $id ) );
84
85 4
	$permalink_args =  isset( $parsed_permalink['query'] ) ? $parsed_permalink['query'] : false;
86
87 4
	if( empty( $permalink_args ) ) {
88
		return array();
89
	}
90
91 4
	parse_str( $permalink_args, $args );
92
93 4
	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;
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 60
		if ( is_string( $classes ) ) {
142 60
			$classes = explode( ' ', $classes );
143
		}
144
145
		// If someone passes something not string or array, we get outta here.
146 60
		if ( ! is_array( $classes ) ) {
147
			return $classes;
148
		}
149
150 60
		$classes = array_map( 'trim', $classes );
151 60
		$classes = array_map( 'sanitize_html_class', $classes );
152 60
		$classes = array_filter( $classes );
153
154 60
		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 24
	$string = normalize_whitespace( $string );
174 24
	return preg_replace('/[\r\n\t ]+/', ' ', $string );
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 ) {
188 22
	if( ! file_exists( $file_path ) ) {
189
		gravityview()->log->error( 'File path does not exist. {path}', array( 'path' => $file_path ) );
190
		return '';
191
	}
192 22
	ob_start();
193 22
	include( $file_path );
194 22
	return ob_get_clean();
195
}
196
197
/**
198
 * Get an image of our intrepid explorer friend
199
 *
200
 * @since 1.12
201
 * @since 2.1 Added $class parameter
202
 *
203
 * @param int $height Height of the cutie in pixels
204
 * @param null|string $css_class If defined, use the passed CSS class (can be empty string). Otherwise, use default alignleft (or alignright, based on RTL).
205
 *
206
 * @return string HTML image tag with floaty's cute mug on it
207
 */
208
function gravityview_get_floaty( $height = 87, $css_class = null ) {
209
210 2
	$width = $height * 0.7586206897;
211
212 2
	if( function_exists('is_rtl') && is_rtl() ) {
213
		$style = 'margin:10px 10px 10px 0; height='. $height .'px; width: '. $width .'px;';
214
		$css_class = is_string( $css_class ) ? $css_class : 'alignright';
215
	} else {
216 2
		$style = 'margin:10px 10px 10px 0; height='. $height .'px; width: '. $width .'px;';
217 2
		$css_class = is_string( $css_class ) ? $css_class : 'alignleft';
218
	}
219
220 2
	return '<img src="'. esc_url( plugins_url( 'assets/images/astronaut-200x263.png', GRAVITYVIEW_FILE ) ) .'" class="'. gravityview_sanitize_html_class( $css_class ).'" height="'.intval( $height ).'" width="'.round( $width, 2 ).'" alt="The GravityView Astronaut Says:" style="'.$style.'" />';
221
}
222
223
/**
224
 * Intelligently format a number
225
 *
226
 * If you don't define the number of decimal places, then it will use the existing number of decimal places. This is done
227
 * in a way that respects the localization of the site.
228
 *
229
 * If you do define decimals, it uses number_format_i18n()
230
 *
231
 * @see number_format_i18n()
232
 *
233
 * @since 1.13
234
 *
235
 * @param int|float|string|double $number A number to format
236
 * @param int|string $decimals Optional. Precision of the number of decimal places. Default '' (use existing number of decimals)
237
 * @param boolean $separator Separate with dots or commas, etc. Default: true.
238
 *
239
 * @return string Converted number in string format.
240
 */
241
function gravityview_number_format( $number, $decimals = '', $separator = true ) {
242 211
	global $wp_locale;
243
244 211
	if( '' === $decimals ) {
245
246 211
		$decimal_point = isset( $wp_locale ) ? $wp_locale->number_format['decimal_point'] : '.';
247
248
		/**
249
		 * Calculate the position of the decimal point in the number
250
		 * @see http://stackoverflow.com/a/2430144/480856
251
		 */
252 211
		$decimals = strlen( substr( strrchr( $number, $decimal_point ), 1 ) );
253
	}
254
255 211
	if ( $separator ) {
256 211
		$number = number_format_i18n( $number, (int)$decimals );
257
	} else {
258 7
		$number = sprintf( "%.{$decimals}f", $number );
259
	}
260
261 211
	return $number;
262
}
263
264
265
/**
266
 * Convert a whole link into a shorter link for display
267
 *
268
 * @since 1.1
269
 *
270
 * @param  string $value Existing URL
271
 * @return string        If parse_url doesn't find a 'host', returns original value. Otherwise, returns formatted link.
272
 */
273
function gravityview_format_link( $value = null ) {
274
275
276 5
	$parts = parse_url( $value );
277
278
	// No domain? Strange...show the original text.
279 5
	if( empty( $parts['host'] ) ) {
280 2
		return $value;
281
	}
282
283
	// Start with empty value for the return URL
284 5
	$return = '';
285
286
	/**
287
	 * @filter `gravityview_anchor_text_striphttp` Strip scheme from the displayed URL?
288
	 * @since 1.5.1
289
	 * @param boolean $enable Whether to strip the scheme. Return false to show scheme. (default: true)\n
290
	 * If true: `http://example.com => example.com`
291
	 */
292 5
	if( false === apply_filters('gravityview_anchor_text_striphttp', true) ) {
293
294
		if( isset( $parts['scheme'] ) ) {
295
			$return .= $parts['scheme'];
296
		}
297
298
	}
299
300
	// The domain, which may contain a subdomain
301 5
	$domain = $parts['host'];
302
303
	/**
304
	 * @filter `gravityview_anchor_text_stripwww` Strip www from the domain?
305
	 * @since 1.5.1
306
	 * @param boolean $enable Whether to strip www. Return false to show www. (default: true)\n
307
	 * If true: `www.example.com => example.com`
308
	 */
309 5
	$strip_www = apply_filters('gravityview_anchor_text_stripwww', true );
310
311 5
	if( $strip_www ) {
312 5
		$domain = str_replace('www.', '', $domain );
313
	}
314
315
	/**
316
	 * @filter `gravityview_anchor_text_nosubdomain` Strip subdomains from the domain?
317
	 * @since 1.5.1
318
	 * @param boolean $enable Whether to strip subdomains. Return false to show subdomains. (default: true)\n
319
	 * If true: `http://demo.example.com => example.com` \n
320
	 * If false: `http://demo.example.com => demo.example.com`
321
	 */
322 5
	$strip_subdomains = apply_filters('gravityview_anchor_text_nosubdomain', true);
323
324 5
	if( $strip_subdomains ) {
325
326 4
		$domain = _gravityview_strip_subdomain( $parts['host'] );
327
328
	}
329
330
	// Add the domain
331 5
	$return .= $domain;
332
333
	/**
334
	 * @filter `gravityview_anchor_text_rootonly` Display link path going only to the base directory, not a sub-directory or file?
335
	 * @since 1.5.1
336
	 * @param boolean $enable Whether to enable "root only". Return false to show full path. (default: true)\n
337
	 * If true: `http://example.com/sub/directory/page.html => example.com`  \n
338
	 * If false: `http://example.com/sub/directory/page.html => example.com/sub/directory/page.html`
339
	 */
340 5
	$root_only = apply_filters('gravityview_anchor_text_rootonly', true);
341
342 5
	if( empty( $root_only ) ) {
343
344 1
		if( isset( $parts['path'] ) ) {
345 1
			$return .= $parts['path'];
346
		}
347
	}
348
349
	/**
350
	 * @filter `gravityview_anchor_text_noquerystring` Strip the query string from the end of the URL?
351
	 * @since 1.5.1
352
	 * @param boolean $enable Whether to enable "root only". Return false to show full path. (default: true)\n
353
	 * If true: `http://example.com/?query=example => example.com`
354
	 */
355 5
	$strip_query_string = apply_filters('gravityview_anchor_text_noquerystring', true );
356
357 5
	if( empty( $strip_query_string ) ) {
358
359 1
		if( isset( $parts['query'] ) ) {
360 1
			$return .= '?'.$parts['query'];
361
		}
362
363
	}
364
365 5
	return $return;
366
}
367
368
/**
369
 * Do a _very_ basic match for second-level TLD domains, like `.co.uk`
370
 *
371
 * 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).
372
 * @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...
373
 * @return string         Extracted domain if it has a subdomain
374
 */
375
function _gravityview_strip_subdomain( $string_maybe_has_subdomain ) {
376
377 2
	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 ) ) {
378 2
		return $matches['domain'];
379
	} else {
380
		return $string_maybe_has_subdomain;
381
	}
382
}
383
384
/**
385
 * The inverse of gv_empty()
386
 *
387
 * @since 2.0
388
 *
389
 * @param mixed  $value Check whether this is not empty
390
 * @param bool $zero_is_empty Should the number zero be treated as an empty value? Default: `false`
391
 * @param bool $allow_string_booleans Whether to check if 'yes', 'true' => `true` and 'no', 'false' => `false`. Default: `false`
392
 *
393
 * @return bool
394
 */
395
function gv_not_empty( $value, $zero_is_empty = false, $allow_string_booleans = false ) {
396
	return ! gv_empty( $value, $zero_is_empty, $allow_string_booleans );
397
}
398
399
/**
400
 * Is the value empty?
401
 *
402
 * Allows you to pass a function instead of just a variable, like the empty() function insists upon (until PHP 5.5)
403
 *
404
 * Checks whether `false`, `null`, empty string, empty array, object with no vars defined
405
 *
406
 * @since 1.15.1
407
 * @param  mixed  $value Check whether this is empty
408
 * @param boolean $zero_is_empty Should the number zero be treated as an empty value?
409
 * @param boolean $allow_string_booleans Whether to check if 'yes', 'true' => `true` and 'no', 'false' => `false`
410
 * @return boolean        True: empty; false: not empty
411
 */
412
function gv_empty( $value, $zero_is_empty = true, $allow_string_booleans = true ) {
413
414
	/**
415
	 * Arrays with empty values are empty.
416
	 *
417
	 * Consider the a missing product field.
418
	 */
419 48
	if ( is_array( $value ) ) {
420 3
		$values = array();
421 3
		foreach ( $value as $v ) {
422 3
			if ( ! gv_empty( $v, $zero_is_empty, $allow_string_booleans ) ) {
423 3
				return false;
424
			}
425
		}
426 3
		return true;
427
	}
428
429
	if (
430 48
		! isset( $value ) // If it's not set, it's empty!
431 48
		|| false === $value
432 48
		|| null === $value
433 48
	    || '' === $value // Empty string
434 48
		|| array() === $value // Empty array
435 48
		|| ( is_object( $value ) && ! get_object_vars( $value ) ) // Empty object
436
	) {
437 13
		return true;
438
	}
439
440 48
	if ( is_string( $value ) && $allow_string_booleans ) {
441
442 1
		$value = trim( $value );
443 1
		$value = strtolower( $value );
444
445 1
		if ( in_array( $value, array( 'yes', 'true' ), true ) ) {
446
			$value = true;
447 1
		} else if( in_array( $value, array( 'no', 'false' ), true ) ) {
448 1
			$value = false;
449
		}
450
	}
451
452
	// If zero isn't empty, then if $value is a number and it's empty, it's zero. Thus, return false.
453 48
	if ( ! $zero_is_empty && is_numeric( $value ) && empty( $value ) ) {
454 2
		return false;
455
	}
456
457 48
	return empty( $value );
458
}
459
460
/**
461
 * If content is JSON, decode it. Otherwise, return the passed value
462
 *
463
 * @since 2.0
464
 *
465
 * @see json_decode() for more information about the function parameters
466
 *
467
 * @param string $value The string that may be decoded
468
 * @param bool $assoc [optional] When `true`, returned objects will be converted into associative arrays
469
 * @param int $depth [optional] User specified recursion depth.
470
 * @param int $options [optional] Bitmask of JSON decode options. Used only on sites running PHP 5.4+
471
 *
472
 * @return array|mixed|object|string If $value is JSON, returns the response from `json_decode()`. Otherwise, returns original value.
473
 */
474
function gv_maybe_json_decode( $value, $assoc = false, $depth = 512, $options = 0 ) {
475
476
	if( ! is_string( $value ) ) {
477
		return $value;
478
	}
479
480
	if ( version_compare( phpversion(), '5.4.0', '>=' ) ) {
481
		$decoded = json_decode( $value, $assoc, $depth, $options );
482
	} else {
483
		$decoded = json_decode( $value, $assoc, $depth );
484
	}
485
486
	// There was a JSON error (PHP 5.3+)
487
	if( function_exists('json_last_error') && JSON_ERROR_NONE !== json_last_error() ) {
488
		return $value;
489
	}
490
491
	// It wasn't JSON (PHP < 5.3 fallback)
492
	if( is_null( $decoded ) ) {
493
		return $value;
494
	}
495
496
	return $decoded;
497
}
498
499
500
/**
501
 * Maps a function to all non-iterable elements of an array or an object.
502
 *
503
 * @see map_deep() This is an alias of the WP core function `map_deep()`, added in 4.4. Here for legacy purposes.
504
 * @since 1.16.3
505
 *
506
 * @param mixed    $value    The array, object, or scalar.
507
 * @param callable $callback The function to map onto $value.
508
 *
509
 * @return mixed The value with the callback applied to all non-arrays and non-objects inside it.
510
 */
511
function gv_map_deep( $value, $callback ) {
512
513
	// Use the original function, if exists.
514
	// Requires WP 4.4+
515 48
	if( function_exists( 'map_deep') ) {
516 48
		return map_deep( $value, $callback );
517
	}
518
519
	// Exact copy of map_deep() code below:
520
	if ( is_array( $value ) ) {
521
		foreach ( $value as $index => $item ) {
522
			$value[ $index ] = gv_map_deep( $item, $callback );
523
		}
524
	} elseif ( is_object( $value ) ) {
525
		$object_vars = get_object_vars( $value );
526
		foreach ( $object_vars as $property_name => $property_value ) {
527
			$value->$property_name = gv_map_deep( $property_value, $callback );
528
		}
529
	} else {
530
		$value = call_user_func( $callback, $value );
531
	}
532
533
	return $value;
534
}
535
536
/**
537
 * Check whether a string is a expected date format
538
 *
539
 * @since 1.15.2
540
 *
541
 * @param string $datetime The date to check
542
 * @param string $expected_format Check whether the date is formatted as expected. Default: Y-m-d
543
 *
544
 * @return bool True: it's a valid datetime, formatted as expected. False: it's not a date formatted as expected.
545
 */
546
function gravityview_is_valid_datetime( $datetime, $expected_format = 'Y-m-d' ) {
547
548
	/**
549
	 * @var bool|DateTime False if not a valid date, (like a relative date). DateTime if a date was created.
550
	 */
551 1
	$formatted_date = DateTime::createFromFormat( $expected_format, $datetime );
552
553
	/**
554
	 * @see http://stackoverflow.com/a/19271434/480856
555
	 */
556 1
	return ( $formatted_date && $formatted_date->format( $expected_format ) === $datetime );
557
}
558
559
/**
560
 * Format date according to locale and using the timezone offset
561
 *
562
 * `wp_date()` is used if available; otherwise, timezone offset is added to the timestamp before it is passed to `date_i18n()`
563
 *
564
 * @since 2.7.2
565
 *
566
 * @param string $format Date format
567
 * @param string $timestamp Timestamp
568
 *
569
 * @return string|false Formatted date or false if the timestamp is invalid
570
 */
571
function gravityview_format_date( $format, $timestamp ) {
572
573 3
	if ( function_exists( 'wp_date' ) ) {
574 3
		return wp_date( $format, $timestamp );
575
	}
576
577
	$timezone_str = get_option( 'timezone_string' ) ?: 'UTC';
578
	$timezone     = new \DateTimeZone( $timezone_str );
579
580
	// Get date in local TZ
581
	$date = new \DateTime( null, $timezone );
582
	$date->setTimestamp( $timestamp );
583
	$date_str = $date->format( 'Y-m-d H:i:s' );
584
585
	//  Get UTC timestamp
586
	$utc_timezone = new \DateTimeZone( 'UTC' );
587
	$utc_date     = new \DateTime( $date_str, $utc_timezone );
588
	$timestamp    = $utc_date->getTimestamp();
589
590
	return date_i18n( $format, $timestamp );
591
}
592
593
/**
594
 * Very commonly needed: get the # of the input based on a full field ID.
595
 *
596
 * Example: 12.3 => field #12, input #3. Returns: 3
597
 * Example: 7 => field #7, no input. Returns: 0
598
 *
599
 * @since 1.16.4
600
 *
601
 * @param string $field_id Full ID of field, with or without input ID, like "12.3" or "7".
602
 *
603
 * @return int If field ID has an input, returns that input number. Otherwise, returns false.
604
 */
605
function gravityview_get_input_id_from_id( $field_id = '' ) {
606
607 10
	if ( ! is_numeric( $field_id ) ) {
608 1
		gravityview()->log->error( '$field_id not numeric', array( 'data' => $field_id ) );
609 1
		return false;
610
	}
611
612 10
	$exploded = explode( '.', "{$field_id}" );
613
614 10
	return isset( $exploded[1] ) ? intval( $exploded[1] ) : false;
615
}
616
617
/**
618
 * Get categories formatted in a way used by GravityView and Gravity Forms input choices
619
 *
620
 * @since 1.15.3
621
 *
622
 * @see get_terms()
623
 *
624
 * @param array $args Arguments array as used by the get_terms() function. Filtered using `gravityview_get_terms_choices_args` filter. Defaults: { \n
625
 *   @type string $taxonomy Used as first argument in get_terms(). Default: "category"
626
 *   @type string $fields Default: 'id=>name' to only fetch term ID and Name \n
627
 *   @type int $number  Limit the total number of terms to fetch. Default: 1000 \n
628
 * }
629
 *
630
 * @return array Multidimensional array with `text` (Category Name) and `value` (Category ID) keys.
631
 */
632
function gravityview_get_terms_choices( $args = array() ) {
633
634
	$defaults = array(
635
		'type'         => 'post',
636
		'child_of'     => 0,
637
		'number'       => 1000, // Set a reasonable max limit
638
		'orderby'      => 'name',
639
		'order'        => 'ASC',
640
		'hide_empty'   => 0,
641
		'hierarchical' => 1,
642
		'taxonomy'     => 'category',
643
		'fields'       => 'id=>name',
644
	);
645
646
	$args = wp_parse_args( $args, $defaults );
647
648
	/**
649
	 * @filter `gravityview_get_terms_choices_args` Modify the arguments passed to `get_terms()`
650
	 * @see get_terms()
651
	 * @since 1.15.3
652
	 */
653
	$args = apply_filters( 'gravityview_get_terms_choices_args', $args );
654
655
	$terms = get_terms( $args['taxonomy'], $args );
656
657
	$choices = array();
658
659
	if ( is_array( $terms ) ) {
660
		foreach ( $terms as $term_id => $term_name ) {
661
			$choices[] = array(
662
				'text'  => $term_name,
663
				'value' => $term_id
664
			);
665
		}
666
	}
667
668
	return $choices;
669
}
670
671
/**
672
 * Maybe convert jQuery-serialized fields into array, otherwise return $_POST['fields'] array
673
 *
674
 * Fields are passed as a jQuery-serialized array, created in admin-views.js in the serializeForm method.
675
 *
676
 * @since 1.16.5
677
 *
678
 * @uses GVCommon::gv_parse_str
679
 *
680
 * @return array Array of fields
681
 */
682
function _gravityview_process_posted_fields() {
683
	$fields = array();
684
685
	if( !empty( $_POST['gv_fields'] ) ) {
686
		if ( ! is_array( $_POST['gv_fields'] ) ) {
687
688
			// We are not using parse_str() due to max_input_vars limitation with large View configurations
689
			$fields_holder = array();
690
			GVCommon::gv_parse_str( stripslashes( $_POST['gv_fields'] ), $fields_holder );
691
692
			if ( isset( $fields_holder['fields'] ) ) {
693
				$fields = $fields_holder['fields'];
694
			} else {
695
				gravityview()->log->error( 'No `fields` key was found after parsing $fields string', array( 'data' => $fields_holder ) );
696
			}
697
698
		} else {
699
			$fields = $_POST['gv_fields'];
700
		}
701
	}
702
703
	return $fields;
704
}
705