Completed
Pull Request — master (#11252)
by
unknown
07:07
created

wc-formatting-functions.php ➔ wc_format_postcode()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 18
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 5
eloc 14
c 1
b 0
f 1
nc 5
nop 2
dl 0
loc 18
rs 8.8571
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
 * Sanitize taxonomy names. Slug format (no spaces, lowercase).
19
 *
20
 * urldecode is used to reverse munging of UTF8 characters.
21
 *
22
 * @param mixed $taxonomy
23
 * @return string
24
 */
25
function wc_sanitize_taxonomy_name( $taxonomy ) {
26
	return apply_filters( 'sanitize_taxonomy_name', urldecode( sanitize_title( $taxonomy ) ), $taxonomy );
27
}
28
29
/**
30
 * Sanitize permalink values before insertion into DB.
31
 *
32
 * Cannot use wc_clean because it sometimes strips % chars and breaks the user's setting.
33
 *
34
 * @since  2.6.0
35
 * @param  string $value
36
 * @return string
37
 */
38
function wc_sanitize_permalink( $value ) {
39
	global $wpdb;
40
41
	$value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
42
43
	if ( is_wp_error( $value ) ) {
44
		$value = '';
45
	}
46
47
	$value = esc_url_raw( $value );
48
	$value = str_replace( 'http://', '', $value );
49
	return untrailingslashit( $value );
50
}
51
52
/**
53
 * Gets the filename part of a download URL.
54
 *
55
 * @param string $file_url
56
 * @return string
57
 */
58
function wc_get_filename_from_url( $file_url ) {
59
	$parts = parse_url( $file_url );
60
	if ( isset( $parts['path'] ) ) {
61
		return basename( $parts['path'] );
62
	}
63
}
64
65
/**
66
 * Normalise dimensions, unify to cm then convert to wanted unit value.
67
 *
68
 * Usage:
69
 * wc_get_dimension(55, 'in');
70
 * wc_get_dimension(55, 'in', 'm');
71
 *
72
 * @param int|float $dimension
73
 * @param string $to_unit 'in', 'm', 'cm', 'm'
74
 * @param string $from_unit (optional) 'in', 'm', 'cm', 'm'
75
 * @return float
76
 */
77
function wc_get_dimension( $dimension, $to_unit, $from_unit = '' ) {
78
	$to_unit = strtolower( $to_unit );
79
80
	if ( empty( $from_unit ) ) {
81
		$from_unit = strtolower( get_option( 'woocommerce_dimension_unit' ) );
82
	}
83
84
	// Unify all units to cm first.
85
	if ( $from_unit !== $to_unit ) {
86 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...
87
			case 'in' :
88
				$dimension *= 2.54;
89
				break;
90
			case 'm' :
91
				$dimension *= 100;
92
				break;
93
			case 'mm' :
94
				$dimension *= 0.1;
95
				break;
96
			case 'yd' :
97
				$dimension *= 91.44;
98
				break;
99
		}
100
101
		// Output desired unit.
102 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...
103
			case 'in' :
104
				$dimension *= 0.3937;
105
				break;
106
			case 'm' :
107
				$dimension *= 0.01;
108
				break;
109
			case 'mm' :
110
				$dimension *= 10;
111
				break;
112
			case 'yd' :
113
				$dimension *= 0.010936133;
114
				break;
115
		}
116
	}
117
118
	return ( $dimension < 0 ) ? 0 : $dimension;
119
}
120
121
/**
122
 * Normalise weights, unify to kg then convert to wanted unit value.
123
 *
124
 * Usage:
125
 * wc_get_weight(55, 'kg');
126
 * wc_get_weight(55, 'kg', 'lbs');
127
 *
128
 * @param int|float $weight
129
 * @param string $to_unit 'g', 'kg', 'lbs', 'oz'
130
 * @param string $from_unit (optional) 'g', 'kg', 'lbs', 'oz'
131
 * @return float
132
 */
