Completed
Push — master ( 9b8056...335a5e )
by Mike
15:35
created

wc-formatting-functions.php ➔ wc_string_to_array()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 2
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 3
rs 10
1
<?php
2
/**
3
 * WooCommerce Formatting
4
 *
5
 * Functions for formatting data.
6
 *
7
 * @author 		WooThemes
8
 * @category 	Core
9
 * @package 	WooCommerce/Functions
10
 * @version     2.1.0
11
 */
12
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit; // Exit if accessed directly
15
}
16
17
/**
18
 * Converts a string (e.g. yes or no) to a bool.
19
 * @since 2.7.0
20
 * @param string $string
21
 * @return bool
22
 */
23
function wc_string_to_bool( $string ) {
24
	return is_bool( $string ) ? $string : ( $string === 'yes' || $string === 1 || $string === '1' );
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $string (string) and 1 (integer) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
25
}
26
27
/**
28
 * Explode a string into an array by $delimiter and remove empty values.
29
 * @since 2.7.0
30
 * @param string $string
31
 * @param string $delimiter
32
 * @return array
33
 */
34
function wc_string_to_array( $string, $delimiter = ',' ) {
35
	return is_array( $string ) ? $string : array_filter( explode( $delimiter, $string ) );
36
}
37
38
/**
39
 * Sanitize taxonomy names. Slug format (no spaces, lowercase).
40
 *
41
 * urldecode is used to reverse munging of UTF8 characters.
42
 *
43
 * @param mixed $taxonomy
44
 * @return string
45
 */
46
function wc_sanitize_taxonomy_name( $taxonomy ) {
47
	return apply_filters( 'sanitize_taxonomy_name', urldecode( sanitize_title( $taxonomy ) ), $taxonomy );
48
}
49
50
/**
51
 * Sanitize permalink values before insertion into DB.
52
 *
53
 * Cannot use wc_clean because it sometimes strips % chars and breaks the user's setting.
54
 *
55
 * @since  2.6.0
56
 * @param  string $value
57
 * @return string
58
 */
59
function wc_sanitize_permalink( $value ) {
60
	global $wpdb;
61
62
	$value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
63
64
	if ( is_wp_error( $value ) ) {
65
		$value = '';
66
	}
67
68
	$value = esc_url_raw( $value );
69
	$value = str_replace( 'http://', '', $value );
70
	return untrailingslashit( $value );
71
}
72
73
/**
74
 * Gets the filename part of a download URL.
75
 *
76
 * @param string $file_url
77
 * @return string
78
 */
79
function wc_get_filename_from_url( $file_url ) {
80
	$parts = parse_url( $file_url );
81
	if ( isset( $parts['path'] ) ) {
82
		return basename( $parts['path'] );
83
	}
84
}
85
86
/**
87
 * Normalise dimensions, unify to cm then convert to wanted unit value.
88
 *
89
 * Usage:
90
 * wc_get_dimension(55, 'in');
91
 * wc_get_dimension(55, 'in', 'm');
92
 *
93
 * @param int|float $dimension
94
 * @param string $to_unit 'in', 'm', 'cm', 'm'
95
 * @param string $from_unit (optional) 'in', 'm', 'cm', 'm'
96
 * @return float
97
 */
98
function wc_get_dimension( $dimension, $to_unit, $from_unit = '' ) {
99
	$to_unit = strtolower( $to_unit );
100
101
	if ( empty( $from_unit ) ) {
102
		$from_unit = strtolower( get_option( 'woocommerce_dimension_unit' ) );
103
	}
104
105
	// Unify all units to cm first.
106
	if ( $from_unit !== $to_unit ) {
107 View Code Duplication
		switch ( $from_unit ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
108
			case 'in' :
109
				$dimension *= 2.54;
110
				break;
111
			case 'm' :
112
				$dimension *= 100;
113
				break;
114
			case 'mm' :
115
				$dimension *= 0.1;
116
				break;
117
			case 'yd' :
118
				$dimension *= 91.44;
119
				break;
120
		}
121
122
		// Output desired unit.
123 View Code Duplication
		switch ( $to_unit ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
124
			case 'in' :
125
				$dimension *= 0.3937;
126
				break;
127
			case 'm' :
128
				$dimension *= 0.01;
129
				break;
130
			case 'mm' :
131
				$dimension *= 10;
132
				break;
133
			case 'yd' :
134
				$dimension *= 0.010936133;
135
				break;
136
		}
137
	}
138
139
	return ( $dimension < 0 ) ? 0 : $dimension;
140
}
141
142
/**
143
 * Normalise weights, unify to kg then convert to wanted unit value.
144
 *
145
 * Usage:
146
 * wc_get_weight(55, 'kg');
147
 * wc_get_weight(55, 'kg', 'lbs');
148
 *
149
 * @param int|float $weight
150
 * @param string $to_unit 'g', 'kg', 'lbs', 'oz'
151
 * @param string $from_unit (optional) 'g', 'kg', 'lbs', 'oz'
152
 * @return float
153
 */
