Completed
Pull Request — master (#11614)
by
unknown
08:16
created

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

Complexity

Conditions 7
Paths 7

Size

Total Lines 24
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 20
c 1
b 0
f 0
nc 7
nop 2
dl 0
loc 24
rs 6.7272
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 'JP' :
669
			$postcode = trim( substr_replace( $postcode, '-', 3, 0 ) );
670
			break;
671
		case 'PL' :
672
			$postcode = trim( substr_replace( $postcode, '-', -3, 0 ) );
673
			break;
674
		case 'PT' :
675
			$postcode = trim( substr_replace( $postcode, '-', 4, 0 ) );
676
			break;
677
	}
678
679
	return apply_filters( 'woocommerce_format_postcode', $postcode, $country );
680
}
681
682
/**
683
 * Normalize postcodes.
684
 *
685
 * Remove spaces and convert characters to uppercase.
686
 *
687
 * @since 2.6.0
688
 * @param string $postcode
689
 * @return string Sanitized postcode.
690
 */
691
function wc_normalize_postcode( $postcode ) {
692
	return preg_replace( '/[\s\-]/', '', trim( strtoupper( $postcode ) ) );
693
}
694
695
/**
696
 * format_phone function.
697
 *
698
 * @param mixed $tel
699
 * @return string
700
 */
701
function wc_format_phone_number( $tel ) {
702
	return str_replace( '.', '-', $tel );
703
}
704
705
/**
706
 * Make a string lowercase.
707
 * Try to use mb_strtolower() when available.
708
 *
709
 * @since  2.3
710
 * @param  string $string
711
 * @return string
712
 */
713
function wc_strtolower( $string ) {
714
	return function_exists( 'mb_strtolower' ) ? mb_strtolower( $string ) : strtolower( $string );
715
}
716
717
/**
718
 * Trim a string and append a suffix.
719
 * @param  string  $string
720
 * @param  integer $chars
721
 * @param  string  $suffix
722
 * @return string
723
 */
724
function wc_trim_string( $string, $chars = 200, $suffix = '...' ) {
725
	if ( strlen( $string ) > $chars ) {
726
		if ( function_exists( 'mb_substr' ) ) {
727
			$string = mb_substr( $string, 0, ( $chars - mb_strlen( $suffix ) ) ) . $suffix;
728
		} else {
729
			$string = substr( $string, 0, ( $chars - strlen( $suffix ) ) ) . $suffix;
730
		}
731
	}
732
	return $string;
733
}
734
735
/**
736
 * Format content to display shortcodes.
737
 *
738
 * @since  2.3.0
739
 * @param  string $raw_string
740
 * @return string
741
 */
742
function wc_format_content( $raw_string ) {
743
	return apply_filters( 'woocommerce_format_content', do_shortcode( shortcode_unautop( wpautop( $raw_string ) ) ), $raw_string );
744
}
745
746
/**
747
 * Format product short description.
748
 * Adds support for Jetpack Markdown.
749
 *
750
 * @since  2.4.0
751
 * @param  string $content
752
 * @return string
753
 */
754
function wc_format_product_short_description( $content ) {
755
	// Add support for Jetpack Markdown
756
	if ( class_exists( 'WPCom_Markdown' ) ) {
757
		$markdown = WPCom_Markdown::get_instance();
758
759
		return wpautop( $markdown->transform( $content, array( 'unslash' => false ) ) );
760
	}
761
762
	return $content;
763
}
764
765
add_filter( 'woocommerce_short_description', 'wc_format_product_short_description', 9999999 );
766
767
/**
768
 * Formats curency symbols when saved in settings.
769
 * @param  string $value
770
 * @param  array $option
771
 * @param  string $raw_value
772
 * @return string
773
 */
774
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...
775
	return wp_kses_post( $raw_value );
776
}
777
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_price_decimal_sep', 'wc_format_option_price_separators', 10, 3 );
778
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_price_thousand_sep', 'wc_format_option_price_separators', 10, 3 );
779
780
/**
781
 * Formats decimals when saved in settings.
782
 * @param  string $value
783
 * @param  array $option
784
 * @param  string $raw_value
785
 * @return string
786
 */
787
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...
788
	return is_null( $raw_value ) ? 2 : absint( $raw_value );
789
}
790
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_price_num_decimals', 'wc_format_option_price_num_decimals', 10, 3 );
791
792
/**
793
 * Formats hold stock option and sets cron event up.
794
 * @param  string $value
795
 * @param  array $option
796
 * @param  string $raw_value
797
 * @return string
798
 */
799
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...
800
	$value = ! empty( $raw_value ) ? absint( $raw_value ) : ''; // Allow > 0 or set to ''
801
802
	wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
803
804
	if ( '' !== $value ) {
805
		wp_schedule_single_event( time() + ( absint( $value ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
806
	}
807
808
	return $value;
809
}
810
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_hold_stock_minutes', 'wc_format_option_hold_stock_minutes', 10, 3 );
811
812
/**
813
 * Sanitize terms from an attribute text based.
814
 *
815
 * @since  2.4.5
816
 * @param  string $term
817
 * @return string
818
 */
819
function wc_sanitize_term_text_based( $term ) {
820
	return trim( wp_unslash( strip_tags( $term ) ) );
821
}
822
823
if ( ! function_exists( 'wc_make_numeric_postcode' ) ) {
824
	/**
825
	 * Make numeric postcode.
826
	 *
827
	 * Converts letters to numbers so we can do a simple range check on postcodes.
828
	 * E.g. PE30 becomes 16050300 (P = 16, E = 05, 3 = 03, 0 = 00)
829
	 *
830
	 * @since 2.6.0
831
	 * @param string $postcode Regular postcode
832
	 * @return string
833
	 */
834
	function wc_make_numeric_postcode( $postcode ) {
835
		$postcode           = str_replace( array( ' ', '-' ), '', $postcode );
836
		$postcode_length    = strlen( $postcode );
837
		$letters_to_numbers = array_merge( array( 0 ), range( 'A', 'Z' ) );
838
		$letters_to_numbers = array_flip( $letters_to_numbers );
839
		$numeric_postcode   = '';
840
841
		for ( $i = 0; $i < $postcode_length; $i ++ ) {
842
			if ( is_numeric( $postcode[ $i ] ) ) {
843
				$numeric_postcode .= str_pad( $postcode[ $i ], 2, '0', STR_PAD_LEFT );
844
			} elseif ( isset( $letters_to_numbers[ $postcode[ $i ] ] ) ) {
845
				$numeric_postcode .= str_pad( $letters_to_numbers[ $postcode[ $i ] ], 2, '0', STR_PAD_LEFT );
846
			} else {
847
				$numeric_postcode .= '00';
848
			}
849
		}
850
851
		return $numeric_postcode;
852
	}
853
}
854