133
function wc_get_weight( $weight, $to_unit, $from_unit = '' ) {
134
	$to_unit = strtolower( $to_unit );
135
136
	if ( empty( $from_unit ) ) {
137
		$from_unit = strtolower( get_option( 'woocommerce_weight_unit' ) );
138
	}
139
140
	// Unify all units to kg first.
141
	if ( $from_unit !== $to_unit ) {
142
		switch ( $from_unit ) {
143
			case 'g' :
144
				$weight *= 0.001;
145
				break;
146
			case 'lbs' :
147
				$weight *= 0.453592;
148
				break;
149
			case 'oz' :
150
				$weight *= 0.0283495;
151
				break;
152
		}
153
154
		// Output desired unit.
155
		switch ( $to_unit ) {
156
			case 'g' :
157
				$weight *= 1000;
158
				break;
159
			case 'lbs' :
160
				$weight *= 2.20462;
161
				break;
162
			case 'oz' :
163
				$weight *= 35.274;
164
				break;
165
		}
166
	}
167
168
	return ( $weight < 0 ) ? 0 : $weight;
169
}
170
171
/**
172
 * Trim trailing zeros off prices.
173
 *
174
 * @param mixed $price
175
 * @return string
176
 */
177
function wc_trim_zeros( $price ) {
178
	return preg_replace( '/' . preg_quote( wc_get_price_decimal_separator(), '/' ) . '0++$/', '', $price );
179
}
180
181
/**
182
 * Round a tax amount.
183
 *
184
 * @param mixed $tax
185
 * @return double
186
 */
187
function wc_round_tax_total( $tax ) {
188
	$dp = wc_get_price_decimals();
189
190
	// @codeCoverageIgnoreStart
191
	if ( version_compare( phpversion(), '5.3', '<' ) ) {
192
		$rounded_tax = round( $tax, $dp );
193
	} else {
194
		// @codeCoverageIgnoreEnd
195
		$rounded_tax = round( $tax, $dp, WC_TAX_ROUNDING_MODE );
196
	}
197
	return apply_filters( 'wc_round_tax_total', $rounded_tax, $tax, $dp, WC_TAX_ROUNDING_MODE );
198
}
199
200
/**
201
 * Make a refund total negative.
202
 * @return float
203
 */
204
function wc_format_refund_total( $amount ) {
205
	return $amount * -1;
206
}
207
208
/**
209
 * Format decimal numbers ready for DB storage.
210
 *
211
 * Sanitize, remove locale formatting, and optionally round + trim off zeros.
212
 *
213
 * @param  float|string $number Expects either a float or a string with a decimal separator only (no thousands)
214
 * @param  mixed $dp number of decimal points to use, blank to use woocommerce_price_num_decimals, or false to avoid all rounding.
215
 * @param  bool $trim_zeros from end of string
216
 * @return string
217
 */
218
function wc_format_decimal( $number, $dp = false, $trim_zeros = false ) {
219
	$locale   = localeconv();
220
	$decimals = array( wc_get_price_decimal_separator(), $locale['decimal_point'], $locale['mon_decimal_point'] );
221
222
	// Remove locale from string
223
	if ( ! is_float( $number ) ) {
224
		$number = wc_clean( str_replace( $decimals, '.', $number ) );
225
	}
226
227
	if ( $dp !== false ) {
228
		$dp     = intval( $dp == "" ? wc_get_price_decimals() : $dp );
229
		$number = number_format( floatval( $number ), $dp, '.', '' );
230
231
	// DP is false - don't use number format, just return a string in our format
232
	} elseif ( is_float( $number ) ) {
233
		$number = wc_clean( str_replace( $decimals, '.', strval( $number ) ) );
234
	}
235
236
	if ( $trim_zeros && strstr( $number, '.' ) ) {
237
		$number = rtrim( rtrim( $number, '0' ), '.' );
238
	}
239
240
	return $number;
241
}
242
243
/**
244
 * Convert a float to a string without locale formatting which PHP adds when changing floats to strings.
245
 * @param  float $float
246
 * @return string
247
 */