154
function wc_get_weight( $weight, $to_unit, $from_unit = '' ) {
155
	$to_unit = strtolower( $to_unit );
156
157
	if ( empty( $from_unit ) ) {
158
		$from_unit = strtolower( get_option( 'woocommerce_weight_unit' ) );
159
	}
160
161
	// Unify all units to kg first.
162
	if ( $from_unit !== $to_unit ) {
163
		switch ( $from_unit ) {
164
			case 'g' :
165
				$weight *= 0.001;
166
				break;
167
			case 'lbs' :
168
				$weight *= 0.453592;
169
				break;
170
			case 'oz' :
171
				$weight *= 0.0283495;
172
				break;
173
		}
174
175
		// Output desired unit.
176
		switch ( $to_unit ) {
177
			case 'g' :
178
				$weight *= 1000;
179
				break;
180
			case 'lbs' :
181
				$weight *= 2.20462;
182
				break;
183
			case 'oz' :
184
				$weight *= 35.274;
185
				break;
186
		}
187
	}
188
189
	return ( $weight < 0 ) ? 0 : $weight;
190
}
191
192
/**
193
 * Trim trailing zeros off prices.
194
 *
195
 * @param mixed $price
196
 * @return string
197
 */
198
function wc_trim_zeros( $price ) {
199
	return preg_replace( '/' . preg_quote( wc_get_price_decimal_separator(), '/' ) . '0++$/', '', $price );
200
}
201
202
/**
203
 * Round a tax amount.
204
 *
205
 * @param mixed $tax
206
 * @return double
207
 */
208
function wc_round_tax_total( $tax ) {
209
	$dp = wc_get_price_decimals();
210
211
	// @codeCoverageIgnoreStart
212
	if ( version_compare( phpversion(), '5.3', '<' ) ) {
213
		$rounded_tax = round( $tax, $dp );
214
	} else {
215
		// @codeCoverageIgnoreEnd
216
		$rounded_tax = round( $tax, $dp, WC_TAX_ROUNDING_MODE );
217
	}
218
	return apply_filters( 'wc_round_tax_total', $rounded_tax, $tax, $dp, WC_TAX_ROUNDING_MODE );
219
}
220
221
/**
222
 * Make a refund total negative.
223
 * @return float
224
 */
225
function wc_format_refund_total( $amount ) {
226
	return $amount * -1;
227
}
228
229
/**
230
 * Format decimal numbers ready for DB storage.
231
 *
232
 * Sanitize, remove locale formatting, and optionally round + trim off zeros.
233
 *
234
 * @param  float|string $number Expects either a float or a string with a decimal separator only (no thousands)
235
 * @param  mixed $dp number of decimal points to use, blank to use woocommerce_price_num_decimals, or false to avoid all rounding.
236
 * @param  bool $trim_zeros from end of string
237
 * @return string
238
 */
