$display = sprintf( __( 'Only %s left in stock', 'woocommerce' ), wc_format_stock_quantity_for_display( $stock_amount, $product ) );
}
break;
case '':
/* translators: %s: stock amount */
$display = sprintf( __( '%s in stock', 'woocommerce' ), wc_format_stock_quantity_for_display( $stock_amount, $product ) );
break;
}
if ( $product->backorders_allowed() && $product->backorders_require_notification() ) {
$display .= ' ' . __( '(can be backordered)', 'woocommerce' );
}
return $display;
}
/**
* Format the stock quantity ready for display.
*
* @since 3.0.0
* @param int $stock_quantity Stock quantity.
* @param WC_Product $product Product instance so that we can pass through the filters.
* @return string
*/
function wc_format_stock_quantity_for_display( $stock_quantity, $product ) {
return apply_filters( 'woocommerce_format_stock_quantity', $stock_quantity, $product );
}
/**
* Format a sale price for display.
*
* @since 3.0.0
* @param string $regular_price Regular price.
* @param string $sale_price Sale price.
* @return string
*/
function wc_format_sale_price( $regular_price, $sale_price ) {
$price = '' . ( is_numeric( $regular_price ) ? wc_price( $regular_price ) : $regular_price ) . ' ' . ( is_numeric( $sale_price ) ? wc_price( $sale_price ) : $sale_price ) . '';
return apply_filters( 'woocommerce_format_sale_price', $price, $regular_price, $sale_price );
}
/**
* Format a price range for display.
*
* @param string $from Price from.
* @param string $to Price to.
* @return string
*/
function wc_format_price_range( $from, $to ) {
/* translators: 1: price from 2: price to */
$price = sprintf( _x( '%1$s – %2$s', 'Price range: from-to', 'woocommerce' ), is_numeric( $from ) ? wc_price( $from ) : $from, is_numeric( $to ) ? wc_price( $to ) : $to );
return apply_filters( 'woocommerce_format_price_range', $price, $from, $to );
}
/**
* Format a weight for display.
*
* @since 3.0.0
* @param float $weight Weight.
* @return string
*/
function wc_format_weight( $weight ) {
$weight_string = wc_format_localized_decimal( $weight );
if ( ! empty( $weight_string ) ) {
$weight_string .= ' ' . get_option( 'woocommerce_weight_unit' );
} else {
$weight_string = __( 'N/A', 'woocommerce' );
}
return apply_filters( 'woocommerce_format_weight', $weight_string, $weight );
}
/**
* Format dimensions for display.
*
* @since 3.0.0
* @param array $dimensions Array of dimensions.
* @return string
*/
function wc_format_dimensions( $dimensions ) {
$dimension_string = implode( ' × ', array_filter( array_map( 'wc_format_localized_decimal', $dimensions ) ) );
if ( ! empty( $dimension_string ) ) {
$dimension_string .= ' ' . get_option( 'woocommerce_dimension_unit' );
} else {
$dimension_string = __( 'N/A', 'woocommerce' );
}
return apply_filters( 'woocommerce_format_dimensions', $dimension_string, $dimensions );
}
/**
* Format a date for output.
*
* @since 3.0.0
* @param WC_DateTime $date Instance of WC_DateTime.
* @param string $format Data format.
* Defaults to the wc_date_format function if not set.
* @return string
*/
function wc_format_datetime( $date, $format = '' ) {
if ( ! $format ) {
$format = wc_date_format();
}
if ( ! is_a( $date, 'WC_DateTime' ) ) {
return '';
}
return $date->date_i18n( $format );
}
/**
* Process oEmbeds.
*
* @since 3.1.0
* @param string $content Content.
* @return string
*/
function wc_do_oembeds( $content ) {
global $wp_embed;
$content = $wp_embed->autoembed( $content );
return $content;
}
/**
* Get part of a string before :.
*
* Used for example in shipping methods ids where they take the format
* method_id:instance_id
*
* @since 3.2.0
* @param string $string String to extract.
* @return string
*/
function wc_get_string_before_colon( $string ) {
return trim( current( explode( ':', (string) $string ) ) );
}
/**
* Array merge and sum function.
*
* Source: https://gist.github.com/Nickology/f700e319cbafab5eaedc
*
* @since 3.2.0
* @return array
*/
function wc_array_merge_recursive_numeric() {
$arrays = func_get_args();
// If there's only one array, it's already merged.
if ( 1 === count( $arrays ) ) {
return $arrays[0];
}
// Remove any items in $arrays that are NOT arrays.
foreach ( $arrays as $key => $array ) {
if ( ! is_array( $array ) ) {
unset( $arrays[ $key ] );
}
}
// We start by setting the first array as our final array.
// We will merge all other arrays with this one.
$final = array_shift( $arrays );
foreach ( $arrays as $b ) {
foreach ( $final as $key => $value ) {
// If $key does not exist in $b, then it is unique and can be safely merged.
if ( ! isset( $b[ $key ] ) ) {
$final[ $key ] = $value;
} else {
// If $key is present in $b, then we need to merge and sum numeric values in both.
if ( is_numeric( $value ) && is_numeric( $b[ $key ] ) ) {
// If both values for these keys are numeric, we sum them.
$final[ $key ] = $value + $b[ $key ];
} elseif ( is_array( $value ) && is_array( $b[ $key ] ) ) {
// If both values are arrays, we recursively call ourself.
$final[ $key ] = wc_array_merge_recursive_numeric( $value, $b[ $key ] );
} else {
// If both keys exist but differ in type, then we cannot merge them.
// In this scenario, we will $b's value for $key is used.
$final[ $key ] = $b[ $key ];
}
}
}
// Finally, we need to merge any keys that exist only in $b.
foreach ( $b as $key => $value ) {
if ( ! isset( $final[ $key ] ) ) {
$final[ $key ] = $value;
}
}
}
return $final;
}
/**
* Implode and escape HTML attributes for output.
*
* @since 3.3.0
* @param array $raw_attributes Attribute name value pairs.
* @return string
*/
function wc_implode_html_attributes( $raw_attributes ) {
$attributes = array();
foreach ( $raw_attributes as $name => $value ) {
$attributes[] = esc_attr( $name ) . '="' . esc_attr( $value ) . '"';
}
return implode( ' ', $attributes );
}
/**
* Escape JSON for use on HTML or attribute text nodes.
*
* @since 3.5.5
* @param string $json JSON to escape.
* @param bool $html True if escaping for HTML text node, false for attributes. Determines how quotes are handled.
* @return string Escaped JSON.
*/
function wc_esc_json( $json, $html = false ) {
return _wp_specialchars(
$json,
$html ? ENT_NOQUOTES : ENT_QUOTES, // Escape quotes in attribute nodes only.
'UTF-8', // json_encode() outputs UTF-8 (really just ASCII), not the blog's charset.
true // Double escape entities: `&` -> `&`.
);
}
/**
* Parse a relative date option from the settings API into a standard format.
*
* @since 3.4.0
* @param mixed $raw_value Value stored in DB.
* @return array Nicely formatted array with number and unit values.
*/
function wc_parse_relative_date_option( $raw_value ) {
$periods = array(
'days' => __( 'Day(s)', 'woocommerce' ),
'weeks' => __( 'Week(s)', 'woocommerce' ),
'months' => __( 'Month(s)', 'woocommerce' ),
'years' => __( 'Year(s)', 'woocommerce' ),
);
$value = wp_parse_args(
(array) $raw_value,
array(
'number' => '',
'unit' => 'days',
)
);
$value['number'] = ! empty( $value['number'] ) ? absint( $value['number'] ) : '';
if ( ! in_array( $value['unit'], array_keys( $periods ), true ) ) {
$value['unit'] = 'days';
}
return $value;
}
/**
* Format the endpoint slug, strip out anything not allowed in a url.
*
* @since 3.5.0
* @param string $raw_value The raw value.
* @return string
*/
function wc_sanitize_endpoint_slug( $raw_value ) {
return sanitize_title( $raw_value );
}
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_checkout_pay_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 );
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_checkout_order_received_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 );
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_add_payment_method_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 );
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_delete_payment_method_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 );
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_set_default_payment_method_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 );
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_orders_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 );
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_view_order_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 );
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_downloads_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 );
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_edit_account_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 );
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_edit_address_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 );
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_payment_methods_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 );
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_myaccount_lost_password_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 );
add_filter( 'woocommerce_admin_settings_sanitize_option_woocommerce_logout_endpoint', 'wc_sanitize_endpoint_slug', 10, 1 );