248
function wc_float_to_string( $float ) {
249
	if ( ! is_float( $float ) ) {
250
		return $float;
251
	}
252
253
	$locale = localeconv();
254
	$string = strval( $float );
255
	$string = str_replace( $locale['decimal_point'], '.', $string );
256
257
	return $string;
258
}
259
260
/**
261
 * Format a price with WC Currency Locale settings.
262
 * @param  string $value
263
 * @return string
264
 */
265
function wc_format_localized_price( $value ) {
266
	return str_replace( '.', wc_get_price_decimal_separator(), strval( $value ) );
267
}
268
269
/**
270
 * Format a decimal with PHP Locale settings.
271
 * @param  string $value
272
 * @return string
273
 */
274
function wc_format_localized_decimal( $value ) {
275
	$locale = localeconv();
276
	return str_replace( '.', $locale['decimal_point'], strval( $value ) );
277
}
278
279
/**
280
 * Clean variables using sanitize_text_field. Arrays are cleaned recursively.
281
 * Non-scalar values are ignored.
282
 * @param string|array $var
283
 * @return string|array
284
 */
285
function wc_clean( $var ) {
286
	if ( is_array( $var ) ) {
287
		return array_map( 'wc_clean', $var );
288
	} else {
289
		return is_scalar( $var ) ? sanitize_text_field( $var ) : $var;
290
	}
291
}
292
293
/**
294
 * Sanitize a string destined to be a tooltip.
295
 *
296
 * @since 2.3.10 Tooltips are encoded with htmlspecialchars to prevent XSS. Should not be used in conjunction with esc_attr()
297
 * @param string $var
298
 * @return string
299
 */
300
function wc_sanitize_tooltip( $var ) {
301
	return htmlspecialchars( wp_kses( html_entity_decode( $var ), array(
302
		'br'     => array(),
303
		'em'     => array(),
304
		'strong' => array(),
305
		'small'  => array(),
306
		'span'   => array(),
307
		'ul'     => array(),
308
		'li'     => array(),
309
		'ol'     => array(),
310
		'p'      => array(),
311
    ) ) );
312
}
313
314
/**
315
 * Merge two arrays.
316
 *
317
 * @param array $a1
318
 * @param array $a2
319
 * @return array
320
 */
321
function wc_array_overlay( $a1, $a2 ) {
322
	foreach ( $a1 as $k => $v ) {
323
		if ( ! array_key_exists( $k, $a2 ) ) {
324
			continue;
325
		}
326
		if ( is_array( $v ) && is_array( $a2[ $k ] ) ) {
327
			$a1[ $k ] = wc_array_overlay( $v, $a2[ $k ] );
328
		} else {
329
			$a1[ $k ] = $a2[ $k ];
330
		}
331
	}
332
	return $a1;
333
}
334
335
/**
336
 * Formats a stock amount by running it through a filter.
337
 * @param  int|float $amount
338
 * @return int|float
339
 */
340
function wc_stock_amount( $amount ) {
341
	return apply_filters( 'woocommerce_stock_amount', $amount );
342
}
343
344
/**
345
 * Get the price format depending on the currency position.
346
 *
347
 * @return string
348
 */
349
function get_woocommerce_price_format() {
350
	$currency_pos = get_option( 'woocommerce_currency_pos' );
351
	$format = '%1$s%2$s';
352
353
	switch ( $currency_pos ) {
354
		case 'left' :
355
			$format = '%1$s%2$s';
356
		break;
357
		case 'right' :
358
			$format = '%2$s%1$s';
359
		break;
360
		case 'left_space' :
361
			$format = '%1$s&nbsp;%2$s';
362
		break;
363
		case 'right_space' :
364
			$format = '%2$s&nbsp;%1$s';
365
		break;
366
	}
367
368
	return apply_filters( 'woocommerce_price_format', $format, $currency_pos );
369
}
370
371
/**
372
 * Return the thousand separator for prices.
373
 * @since  2.3
374
 * @return string
375
 */
376
function wc_get_price_thousand_separator() {
377
	$separator = stripslashes( get_option( 'woocommerce_price_thousand_sep' ) );
378
	return $separator;
379
}
380
381
/**
382
 * Return the decimal separator for prices.
383
 * @since  2.3
384
 * @return string
385
 */