239
function wc_format_decimal( $number, $dp = false, $trim_zeros = false ) {
240
	$locale   = localeconv();
241
	$decimals = array( wc_get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'] );
242
243
	// Remove locale from string
244
	if ( ! is_float( $number ) ) {
245
		$number = wc_clean( str_replace( $decimals, '.', $number ) );
246
	}
247
248
	if ( $dp !== false ) {
249
		$dp     = intval( $dp == "" ? wc_get_price_decimals() : $dp );
250
		$number = number_format( floatval( $number ), $dp, '.', '' );
251
252
	// DP is false - don't use number format, just return a string in our format
253
	} elseif ( is_float( $number ) ) {
254
		$number = wc_clean( str_replace( $decimals, '.', strval( $number ) ) );
255
	}
256
257
	if ( $trim_zeros && strstr( $number, '.' ) ) {
258
		$number = rtrim( rtrim( $number, '0' ), '.' );
259
	}
260
261
	return $number;
262
}
263
264
/**
265
 * Convert a float to a string without locale formatting which PHP adds when changing floats to strings.
266
 * @param  float $float
267
 * @return string
268
 */
269
function wc_float_to_string( $float ) {
270
	if ( ! is_float( $float ) ) {
271
		return $float;
272
	}
273
274
	$locale = localeconv();
275
	$string = strval( $float );
276
	$string = str_replace( $locale['decimal_point'], '.', $string );
277
278
	return $string;
279
}
280
281
/**
282
 * Format a price with WC Currency Locale settings.
283
 * @param  string $value
284
 * @return string
285
 */
286
function wc_format_localized_price( $value ) {
287
	return str_replace( '.', wc_get_price_decimal_separator(), strval( $value ) );
288
}
289
290
/**
291
 * Format a decimal with PHP Locale settings.
292
 * @param  string $value
293
 * @return string
294
 */
295
function wc_format_localized_decimal( $value ) {
296
	$locale = localeconv();
297
	return str_replace( '.', $locale['decimal_point'], strval( $value ) );
298
}
299
300
/**
301
 * Clean variables using sanitize_text_field. Arrays are cleaned recursively.
302
 * Non-scalar values are ignored.
303
 * @param string|array $var
304
 * @return string|array
305
 */
306
function wc_clean( $var ) {
307
	if ( is_array( $var ) ) {
308
		return array_map( 'wc_clean', $var );
309
	} else {
310
		return is_scalar( $var ) ? sanitize_text_field( $var ) : $var;
311
	}
312
}
313
314
/**
315
 * Sanitize a string destined to be a tooltip.
316
 *
317
 * @since 2.3.10 Tooltips are encoded with htmlspecialchars to prevent XSS. Should not be used in conjunction with esc_attr()
318
 * @param string $var
319
 * @return string
320
 */
321
function wc_sanitize_tooltip( $var ) {
322
	return htmlspecialchars( wp_kses( html_entity_decode( $var ), array(
323
		'br'     => array(),
324
		'em'     => array(),
325
		'strong' => array(),
326
		'small'  => array(),
327
		'span'   => array(),
328
		'ul'     => array(),
329
		'li'     => array(),
330
		'ol'     => array(),
331
		'p'      => array(),
332
	) ) );
333
}
334
335
/**
336
 * Merge two arrays.
337
 *
338
 * @param array $a1
339
 * @param array $a2
340
 * @return array
341
 */
342
function wc_array_overlay( $a1, $a2 ) {
343
	foreach ( $a1 as $k => $v ) {
344
		if ( ! array_key_exists( $k, $a2 ) ) {
345
			continue;
346
		}
347
		if ( is_array( $v ) && is_array( $a2[ $k ] ) ) {
348
			$a1[ $k ] = wc_array_overlay( $v, $a2[ $k ] );
349
		} else {
350
			$a1[ $k ] = $a2[ $k ];
351
		}
352
	}
353
	return $a1;
354
}
355
356
/**
357
 * Formats a stock amount by running it through a filter.
358
 * @param  int|float $amount
359
 * @return int|float
360
 */
361
function wc_stock_amount( $amount ) {
362
	return apply_filters( 'woocommerce_stock_amount', $amount );
363
}
364
365
/**
366
 * Get the price format depending on the currency position.
367
 *
368
 * @return string
369
 */
370
function get_woocommerce_price_format() {
371
	$currency_pos = get_option( 'woocommerce_currency_pos' );
372
	$format = '%1$s%2$s';
373
374
	switch ( $currency_pos ) {
375
		case 'left' :
376
			$format = '%1$s%2$s';
377
		break;
378
		case 'right' :
379
			$format = '%2$s%1$s';
380
		break;
381
		case 'left_space' :
382
			$format = '%1$s&nbsp;%2$s';
383
		break;
384
		case 'right_space' :
385
			$format = '%2$s&nbsp;%1$s';
386
		break;
387
	}
388
389
	return apply_filters( 'woocommerce_price_format', $format, $currency_pos );
390
}
391
392
/**
393
 * Return the thousand separator for prices.
394
 * @since  2.3
395
 * @return string
396
 */
397
function wc_get_price_thousand_separator() {
398
	$separator = stripslashes( get_option( 'woocommerce_price_thousand_sep' ) );
399
	return $separator;
400
}
401
402
/**
403
 * Return the decimal separator for prices.
404
 * @since  2.3
405
 * @return string
406
 */
407
function wc_get_price_decimal_separator() {
408
	$separator = stripslashes( get_option( 'woocommerce_price_decimal_sep' ) );
409
	return $separator ? $separator : '.';
410
}
411
412
/**
413
 * Return the number of decimals after the decimal point.
414
 * @since  2.3
415
 * @return int
416
 */
417
function wc_get_price_decimals() {
418
	return absint( get_option( 'woocommerce_price_num_decimals', 2 ) );
419
}
420
421
/**
422
 * Format the price with a currency symbol.
423
 *
424
 * @param float $price
425
 * @param array $args (default: array())
426
 * @return string
427
 */
428
function wc_price( $price, $args = array() ) {
429
	extract( apply_filters( 'wc_price_args', wp_parse_args( $args, array(
430
		'ex_tax_label'       => false,
431
		'currency'           => '',
432
		'decimal_separator'  => wc_get_price_decimal_separator(),
433
		'thousand_separator' => wc_get_price_thousand_separator(),
434
		'decimals'           => wc_get_price_decimals(),
435
		'price_format'       => get_woocommerce_price_format()
436
	) ) ) );
437
438
	$negative        = $price < 0;
439
	$price           = apply_filters( 'raw_woocommerce_price', floatval( $negative ? $price * -1 : $price ) );
440
	$price           = apply_filters( 'formatted_woocommerce_price', number_format( $price, $decimals, $decimal_separator, $thousand_separator ), $price, $decimals, $decimal_separator, $thousand_separator );
441
442
	if ( apply_filters( 'woocommerce_price_trim_zeros', false ) && $decimals > 0 ) {
443
		$price = wc_trim_zeros( $price );
444
	}
445
446
	$formatted_price = ( $negative ? '-' : '' ) . sprintf( $price_format, '<span class="woocommerce-Price-currencySymbol">' . get_woocommerce_currency_symbol( $currency ) . '</span>', $price );
447
	$return          = '<span class="woocommerce-Price-amount amount">' . $formatted_price . '</span>';
448
449
	if ( $ex_tax_label && wc_tax_enabled() ) {
450
		$return .= ' <small class="woocommerce-Price-taxLabel tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
451
	}
452
453
	return apply_filters( 'wc_price', $return, $price, $args );
454
}
455
456
/**
457
 * let_to_num function.
458
 *
459
 * This function transforms the php.ini notation for numbers (like '2M') to an integer.
460
 *
461
 * @param $size
462
 * @return int
463
 */
464
function wc_let_to_num( $size ) {
465
	$l   = substr( $size, -1 );
466
	$ret = substr( $size, 0, -1 );
467
	switch ( strtoupper( $l ) ) {
468
		case 'P':
469
			$ret *= 1024;
470
		case 'T':
471
			$ret *= 1024;
472
		case 'G':
473
			$ret *= 1024;
474
		case 'M':
475
			$ret *= 1024;
476
		case 'K':
477
			$ret *= 1024;
478
	}
479
	return $ret;
480
}
481
482
/**
483
 * WooCommerce Date Format - Allows to change date format for everything WooCommerce.
484
 *
485
 * @return string
486
 */
487
function wc_date_format() {
488
	return apply_filters( 'woocommerce_date_format', get_option( 'date_format' ) );
489
}
490
491
/**
492
 * WooCommerce Time Format - Allows to change time format for everything WooCommerce.
493
 *
494
 * @return string
495
 */
496
function wc_time_format() {
497
	return apply_filters( 'woocommerce_time_format', get_option( 'time_format' ) );
498
}
499
500
/**
501
 * WooCommerce Timezone - helper to retrieve the timezone string for a site until.
502
 * a WP core method exists (see https://core.trac.wordpress.org/ticket/24730).
503
 *
504
 * Adapted from https://secure.php.net/manual/en/function.timezone-name-from-abbr.php#89155.
505
 *
506
 * @since 2.1
507
 * @return string a valid PHP timezone string for the site
508
 */
509
function wc_timezone_string() {
510
511
	// if site timezone string exists, return it
512
	if ( $timezone = get_option( 'timezone_string' ) ) {
513
		return $timezone;
514
	}
515
516
	// get UTC offset, if it isn't set then return UTC
517
	if ( 0 === ( $utc_offset = get_option( 'gmt_offset', 0 ) ) ) {
518
		return 'UTC';
519
	}
520
521
	// adjust UTC offset from hours to seconds
522
	$utc_offset *= 3600;
523
524
	// attempt to guess the timezone string from the UTC offset
525
	$timezone = timezone_name_from_abbr( '', $utc_offset, 0 );
526
527
	// last try, guess timezone string manually
528
	if ( false === $timezone ) {
529
		$is_dst = date( 'I' );
530
531
		foreach ( timezone_abbreviations_list() as $abbr ) {
532
			foreach ( $abbr as $city ) {
533
				if ( $city['dst'] == $is_dst && $city['offset'] == $utc_offset ) {
534
					return $city['timezone_id'];
535
				}
536
			}
537
		}
538
539
		// fallback to UTC
540
		return 'UTC';
541
	}
542
543
	return $timezone;
544
}
545
546
if ( ! function_exists( 'wc_rgb_from_hex' ) ) {
547
548
	/**
549
	 * Hex darker/lighter/contrast functions for colours.
550
	 *
551
	 * @param mixed $color
552
	 * @return string
553
	 */
554
	function wc_rgb_from_hex( $color ) {
555
		$color = str_replace( '#', '', $color );
556
		// Convert shorthand colors to full format, e.g. "FFF" -> "FFFFFF"
557
		$color = preg_replace( '~^(.)(.)(.)$~', '$1$1$2$2$3$3', $color );
558
559
		$rgb      = array();
560
		$rgb['R'] = hexdec( $color{0}.$color{1} );
561
		$rgb['G'] = hexdec( $color{2}.$color{3} );
562
		$rgb['B'] = hexdec( $color{4}.$color{5} );
563
564
		return $rgb;
565
	}
566
}
567
568 View Code Duplication
if ( ! function_exists( 'wc_hex_darker' ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
569
570
	/**
571
	 * Hex darker/lighter/contrast functions for colours.
572
	 *
573
	 * @param mixed $color
574
	 * @param int $factor (default: 30)
575
	 * @return string
576
	 */
577
	function wc_hex_darker( $color, $factor = 30 ) {
578
		$base  = wc_rgb_from_hex( $color );
579
		$color = '#';
580
581
		foreach ( $base as $k => $v ) {
582
			$amount      = $v / 100;
583
			$amount      = round( $amount * $factor );
584
			$new_decimal = $v - $amount;
585
586
			$new_hex_component = dechex( $new_decimal );
587
			if ( strlen( $new_hex_component ) < 2 ) {
588
				$new_hex_component = "0" . $new_hex_component;
589
			}
590
			$color .= $new_hex_component;
591
		}
592
593
		return $color;
594
	}
595
}
596
597 View Code Duplication
if ( ! function_exists( 'wc_hex_lighter' ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
598
599
	/**
600
	 * Hex darker/lighter/contrast functions for colours.
601
	 *
602
	 * @param mixed $color
603
	 * @param int $factor (default: 30)
604
	 * @return string
605
	 */
606
	function wc_hex_lighter( $color, $factor = 30 ) {
607
		$base  = wc_rgb_from_hex( $color );
608
		$color = '#';
609
610
		foreach ( $base as $k => $v ) {
611
			$amount      = 255 - $v;
612
			$amount      = $amount / 100;
613
			$amount      = round( $amount * $factor );
614
			$new_decimal = $v + $amount;
615
616
			$new_hex_component = dechex( $new_decimal );
617
			if ( strlen( $new_hex_component ) < 2 ) {
618
				$new_hex_component = "0" . $new_hex_component;
619
			}
620
			$color .= $new_hex_component;
621
		}
622
623
		return $color;
624
	}
625
}
626
627
if ( ! function_exists( 'wc_light_or_dark' ) ) {
628
629
	/**
630
	 * Detect if we should use a light or dark colour on a background colour.
631
	 *
632
	 * @param mixed $color
633
	 * @param string $dark (default: '#000000')
634
	 * @param string $light (default: '#FFFFFF')
635
	 * @return string
636
	 */
637
	function wc_light_or_dark( $color, $dark = '#000000', $light = '#FFFFFF' ) {
638
639
		$hex = str_replace( '#', '', $color );
640
641
		$c_r = hexdec( substr( $hex, 0, 2 ) );
642
		$c_g = hexdec( substr( $hex, 2, 2 ) );
643
		$c_b = hexdec( substr( $hex, 4, 2 ) );
644
645
		$brightness = ( ( $c_r * 299 ) + ( $c_g * 587 ) + ( $c_b * 114 ) ) / 1000;
646
647
		return $brightness > 155 ? $dark : $light;
648
	}
649
}
650
651
if ( ! function_exists( 'wc_format_hex' ) ) {
652
653
	/**
654
	 * Format string as hex.
655
	 *
656
	 * @param string $hex
657
	 * @return string
658
	 */
659
	function wc_format_hex( $hex ) {
660
661
		$hex = trim( str_replace( '#', '', $hex ) );
662
663
		if ( strlen( $hex ) == 3 ) {
664
			$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
665
		}
666
667
		return $hex ? '#' . $hex : null;
668
	}
669
}
670
671
/**
672
 * Format the postcode according to the country and length of the postcode.
673
 *
674
 * @param string $postcode
675
 * @param string $country
676
 * @return string Formatted postcode.
677
 */
678
function wc_format_postcode( $postcode, $country ) {
679
	$postcode = wc_normalize_postcode( $postcode );
680
681
	switch ( $country ) {
682
		case 'CA' :
683
		case 'GB' :
684
			$postcode = trim( substr_replace( $postcode, ' ', -3, 0 ) );
685
			break;
686
		case 'BR' :
687
		case 'PL' :
688
			$postcode = trim( substr_replace( $postcode, '-', -3, 0 ) );
689
			break;
690
		case 'JP' :
691
			$postcode = trim( substr_replace( $postcode, '-', 3, 0 ) );
692
			break;
693
		case 'PT' :
694
			$postcode = trim( substr_replace( $postcode, '-', 4, 0 ) );
695
			break;
696
	}
697
698
	return apply_filters( 'woocommerce_format_postcode', $postcode, $country );
699
}
700
701
/**
702
 * Normalize postcodes.
703
 *
704
 * Remove spaces and convert characters to uppercase.
705
 *
706
 * @since 2.6.0
707
 * @param string $postcode
708
 * @return string Sanitized postcode.
709
 */
710
function wc_normalize_postcode( $postcode ) {
711
	return preg_replace( '/[\s\-]/', '', trim( strtoupper( $postcode ) ) );
712
}
713
714
/**
715
 * format_phone function.
716
 *
717
 * @param mixed $tel
718
 * @return string
719
 */
720
function wc_format_phone_number( $tel ) {
721
	return str_replace( '.', '-', $tel );
722
}
723
724
/**
725
 * Make a string lowercase.
726
 * Try to use mb_strtolower() when available.
727
 *
728
 * @since  2.3
729
 * @param  string $string
730
 * @return string
731
 */
732
function wc_strtolower( $string ) {
733
	return function_exists( 'mb_strtolower' ) ? mb_strtolower( $string ) : strtolower( $string );
734
}
735
736
/**
737
 * Trim a string and append a suffix.
738
 * @param  string  $string
739
 * @param  integer $chars
740
 * @param  string  $suffix
741
 * @return string
742
 */
743
function wc_trim_string( $string, $chars = 200, $suffix = '...' ) {
744
	if ( strlen( $string ) > $chars ) {
745
		if ( function_exists( 'mb_substr' ) ) {
746
			$string = mb_substr( $string, 0, ( $chars - mb_strlen( $suffix ) ) ) . $suffix;
747
		} else {
748
			$string = substr( $string, 0, ( $chars - strlen( $suffix ) ) ) . $suffix;
749
		}
750
	}
751
	return $string;
752
}
753
754
/**
755
 * Format content to display shortcodes.
756
 *
757
 * @since  2.3.0
758
 * @param  string $raw_string
759
 * @return string
760
 */
761
function wc_format_content( $raw_string ) {
762
	return apply_filters( 'woocommerce_format_content', do_shortcode( shortcode_unautop( wpautop( $raw_string ) ) ), $raw_string );
763
}
764
765
/**
766
 * Format product short description.
767
 * Adds support for Jetpack Markdown.
768
 *
769
 * @since  2.4.0
770
 * @param  string $content
771
 * @return string
772
 */
773
function wc_format_product_short_description( $content ) {
774
	// Add support for Jetpack Markdown
775
	if ( class_exists( 'WPCom_Markdown' ) ) {
776
		$markdown = WPCom_Markdown::get_instance();
777
778
		return wpautop( $markdown->transform( $content, array( 'unslash' => false ) ) );
779
	}
780
781
	return $content;
782
}
783
784
add_filter( 'woocommerce_short_description', 'wc_format_product_short_description', 9999999 );
785
786
/**
787
 * Formats curency symbols when saved in settings.
788
 * @param  string $value
789
 * @param  array $option
790
 * @param  string $raw_value
791
 * @return string
792
 */
793
function wc_format_option_price_separators( $value, $option, $raw_value ) {
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $option is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
794
	return wp_kses_post( $raw_value );
795
}
796
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_price_decimal_sep', 'wc_format_option_price_separators', 10, 3 );
797
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_price_thousand_sep', 'wc_format_option_price_separators', 10, 3 );
798
799
/**
800
 * Formats decimals when saved in settings.
801
 * @param  string $value
802
 * @param  array $option
803
 * @param  string $raw_value
804
 * @return string
805
 */
806
function wc_format_option_price_num_decimals( $value, $option, $raw_value ) {
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $option is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
807
	return is_null( $raw_value ) ? 2 : absint( $raw_value );
808
}
809
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_price_num_decimals', 'wc_format_option_price_num_decimals', 10, 3 );
810
811
/**
812
 * Formats hold stock option and sets cron event up.
813
 * @param  string $value
814
 * @param  array $option
815
 * @param  string $raw_value
816
 * @return string
817
 */
818
function wc_format_option_hold_stock_minutes( $value, $option, $raw_value ) {
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $option is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
819
	$value = ! empty( $raw_value ) ? absint( $raw_value ) : ''; // Allow > 0 or set to ''
820
821
	wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
822
823
	if ( '' !== $value ) {
824
		wp_schedule_single_event( time() + ( absint( $value ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
825
	}
826
827
	return $value;
828
}
829
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_hold_stock_minutes', 'wc_format_option_hold_stock_minutes', 10, 3 );
830
831
/**
832
 * Sanitize terms from an attribute text based.
833
 *
834
 * @since  2.4.5
835
 * @param  string $term
836
 * @return string
837
 */
838
function wc_sanitize_term_text_based( $term ) {
839
	return trim( wp_unslash( strip_tags( $term ) ) );
840
}
841
842
if ( ! function_exists( 'wc_make_numeric_postcode' ) ) {
843
	/**
844
	 * Make numeric postcode.
845
	 *
846
	 * Converts letters to numbers so we can do a simple range check on postcodes.
847
	 * E.g. PE30 becomes 16050300 (P = 16, E = 05, 3 = 03, 0 = 00)
848
	 *
849
	 * @since 2.6.0
850
	 * @param string $postcode Regular postcode
851
	 * @return string
852
	 */
853
	function wc_make_numeric_postcode( $postcode ) {
854
		$postcode           = str_replace( array( ' ', '-' ), '', $postcode );
855
		$postcode_length    = strlen( $postcode );
856
		$letters_to_numbers = array_merge( array( 0 ), range( 'A', 'Z' ) );
857
		$letters_to_numbers = array_flip( $letters_to_numbers );
858
		$numeric_postcode   = '';
859
860
		for ( $i = 0; $i < $postcode_length; $i ++ ) {
861
			if ( is_numeric( $postcode[ $i ] ) ) {
862
				$numeric_postcode .= str_pad( $postcode[ $i ], 2, '0', STR_PAD_LEFT );
863
			} elseif ( isset( $letters_to_numbers[ $postcode[ $i ] ] ) ) {
864
				$numeric_postcode .= str_pad( $letters_to_numbers[ $postcode[ $i ] ], 2, '0', STR_PAD_LEFT );
865
			} else {
866
				$numeric_postcode .= '00';
867
			}
868
		}
869
870
		return $numeric_postcode;
871
	}
872
}
873