386
function wc_get_price_decimal_separator() {
387
	$separator = stripslashes( get_option( 'woocommerce_price_decimal_sep' ) );
388
	return $separator ? $separator : '.';
389
}
390
391
/**
392
 * Return the number of decimals after the decimal point.
393
 * @since  2.3
394
 * @return int
395
 */
396
function wc_get_price_decimals() {
397
	return absint( get_option( 'woocommerce_price_num_decimals', 2 ) );
398
}
399
400
/**
401
 * Format the price with a currency symbol.
402
 *
403
 * @param float $price
404
 * @param array $args (default: array())
405
 * @return string
406
 */
407
function wc_price( $price, $args = array() ) {
408
	extract( apply_filters( 'wc_price_args', wp_parse_args( $args, array(
409
		'ex_tax_label'       => false,
410
		'currency'           => '',
411
		'decimal_separator'  => wc_get_price_decimal_separator(),
412
		'thousand_separator' => wc_get_price_thousand_separator(),
413
		'decimals'           => wc_get_price_decimals(),
414
		'price_format'       => get_woocommerce_price_format()
415
	) ) ) );
416
417
	$negative        = $price < 0;
418
	$price           = apply_filters( 'raw_woocommerce_price', floatval( $negative ? $price * -1 : $price ) );
419
	$price           = apply_filters( 'formatted_woocommerce_price', number_format( $price, $decimals, $decimal_separator, $thousand_separator ), $price, $decimals, $decimal_separator, $thousand_separator );
420
421
	if ( apply_filters( 'woocommerce_price_trim_zeros', false ) && $decimals > 0 ) {
422
		$price = wc_trim_zeros( $price );
423
	}
424
425
	$formatted_price = ( $negative ? '-' : '' ) . sprintf( $price_format, '<span class="woocommerce-Price-currencySymbol">' . get_woocommerce_currency_symbol( $currency ) . '</span>', $price );
426
	$return          = '<span class="woocommerce-Price-amount amount">' . $formatted_price . '</span>';
427
428
	if ( $ex_tax_label && wc_tax_enabled() ) {
429
		$return .= ' <small class="woocommerce-Price-taxLabel tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
430
	}
431
432
	return apply_filters( 'wc_price', $return, $price, $args );
433
}
434
435
/**
436
 * let_to_num function.
437
 *
438
 * This function transforms the php.ini notation for numbers (like '2M') to an integer.
439
 *
440
 * @param $size
441
 * @return int
442
 */
443
function wc_let_to_num( $size ) {
444
	$l   = substr( $size, -1 );
445
	$ret = substr( $size, 0, -1 );
446
	switch ( strtoupper( $l ) ) {
447
		case 'P':
448
			$ret *= 1024;
449
		case 'T':
450
			$ret *= 1024;
451
		case 'G':
452
			$ret *= 1024;
453
		case 'M':
454
			$ret *= 1024;
455
		case 'K':
456
			$ret *= 1024;
457
	}
458
	return $ret;
459
}
460
461
/**
462
 * WooCommerce Date Format - Allows to change date format for everything WooCommerce.
463
 *
464
 * @return string
465
 */
466
function wc_date_format() {
467
	return apply_filters( 'woocommerce_date_format', get_option( 'date_format' ) );
468
}
469
470
/**
471
 * WooCommerce Time Format - Allows to change time format for everything WooCommerce.
472
 *
473
 * @return string
474
 */
475
function wc_time_format() {
476
	return apply_filters( 'woocommerce_time_format', get_option( 'time_format' ) );
477
}
478
479
/**
480
 * WooCommerce Timezone - helper to retrieve the timezone string for a site until.
481
 * a WP core method exists (see https://core.trac.wordpress.org/ticket/24730).
482
 *
483
 * Adapted from https://secure.php.net/manual/en/function.timezone-name-from-abbr.php#89155.
484
 *
485
 * @since 2.1
486
 * @return string a valid PHP timezone string for the site
487
 */
488
function wc_timezone_string() {
489
490
	// if site timezone string exists, return it
491
	if ( $timezone = get_option( 'timezone_string' ) ) {
492
		return $timezone;
493
	}
494
495
	// get UTC offset, if it isn't set then return UTC
496
	if ( 0 === ( $utc_offset = get_option( 'gmt_offset', 0 ) ) ) {
497
		return 'UTC';
498
	}
499
500
	// adjust UTC offset from hours to seconds
501
	$utc_offset *= 3600;
502
503
	// attempt to guess the timezone string from the UTC offset
504
	$timezone = timezone_name_from_abbr( '', $utc_offset, 0 );
505
506
	// last try, guess timezone string manually
507
	if ( false === $timezone ) {
508
		$is_dst = date( 'I' );
509
510
		foreach ( timezone_abbreviations_list() as $abbr ) {
511
			foreach ( $abbr as $city ) {
512
				if ( $city['dst'] == $is_dst && $city['offset'] == $utc_offset ) {
513
					return $city['timezone_id'];
514
				}
515
			}
516
		}
517
518
		// fallback to UTC
519
		return 'UTC';
520
	}
521
522
	return $timezone;
523
}
524
525
if ( ! function_exists( 'wc_rgb_from_hex' ) ) {
526
527
	/**
528
	 * Hex darker/lighter/contrast functions for colours.
529
	 *
530
	 * @param mixed $color
531
	 * @return string
532
	 */
533
	function wc_rgb_from_hex( $color ) {
534
		$color = str_replace( '#', '', $color );
535
		// Convert shorthand colors to full format, e.g. "FFF" -> "FFFFFF"
536
		$color = preg_replace( '~^(.)(.)(.)$~', '$1$1$2$2$3$3', $color );
537
538
		$rgb      = array();
539
		$rgb['R'] = hexdec( $color{0}.$color{1} );
540
		$rgb['G'] = hexdec( $color{2}.$color{3} );
541
		$rgb['B'] = hexdec( $color{4}.$color{5} );
542
543
		return $rgb;
544
	}
545
}
546
547 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...
548
549
	/**
550
	 * Hex darker/lighter/contrast functions for colours.
551
	 *
552
	 * @param mixed $color
553
	 * @param int $factor (default: 30)
554
	 * @return string
555
	 */
556
	function wc_hex_darker( $color, $factor = 30 ) {
557
		$base  = wc_rgb_from_hex( $color );
558
		$color = '#';
559
560
		foreach ( $base as $k => $v ) {
561
			$amount      = $v / 100;
562
			$amount      = round( $amount * $factor );
563
			$new_decimal = $v - $amount;
564
565
			$new_hex_component = dechex( $new_decimal );
566
			if ( strlen( $new_hex_component ) < 2 ) {
567
				$new_hex_component = "0" . $new_hex_component;
568
			}
569
			$color .= $new_hex_component;
570
		}
571
572
		return $color;
573
	}
574
}
575
576 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...
577
578
	/**
579
	 * Hex darker/lighter/contrast functions for colours.
580
	 *
581
	 * @param mixed $color
582
	 * @param int $factor (default: 30)
583
	 * @return string
584
	 */
585
	function wc_hex_lighter( $color, $factor = 30 ) {
586
		$base  = wc_rgb_from_hex( $color );
587
		$color = '#';
588
589
		foreach ( $base as $k => $v ) {
590
			$amount      = 255 - $v;
591
			$amount      = $amount / 100;
592
			$amount      = round( $amount * $factor );
593
			$new_decimal = $v + $amount;
594
595
			$new_hex_component = dechex( $new_decimal );
596
			if ( strlen( $new_hex_component ) < 2 ) {
597
				$new_hex_component = "0" . $new_hex_component;
598
			}
599
			$color .= $new_hex_component;
600
		}
601
602
		return $color;
603
	}
604
}
605
606
if ( ! function_exists( 'wc_light_or_dark' ) ) {
607
608
	/**
609
	 * Detect if we should use a light or dark colour on a background colour.
610
	 *
611
	 * @param mixed $color
612
	 * @param string $dark (default: '#000000')
613
	 * @param string $light (default: '#FFFFFF')
614
	 * @return string
615
	 */
616
	function wc_light_or_dark( $color, $dark = '#000000', $light = '#FFFFFF' ) {
617
618
		$hex = str_replace( '#', '', $color );
619
620
		$c_r = hexdec( substr( $hex, 0, 2 ) );
621
		$c_g = hexdec( substr( $hex, 2, 2 ) );
622
		$c_b = hexdec( substr( $hex, 4, 2 ) );
623
624
		$brightness = ( ( $c_r * 299 ) + ( $c_g * 587 ) + ( $c_b * 114 ) ) / 1000;
625
626
		return $brightness > 155 ? $dark : $light;
627
	}
628
}
629
630
if ( ! function_exists( 'wc_format_hex' ) ) {
631
632
	/**
633
	 * Format string as hex.
634
	 *
635
	 * @param string $hex
636
	 * @return string
637
	 */
638
	function wc_format_hex( $hex ) {
639
640
		$hex = trim( str_replace( '#', '', $hex ) );
641
642
		if ( strlen( $hex ) == 3 ) {
643
			$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
644
		}
645
646
		return $hex ? '#' . $hex : null;
647
	}
648
}
649
650
/**
651
 * Format the postcode according to the country and length of the postcode.
652
 *
653
 * @param string $postcode
654
 * @param string $country
655
 * @return string Formatted postcode.
656
 */
657
function wc_format_postcode( $postcode, $country ) {
658
	$postcode = wc_normalize_postcode( $postcode );
659
660
	switch ( $country ) {
661
		case 'CA' :
662
		case 'GB' :
663
			$postcode = trim( substr_replace( $postcode, ' ', -3, 0 ) );
664
			break;
665
		case 'BR' :
666
			$postcode = trim( substr_replace( $postcode, '-', -3, 0 ) );
667
			break;
668
		case 'PT' :
669
			$postcode = trim( substr_replace( $postcode, '-', 4, 0 ) );
670
			break;
671
	}
672
673
	return apply_filters( 'woocommerce_format_postcode', $postcode, $country );
674
}
675
676
/**
677
 * Normalize postcodes.
678
 *
679
 * Remove spaces and convert characters to uppercase.
680
 *
681
 * @since 2.6.0
682
 * @param string $postcode
683
 * @return string Sanitized postcode.
684
 */
685
function wc_normalize_postcode( $postcode ) {
686
	return preg_replace( '/[\s\-]/', '', trim( strtoupper( $postcode ) ) );
687
}
688
689
/**
690
 * format_phone function.
691
 *
692
 * @param mixed $tel
693
 * @return string
694
 */
695
function wc_format_phone_number( $tel ) {
696
	return str_replace( '.', '-', $tel );
697
}
698
699
/**
700
 * Make a string lowercase.
701
 * Try to use mb_strtolower() when available.
702
 *
703
 * @since  2.3
704
 * @param  string $string
705
 * @return string
706
 */
707
function wc_strtolower( $string ) {
708
	return function_exists( 'mb_strtolower' ) ? mb_strtolower( $string ) : strtolower( $string );
709
}
710
711
/**
712
 * Trim a string and append a suffix.
713
 * @param  string  $string
714
 * @param  integer $chars
715
 * @param  string  $suffix
716
 * @return string
717
 */
718
function wc_trim_string( $string, $chars = 200, $suffix = '...' ) {
719
	if ( strlen( $string ) > $chars ) {
720
		if ( function_exists( 'mb_substr' ) ) {
721
			$string = mb_substr( $string, 0, ( $chars - mb_strlen( $suffix ) ) ) . $suffix;
722
		} else {
723
			$string = substr( $string, 0, ( $chars - strlen( $suffix ) ) ) . $suffix;
724
		}
725
	}
726
	return $string;
727
}
728
729
/**
730
 * Format content to display shortcodes.
731
 *
732
 * @since  2.3.0
733
 * @param  string $raw_string
734
 * @return string
735
 */
736
function wc_format_content( $raw_string ) {
737
	return apply_filters( 'woocommerce_format_content', do_shortcode( shortcode_unautop( wpautop( $raw_string ) ) ), $raw_string );
738
}
739
740
/**
741
 * Format product short description.
742
 * Adds support for Jetpack Markdown.
743
 *
744
 * @since  2.4.0
745
 * @param  string $content
746
 * @return string
747
 */
748
function wc_format_product_short_description( $content ) {
749
	// Add support for Jetpack Markdown
750
	if ( class_exists( 'WPCom_Markdown' ) ) {
751
		$markdown = WPCom_Markdown::get_instance();
752
753
		return wpautop( $markdown->transform( $content, array( 'unslash' => false ) ) );
754
	}
755
756
	return $content;
757
}
758
759
add_filter( 'woocommerce_short_description', 'wc_format_product_short_description', 9999999 );
760
761
/**
762
 * Formats curency symbols when saved in settings.
763
 * @param  string $value
764
 * @param  array $option
765
 * @param  string $raw_value
766
 * @return string
767
 */
768
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...
769
	return wp_kses_post( $raw_value );
770
}
771
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_price_decimal_sep', 'wc_format_option_price_separators', 10, 3 );
772
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_price_thousand_sep', 'wc_format_option_price_separators', 10, 3 );
773
774
/**
775
 * Formats decimals when saved in settings.
776
 * @param  string $value
777
 * @param  array $option
778
 * @param  string $raw_value
779
 * @return string
780
 */
781
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...
782
	return is_null( $raw_value ) ? 2 : absint( $raw_value );
783
}
784
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_price_num_decimals', 'wc_format_option_price_num_decimals', 10, 3 );
785
786
/**
787
 * Formats hold stock option and sets cron event up.
788
 * @param  string $value
789
 * @param  array $option
790
 * @param  string $raw_value
791
 * @return string
792
 */
793
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...
794
	$value = ! empty( $raw_value ) ? absint( $raw_value ) : ''; // Allow > 0 or set to ''
795
796
	wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
797
798
	if ( '' !== $value ) {
799
		wp_schedule_single_event( time() + ( absint( $value ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
800
	}
801
802
	return $value;
803
}
804
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_hold_stock_minutes', 'wc_format_option_hold_stock_minutes', 10, 3 );
805
806
/**
807
 * Sanitize terms from an attribute text based.
808
 *
809
 * @since  2.4.5
810
 * @param  string $term
811
 * @return string
812
 */
813
function wc_sanitize_term_text_based( $term ) {
814
	return trim( wp_unslash( strip_tags( $term ) ) );
815
}
816
817
if ( ! function_exists( 'wc_make_numeric_postcode' ) ) {
818
	/**
819
	 * Make numeric postcode.
820
	 *
821
	 * Converts letters to numbers so we can do a simple range check on postcodes.
822
	 * E.g. PE30 becomes 16050300 (P = 16, E = 05, 3 = 03, 0 = 00)
823
	 *
824
	 * @since 2.6.0
825
	 * @param string $postcode Regular postcode
826
	 * @return string
827
	 */
828
	function wc_make_numeric_postcode( $postcode ) {
829
		$postcode_length    = strlen( $postcode );
830
		$letters_to_numbers = array_merge( array( 0 ), range( 'A', 'Z' ) );
831
		$letters_to_numbers = array_flip( $letters_to_numbers );
832
		$numeric_postcode   = '';
833
834
		for ( $i = 0; $i < $postcode_length; $i ++ ) {
835
			if ( is_numeric( $postcode[ $i ] ) ) {
836
				$numeric_postcode .= str_pad( $postcode[ $i ], 2, '0', STR_PAD_LEFT );
837
			} elseif ( isset( $letters_to_numbers[ $postcode[ $i ] ] ) ) {
838
				$numeric_postcode .= str_pad( $letters_to_numbers[ $postcode[ $i ] ], 2, '0', STR_PAD_LEFT );
839
			} else {
840
				$numeric_postcode .= '00';
841
			}
842
		}
843
844
		return $numeric_postcode;
845
	}
846
}
847