Welcome to the very best in globally sourced premium goods.
We offer free shipping, free returns shopping experience.
/**
* Deprecated functions
*
* Where functions come to die.
*
* @author Automattic
* @category Core
* @package WooCommerce\Functions
* @version 3.3.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Runs a deprecated action with notice only if used.
*
* @since 3.0.0
* @param string $tag The name of the action hook.
* @param array $args Array of additional function arguments to be passed to do_action().
* @param string $version The version of WooCommerce that deprecated the hook.
* @param string $replacement The hook that should have been used.
* @param string $message A message regarding the change.
*/
function wc_do_deprecated_action( $tag, $args, $version, $replacement = null, $message = null ) {
if ( ! has_action( $tag ) ) {
return;
}
wc_deprecated_hook( $tag, $version, $replacement, $message );
do_action_ref_array( $tag, $args );
}
/**
* Wrapper for deprecated functions so we can apply some extra logic.
*
* @since 3.0.0
* @param string $function Function used.
* @param string $version Version the message was added in.
* @param string $replacement Replacement for the called function.
*/
function wc_deprecated_function( $function, $version, $replacement = null ) {
// @codingStandardsIgnoreStart
if ( wp_doing_ajax() || WC()->is_rest_api_request() ) {
do_action( 'deprecated_function_run', $function, $replacement, $version );
$log_string = "The {$function} function is deprecated since version {$version}.";
$log_string .= $replacement ? " Replace with {$replacement}." : '';
error_log( $log_string );
} else {
_deprecated_function( $function, $version, $replacement );
}
// @codingStandardsIgnoreEnd
}
/**
* Wrapper for deprecated hook so we can apply some extra logic.
*
* @since 3.3.0
* @param string $hook The hook that was used.
* @param string $version The version of WordPress that deprecated the hook.
* @param string $replacement The hook that should have been used.
* @param string $message A message regarding the change.
*/
function wc_deprecated_hook( $hook, $version, $replacement = null, $message = null ) {
// @codingStandardsIgnoreStart
if ( wp_doing_ajax() || WC()->is_rest_api_request() ) {
do_action( 'deprecated_hook_run', $hook, $replacement, $version, $message );
$message = empty( $message ) ? '' : ' ' . $message;
$log_string = "{$hook} is deprecated since version {$version}";
$log_string .= $replacement ? "! Use {$replacement} instead." : ' with no alternative available.';
error_log( $log_string . $message );
} else {
_deprecated_hook( $hook, $version, $replacement, $message );
}
// @codingStandardsIgnoreEnd
}
/**
* When catching an exception, this allows us to log it if unexpected.
*
* @since 3.3.0
* @param Exception $exception_object The exception object.
* @param string $function The function which threw exception.
* @param array $args The args passed to the function.
*/
function wc_caught_exception( $exception_object, $function = '', $args = array() ) {
// @codingStandardsIgnoreStart
$message = $exception_object->getMessage();
$message .= '. Args: ' . print_r( $args, true ) . '.';
do_action( 'woocommerce_caught_exception', $exception_object, $function, $args );
error_log( "Exception caught in {$function}. {$message}." );
// @codingStandardsIgnoreEnd
}
/**
* Wrapper for _doing_it_wrong().
*
* @since 3.0.0
* @param string $function Function used.
* @param string $message Message to log.
* @param string $version Version the message was added in.
*/
function wc_doing_it_wrong( $function, $message, $version ) {
// @codingStandardsIgnoreStart
$message .= ' Backtrace: ' . wp_debug_backtrace_summary();
if ( wp_doing_ajax() || WC()->is_rest_api_request() ) {
do_action( 'doing_it_wrong_run', $function, $message, $version );
error_log( "{$function} was called incorrectly. {$message}. This message was added in version {$version}." );
} else {
_doing_it_wrong( $function, $message, $version );
}
// @codingStandardsIgnoreEnd
}
/**
* Wrapper for deprecated arguments so we can apply some extra logic.
*
* @since 3.0.0
* @param string $argument
* @param string $version
* @param string $replacement
*/
function wc_deprecated_argument( $argument, $version, $message = null ) {
if ( wp_doing_ajax() || WC()->is_rest_api_request() ) {
do_action( 'deprecated_argument_run', $argument, $message, $version );
error_log( "The {$argument} argument is deprecated since version {$version}. {$message}" );
} else {
_deprecated_argument( $argument, $version, $message );
}
}
/**
* @deprecated 2.1
*/
function woocommerce_show_messages() {
wc_deprecated_function( 'woocommerce_show_messages', '2.1', 'wc_print_notices' );
wc_print_notices();
}
/**
* @deprecated 2.1
*/
function woocommerce_weekend_area_js() {
wc_deprecated_function( 'woocommerce_weekend_area_js', '2.1' );
}
/**
* @deprecated 2.1
*/
function woocommerce_tooltip_js() {
wc_deprecated_function( 'woocommerce_tooltip_js', '2.1' );
}
/**
* @deprecated 2.1
*/
function woocommerce_datepicker_js() {
wc_deprecated_function( 'woocommerce_datepicker_js', '2.1' );
}
/**
* @deprecated 2.1
*/
function woocommerce_admin_scripts() {
wc_deprecated_function( 'woocommerce_admin_scripts', '2.1' );
}
/**
* @deprecated 2.1
*/
function woocommerce_create_page( $slug, $option = '', $page_title = '', $page_content = '', $post_parent = 0 ) {
wc_deprecated_function( 'woocommerce_create_page', '2.1', 'wc_create_page' );
return wc_create_page( $slug, $option, $page_title, $page_content, $post_parent );
}
/**
* @deprecated 2.1
*/
function woocommerce_readfile_chunked( $file, $retbytes = true ) {
wc_deprecated_function( 'woocommerce_readfile_chunked', '2.1', 'WC_Download_Handler::readfile_chunked()' );
return WC_Download_Handler::readfile_chunked( $file );
}
/**
* Formal total costs - format to the number of decimal places for the base currency.
*
* @access public
* @param mixed $number
* @deprecated 2.1
* @return string
*/
function woocommerce_format_total( $number ) {
wc_deprecated_function( __FUNCTION__, '2.1', 'wc_format_decimal()' );
return wc_format_decimal( $number, wc_get_price_decimals(), false );
}
/**
* Get product name with extra details such as SKU price and attributes. Used within admin.
*
* @access public
* @param WC_Product $product
* @deprecated 2.1
* @return string
*/
function woocommerce_get_formatted_product_name( $product ) {
wc_deprecated_function( __FUNCTION__, '2.1', 'WC_Product::get_formatted_name()' );
return $product->get_formatted_name();
}
/**
* Handle IPN requests for the legacy paypal gateway by calling gateways manually if needed.
*
* @access public
*/
function woocommerce_legacy_paypal_ipn() {
if ( ! empty( $_GET['paypalListener'] ) && 'paypal_standard_IPN' === $_GET['paypalListener'] ) {
WC()->payment_gateways();
do_action( 'woocommerce_api_wc_gateway_paypal' );
}
}
add_action( 'init', 'woocommerce_legacy_paypal_ipn' );
/**
* @deprecated 3.0
*/
function get_product( $the_product = false, $args = array() ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_product' );
return wc_get_product( $the_product, $args );
}
/**
* @deprecated 3.0
*/
function woocommerce_protected_product_add_to_cart( $passed, $product_id ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_protected_product_add_to_cart' );
return wc_protected_product_add_to_cart( $passed, $product_id );
}
/**
* @deprecated 3.0
*/
function woocommerce_empty_cart() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_empty_cart' );
wc_empty_cart();
}
/**
* @deprecated 3.0
*/
function woocommerce_load_persistent_cart( $user_login, $user = 0 ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_load_persistent_cart' );
return wc_load_persistent_cart( $user_login, $user );
}
/**
* @deprecated 3.0
*/
function woocommerce_add_to_cart_message( $product_id ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_add_to_cart_message' );
wc_add_to_cart_message( $product_id );
}
/**
* @deprecated 3.0
*/
function woocommerce_clear_cart_after_payment() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_clear_cart_after_payment' );
wc_clear_cart_after_payment();
}
/**
* @deprecated 3.0
*/
function woocommerce_cart_totals_subtotal_html() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cart_totals_subtotal_html' );
wc_cart_totals_subtotal_html();
}
/**
* @deprecated 3.0
*/
function woocommerce_cart_totals_shipping_html() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cart_totals_shipping_html' );
wc_cart_totals_shipping_html();
}
/**
* @deprecated 3.0
*/
function woocommerce_cart_totals_coupon_html( $coupon ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cart_totals_coupon_html' );
wc_cart_totals_coupon_html( $coupon );
}
/**
* @deprecated 3.0
*/
function woocommerce_cart_totals_order_total_html() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cart_totals_order_total_html' );
wc_cart_totals_order_total_html();
}
/**
* @deprecated 3.0
*/
function woocommerce_cart_totals_fee_html( $fee ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cart_totals_fee_html' );
wc_cart_totals_fee_html( $fee );
}
/**
* @deprecated 3.0
*/
function woocommerce_cart_totals_shipping_method_label( $method ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cart_totals_shipping_method_label' );
return wc_cart_totals_shipping_method_label( $method );
}
/**
* @deprecated 3.0
*/
function woocommerce_get_template_part( $slug, $name = '' ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_template_part' );
wc_get_template_part( $slug, $name );
}
/**
* @deprecated 3.0
*/
function woocommerce_get_template( $template_name, $args = array(), $template_path = '', $default_path = '' ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_template' );
wc_get_template( $template_name, $args, $template_path, $default_path );
}
/**
* @deprecated 3.0
*/
function woocommerce_locate_template( $template_name, $template_path = '', $default_path = '' ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_locate_template' );
return wc_locate_template( $template_name, $template_path, $default_path );
}
/**
* @deprecated 3.0
*/
function woocommerce_mail( $to, $subject, $message, $headers = "Content-Type: text/html\r\n", $attachments = "" ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_mail' );
wc_mail( $to, $subject, $message, $headers, $attachments );
}
/**
* @deprecated 3.0
*/
function woocommerce_disable_admin_bar( $show_admin_bar ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_disable_admin_bar' );
return wc_disable_admin_bar( $show_admin_bar );
}
/**
* @deprecated 3.0
*/
function woocommerce_create_new_customer( $email, $username = '', $password = '' ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_create_new_customer' );
return wc_create_new_customer( $email, $username, $password );
}
/**
* @deprecated 3.0
*/
function woocommerce_set_customer_auth_cookie( $customer_id ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_set_customer_auth_cookie' );
wc_set_customer_auth_cookie( $customer_id );
}
/**
* @deprecated 3.0
*/
function woocommerce_update_new_customer_past_orders( $customer_id ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_update_new_customer_past_orders' );
return wc_update_new_customer_past_orders( $customer_id );
}
/**
* @deprecated 3.0
*/
function woocommerce_paying_customer( $order_id ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_paying_customer' );
wc_paying_customer( $order_id );
}
/**
* @deprecated 3.0
*/
function woocommerce_customer_bought_product( $customer_email, $user_id, $product_id ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_customer_bought_product' );
return wc_customer_bought_product( $customer_email, $user_id, $product_id );
}
/**
* @deprecated 3.0
*/
function woocommerce_customer_has_capability( $allcaps, $caps, $args ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_customer_has_capability' );
return wc_customer_has_capability( $allcaps, $caps, $args );
}
/**
* @deprecated 3.0
*/
function woocommerce_sanitize_taxonomy_name( $taxonomy ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_sanitize_taxonomy_name' );
return wc_sanitize_taxonomy_name( $taxonomy );
}
/**
* @deprecated 3.0
*/
function woocommerce_get_filename_from_url( $file_url ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_filename_from_url' );
return wc_get_filename_from_url( $file_url );
}
/**
* @deprecated 3.0
*/
function woocommerce_get_dimension( $dim, $to_unit ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_dimension' );
return wc_get_dimension( $dim, $to_unit );
}
/**
* @deprecated 3.0
*/
function woocommerce_get_weight( $weight, $to_unit ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_weight' );
return wc_get_weight( $weight, $to_unit );
}
/**
* @deprecated 3.0
*/
function woocommerce_trim_zeros( $price ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_trim_zeros' );
return wc_trim_zeros( $price );
}
/**
* @deprecated 3.0
*/
function woocommerce_round_tax_total( $tax ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_round_tax_total' );
return wc_round_tax_total( $tax );
}
/**
* @deprecated 3.0
*/
function woocommerce_format_decimal( $number, $dp = false, $trim_zeros = false ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_format_decimal' );
return wc_format_decimal( $number, $dp, $trim_zeros );
}
/**
* @deprecated 3.0
*/
function woocommerce_clean( $var ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_clean' );
return wc_clean( $var );
}
/**
* @deprecated 3.0
*/
function woocommerce_array_overlay( $a1, $a2 ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_array_overlay' );
return wc_array_overlay( $a1, $a2 );
}
/**
* @deprecated 3.0
*/
function woocommerce_price( $price, $args = array() ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_price' );
return wc_price( $price, $args );
}
/**
* @deprecated 3.0
*/
function woocommerce_let_to_num( $size ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_let_to_num' );
return wc_let_to_num( $size );
}
/**
* @deprecated 3.0
*/
function woocommerce_date_format() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_date_format' );
return wc_date_format();
}
/**
* @deprecated 3.0
*/
function woocommerce_time_format() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_time_format' );
return wc_time_format();
}
/**
* @deprecated 3.0
*/
function woocommerce_timezone_string() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_timezone_string' );
return wc_timezone_string();
}
if ( ! function_exists( 'woocommerce_rgb_from_hex' ) ) {
/**
* @deprecated 3.0
*/
function woocommerce_rgb_from_hex( $color ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_rgb_from_hex' );
return wc_rgb_from_hex( $color );
}
}
if ( ! function_exists( 'woocommerce_hex_darker' ) ) {
/**
* @deprecated 3.0
*/
function woocommerce_hex_darker( $color, $factor = 30 ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_hex_darker' );
return wc_hex_darker( $color, $factor );
}
}
if ( ! function_exists( 'woocommerce_hex_lighter' ) ) {
/**
* @deprecated 3.0
*/
function woocommerce_hex_lighter( $color, $factor = 30 ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_hex_lighter' );
return wc_hex_lighter( $color, $factor );
}
}
if ( ! function_exists( 'woocommerce_light_or_dark' ) ) {
/**
* @deprecated 3.0
*/
function woocommerce_light_or_dark( $color, $dark = '#000000', $light = '#FFFFFF' ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_light_or_dark' );
return wc_light_or_dark( $color, $dark, $light );
}
}
if ( ! function_exists( 'woocommerce_format_hex' ) ) {
/**
* @deprecated 3.0
*/
function woocommerce_format_hex( $hex ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_format_hex' );
return wc_format_hex( $hex );
}
}
/**
* @deprecated 3.0
*/
function woocommerce_get_order_id_by_order_key( $order_key ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_order_id_by_order_key' );
return wc_get_order_id_by_order_key( $order_key );
}
/**
* @deprecated 3.0
*/
function woocommerce_downloadable_file_permission( $download_id, $product_id, $order ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_downloadable_file_permission' );
return wc_downloadable_file_permission( $download_id, $product_id, $order );
}
/**
* @deprecated 3.0
*/
function woocommerce_downloadable_product_permissions( $order_id ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_downloadable_product_permissions' );
wc_downloadable_product_permissions( $order_id );
}
/**
* @deprecated 3.0
*/
function woocommerce_add_order_item( $order_id, $item ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_add_order_item' );
return wc_add_order_item( $order_id, $item );
}
/**
* @deprecated 3.0
*/
function woocommerce_delete_order_item( $item_id ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_delete_order_item' );
return wc_delete_order_item( $item_id );
}
/**
* @deprecated 3.0
*/
function woocommerce_update_order_item_meta( $item_id, $meta_key, $meta_value, $prev_value = '' ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_update_order_item_meta' );
return wc_update_order_item_meta( $item_id, $meta_key, $meta_value, $prev_value );
}
/**
* @deprecated 3.0
*/
function woocommerce_add_order_item_meta( $item_id, $meta_key, $meta_value, $unique = false ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_add_order_item_meta' );
return wc_add_order_item_meta( $item_id, $meta_key, $meta_value, $unique );
}
/**
* @deprecated 3.0
*/
function woocommerce_delete_order_item_meta( $item_id, $meta_key, $meta_value = '', $delete_all = false ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_delete_order_item_meta' );
return wc_delete_order_item_meta( $item_id, $meta_key, $meta_value, $delete_all );
}
/**
* @deprecated 3.0
*/
function woocommerce_get_order_item_meta( $item_id, $key, $single = true ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_order_item_meta' );
return wc_get_order_item_meta( $item_id, $key, $single );
}
/**
* @deprecated 3.0
*/
function woocommerce_cancel_unpaid_orders() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_cancel_unpaid_orders' );
wc_cancel_unpaid_orders();
}
/**
* @deprecated 3.0
*/
function woocommerce_processing_order_count() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_processing_order_count' );
return wc_processing_order_count();
}
/**
* @deprecated 3.0
*/
function woocommerce_get_page_id( $page ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_page_id' );
return wc_get_page_id( $page );
}
/**
* @deprecated 3.0
*/
function woocommerce_get_endpoint_url( $endpoint, $value = '', $permalink = '' ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_endpoint_url' );
return wc_get_endpoint_url( $endpoint, $value, $permalink );
}
/**
* @deprecated 3.0
*/
function woocommerce_lostpassword_url( $url ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_lostpassword_url' );
return wc_lostpassword_url( $url );
}
/**
* @deprecated 3.0
*/
function woocommerce_customer_edit_account_url() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_customer_edit_account_url' );
return wc_customer_edit_account_url();
}
/**
* @deprecated 3.0
*/
function woocommerce_nav_menu_items( $items, $args ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_nav_menu_items' );
return wc_nav_menu_items( $items );
}
/**
* @deprecated 3.0
*/
function woocommerce_nav_menu_item_classes( $menu_items, $args ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_nav_menu_item_classes' );
return wc_nav_menu_item_classes( $menu_items );
}
/**
* @deprecated 3.0
*/
function woocommerce_list_pages( $pages ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_list_pages' );
return wc_list_pages( $pages );
}
/**
* @deprecated 3.0
*/
function woocommerce_product_dropdown_categories( $args = array(), $deprecated_hierarchical = 1, $deprecated_show_uncategorized = 1, $deprecated_orderby = '' ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_product_dropdown_categories' );
return wc_product_dropdown_categories( $args, $deprecated_hierarchical, $deprecated_show_uncategorized, $deprecated_orderby );
}
/**
* @deprecated 3.0
*/
function woocommerce_walk_category_dropdown_tree( $a1 = '', $a2 = '', $a3 = '' ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_walk_category_dropdown_tree' );
return wc_walk_category_dropdown_tree( $a1, $a2, $a3 );
}
/**
* @deprecated 3.0
*/
function woocommerce_taxonomy_metadata_wpdbfix() {
wc_deprecated_function( __FUNCTION__, '3.0' );
}
/**
* @deprecated 3.0
*/
function wc_taxonomy_metadata_wpdbfix() {
wc_deprecated_function( __FUNCTION__, '3.0' );
}
/**
* @deprecated 3.0
*/
function woocommerce_order_terms( $the_term, $next_id, $taxonomy, $index = 0, $terms = null ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_reorder_terms' );
return wc_reorder_terms( $the_term, $next_id, $taxonomy, $index, $terms );
}
/**
* @deprecated 3.0
*/
function woocommerce_set_term_order( $term_id, $index, $taxonomy, $recursive = false ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_set_term_order' );
return wc_set_term_order( $term_id, $index, $taxonomy, $recursive );
}
/**
* @deprecated 3.0
*/
function woocommerce_terms_clauses( $clauses, $taxonomies, $args ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_terms_clauses' );
return wc_terms_clauses( $clauses, $taxonomies, $args );
}
/**
* @deprecated 3.0
*/
function _woocommerce_term_recount( $terms, $taxonomy, $callback, $terms_are_term_taxonomy_ids ) {
wc_deprecated_function( __FUNCTION__, '3.0', '_wc_term_recount' );
return _wc_term_recount( $terms, $taxonomy, $callback, $terms_are_term_taxonomy_ids );
}
/**
* @deprecated 3.0
*/
function woocommerce_recount_after_stock_change( $product_id ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_recount_after_stock_change' );
return wc_recount_after_stock_change( $product_id );
}
/**
* @deprecated 3.0
*/
function woocommerce_change_term_counts( $terms, $taxonomies, $args ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_change_term_counts' );
return wc_change_term_counts( $terms, $taxonomies );
}
/**
* @deprecated 3.0
*/
function woocommerce_get_product_ids_on_sale() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_product_ids_on_sale' );
return wc_get_product_ids_on_sale();
}
/**
* @deprecated 3.0
*/
function woocommerce_get_featured_product_ids() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_featured_product_ids' );
return wc_get_featured_product_ids();
}
/**
* @deprecated 3.0
*/
function woocommerce_get_product_terms( $object_id, $taxonomy, $fields = 'all' ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_product_terms' );
return wc_get_product_terms( $object_id, $taxonomy, array( 'fields' => $fields ) );
}
/**
* @deprecated 3.0
*/
function woocommerce_product_post_type_link( $permalink, $post ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_product_post_type_link' );
return wc_product_post_type_link( $permalink, $post );
}
/**
* @deprecated 3.0
*/
function woocommerce_placeholder_img_src() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_placeholder_img_src' );
return wc_placeholder_img_src();
}
/**
* @deprecated 3.0
*/
function woocommerce_placeholder_img( $size = 'woocommerce_thumbnail' ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_placeholder_img' );
return wc_placeholder_img( $size );
}
/**
* @deprecated 3.0
*/
function woocommerce_get_formatted_variation( $variation = '', $flat = false ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_formatted_variation' );
return wc_get_formatted_variation( $variation, $flat );
}
/**
* @deprecated 3.0
*/
function woocommerce_scheduled_sales() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_scheduled_sales' );
return wc_scheduled_sales();
}
/**
* @deprecated 3.0
*/
function woocommerce_get_attachment_image_attributes( $attr ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_get_attachment_image_attributes' );
return wc_get_attachment_image_attributes( $attr );
}
/**
* @deprecated 3.0
*/
function woocommerce_prepare_attachment_for_js( $response ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_prepare_attachment_for_js' );
return wc_prepare_attachment_for_js( $response );
}
/**
* @deprecated 3.0
*/
function woocommerce_track_product_view() {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_track_product_view' );
return wc_track_product_view();
}
/**
* @deprecated 2.3 has no replacement
*/
function woocommerce_compile_less_styles() {
wc_deprecated_function( 'woocommerce_compile_less_styles', '2.3' );
}
/**
* woocommerce_calc_shipping was an option used to determine if shipping was enabled prior to version 2.6.0. This has since been replaced with wc_shipping_enabled() function and
* the woocommerce_ship_to_countries setting.
* @deprecated 2.6.0
* @return string
*/
function woocommerce_calc_shipping_backwards_compatibility( $value ) {
if ( Constants::is_defined( 'WC_UPDATING' ) ) {
return $value;
}
return 'disabled' === get_option( 'woocommerce_ship_to_countries' ) ? 'no' : 'yes';
}
add_filter( 'pre_option_woocommerce_calc_shipping', 'woocommerce_calc_shipping_backwards_compatibility' );
/**
* @deprecated 3.0.0
* @see WC_Structured_Data class
*
* @return string
*/
function woocommerce_get_product_schema() {
wc_deprecated_function( 'woocommerce_get_product_schema', '3.0' );
global $product;
$schema = "Product";
// Downloadable product schema handling
if ( $product->is_downloadable() ) {
switch ( $product->download_type ) {
case 'application' :
$schema = "SoftwareApplication";
break;
case 'music' :
$schema = "MusicAlbum";
break;
default :
$schema = "Product";
break;
}
}
return 'http://schema.org/' . $schema;
}
/**
* Save product price.
*
* This is a private function (internal use ONLY) used until a data manipulation api is built.
*
* @deprecated 3.0.0
* @param int $product_id
* @param float $regular_price
* @param float $sale_price
* @param string $date_from
* @param string $date_to
*/
function _wc_save_product_price( $product_id, $regular_price, $sale_price = '', $date_from = '', $date_to = '' ) {
wc_doing_it_wrong( '_wc_save_product_price()', 'This function is not for developer use and is deprecated.', '3.0' );
$product_id = absint( $product_id );
$regular_price = wc_format_decimal( $regular_price );
$sale_price = '' === $sale_price ? '' : wc_format_decimal( $sale_price );
$date_from = wc_clean( $date_from );
$date_to = wc_clean( $date_to );
update_post_meta( $product_id, '_regular_price', $regular_price );
update_post_meta( $product_id, '_sale_price', $sale_price );
// Save Dates
update_post_meta( $product_id, '_sale_price_dates_from', $date_from ? strtotime( $date_from ) : '' );
update_post_meta( $product_id, '_sale_price_dates_to', $date_to ? strtotime( $date_to ) : '' );
if ( $date_to && ! $date_from ) {
$date_from = strtotime( 'NOW', current_time( 'timestamp' ) );
update_post_meta( $product_id, '_sale_price_dates_from', $date_from );
}
// Update price if on sale
if ( '' !== $sale_price && '' === $date_to && '' === $date_from ) {
update_post_meta( $product_id, '_price', $sale_price );
} else {
update_post_meta( $product_id, '_price', $regular_price );
}
if ( '' !== $sale_price && $date_from && strtotime( $date_from ) < strtotime( 'NOW', current_time( 'timestamp' ) ) ) {
update_post_meta( $product_id, '_price', $sale_price );
}
if ( $date_to && strtotime( $date_to ) < strtotime( 'NOW', current_time( 'timestamp' ) ) ) {
update_post_meta( $product_id, '_price', $regular_price );
update_post_meta( $product_id, '_sale_price_dates_from', '' );
update_post_meta( $product_id, '_sale_price_dates_to', '' );
}
}
/**
* Return customer avatar URL.
*
* @deprecated 3.1.0
* @since 2.6.0
* @param string $email the customer's email.
* @return string the URL to the customer's avatar.
*/
function wc_get_customer_avatar_url( $email ) {
// Deprecated in favor of WordPress get_avatar_url() function.
wc_deprecated_function( 'wc_get_customer_avatar_url()', '3.1', 'get_avatar_url()' );
return get_avatar_url( $email );
}
/**
* WooCommerce Core Supported Themes.
*
* @deprecated 3.3.0
* @since 2.2
* @return string[]
*/
function wc_get_core_supported_themes() {
wc_deprecated_function( 'wc_get_core_supported_themes()', '3.3' );
return array( 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' );
}
/**
* Get min/max price meta query args.
*
* @deprecated 3.6.0
* @since 3.0.0
* @param array $args Min price and max price arguments.
* @return array
*/
function wc_get_min_max_price_meta_query( $args ) {
wc_deprecated_function( 'wc_get_min_max_price_meta_query()', '3.6' );
$current_min_price = isset( $args['min_price'] ) ? floatval( $args['min_price'] ) : 0;
$current_max_price = isset( $args['max_price'] ) ? floatval( $args['max_price'] ) : PHP_INT_MAX;
return apply_filters(
'woocommerce_get_min_max_price_meta_query',
array(
'key' => '_price',
'value' => array( $current_min_price, $current_max_price ),
'compare' => 'BETWEEN',
'type' => 'DECIMAL(10,' . wc_get_price_decimals() . ')',
),
$args
);
}
/**
* When a term is split, ensure meta data maintained.
*
* @deprecated 3.6.0
* @param int $old_term_id Old term ID.
* @param int $new_term_id New term ID.
* @param string $term_taxonomy_id Term taxonomy ID.
* @param string $taxonomy Taxonomy.
*/
function wc_taxonomy_metadata_update_content_for_split_terms( $old_term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) {
wc_deprecated_function( 'wc_taxonomy_metadata_update_content_for_split_terms', '3.6' );
}
/**
* WooCommerce Term Meta API.
*
* WC tables for storing term meta are deprecated from WordPress 4.4 since 4.4 has its own table.
* This function serves as a wrapper, using the new table if present, or falling back to the WC table.
*
* @deprecated 3.6.0
* @param int $term_id Term ID.
* @param string $meta_key Meta key.
* @param mixed $meta_value Meta value.
* @param string $prev_value Previous value. (default: '').
* @return bool
*/
function update_woocommerce_term_meta( $term_id, $meta_key, $meta_value, $prev_value = '' ) {
wc_deprecated_function( 'update_woocommerce_term_meta', '3.6', 'update_term_meta' );
return function_exists( 'update_term_meta' ) ? update_term_meta( $term_id, $meta_key, $meta_value, $prev_value ) : update_metadata( 'woocommerce_term', $term_id, $meta_key, $meta_value, $prev_value );
}
/**
* WooCommerce Term Meta API.
*
* WC tables for storing term meta are deprecated from WordPress 4.4 since 4.4 has its own table.
* This function serves as a wrapper, using the new table if present, or falling back to the WC table.
*
* @deprecated 3.6.0
* @param int $term_id Term ID.
* @param string $meta_key Meta key.
* @param mixed $meta_value Meta value.
* @param bool $unique Make meta key unique. (default: false).
* @return bool
*/
function add_woocommerce_term_meta( $term_id, $meta_key, $meta_value, $unique = false ) {
wc_deprecated_function( 'add_woocommerce_term_meta', '3.6', 'add_term_meta' );
return function_exists( 'add_term_meta' ) ? add_term_meta( $term_id, $meta_key, $meta_value, $unique ) : add_metadata( 'woocommerce_term', $term_id, $meta_key, $meta_value, $unique );
}
/**
* WooCommerce Term Meta API
*
* WC tables for storing term meta are deprecated from WordPress 4.4 since 4.4 has its own table.
* This function serves as a wrapper, using the new table if present, or falling back to the WC table.
*
* @deprecated 3.6.0
* @param int $term_id Term ID.
* @param string $meta_key Meta key.
* @param mixed $meta_value Meta value (default: '').
* @param bool $deprecated Deprecated param (default: false).
* @return bool
*/
function delete_woocommerce_term_meta( $term_id, $meta_key, $meta_value = '', $deprecated = false ) {
wc_deprecated_function( 'delete_woocommerce_term_meta', '3.6', 'delete_term_meta' );
return function_exists( 'delete_term_meta' ) ? delete_term_meta( $term_id, $meta_key, $meta_value ) : delete_metadata( 'woocommerce_term', $term_id, $meta_key, $meta_value );
}
/**
* WooCommerce Term Meta API
*
* WC tables for storing term meta are deprecated from WordPress 4.4 since 4.4 has its own table.
* This function serves as a wrapper, using the new table if present, or falling back to the WC table.
*
* @deprecated 3.6.0
* @param int $term_id Term ID.
* @param string $key Meta key.
* @param bool $single Whether to return a single value. (default: true).
* @return mixed
*/
function get_woocommerce_term_meta( $term_id, $key, $single = true ) {
wc_deprecated_function( 'get_woocommerce_term_meta', '3.6', 'get_term_meta' );
return function_exists( 'get_term_meta' ) ? get_term_meta( $term_id, $key, $single ) : get_metadata( 'woocommerce_term', $term_id, $key, $single );
}
/**
* WooCommerce Order Item Functions
*
* Functions for order specific things.
*
* @package WooCommerce\Functions
* @version 3.4.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Add a item to an order (for example a line item).
*
* @param int $order_id Order ID.
* @param array $item_array Items list.
*
* @throws Exception When `WC_Data_Store::load` validation fails.
* @return int|bool Item ID or false
*/
function wc_add_order_item( $order_id, $item_array ) {
$order_id = absint( $order_id );
if ( ! $order_id ) {
return false;
}
$defaults = array(
'order_item_name' => '',
'order_item_type' => 'line_item',
);
$item_array = wp_parse_args( $item_array, $defaults );
$data_store = WC_Data_Store::load( 'order-item' );
$item_id = $data_store->add_order_item( $order_id, $item_array );
$item = WC_Order_Factory::get_order_item( $item_id );
do_action( 'woocommerce_new_order_item', $item_id, $item, $order_id );
return $item_id;
}
/**
* Update an item for an order.
*
* @since 2.2
* @param int $item_id Item ID.
* @param array $args Either `order_item_type` or `order_item_name`.
*
* @throws Exception When `WC_Data_Store::load` validation fails.
* @return bool True if successfully updated, false otherwise.
*/
function wc_update_order_item( $item_id, $args ) {
$data_store = WC_Data_Store::load( 'order-item' );
$update = $data_store->update_order_item( $item_id, $args );
if ( false === $update ) {
return false;
}
do_action( 'woocommerce_update_order_item', $item_id, $args );
return true;
}
/**
* Delete an item from the order it belongs to based on item id.
*
* @param int $item_id Item ID.
*
* @throws Exception When `WC_Data_Store::load` validation fails.
* @return bool
*/
function wc_delete_order_item( $item_id ) {
$item_id = absint( $item_id );
if ( ! $item_id ) {
return false;
}
$data_store = WC_Data_Store::load( 'order-item' );
do_action( 'woocommerce_before_delete_order_item', $item_id );
$data_store->delete_order_item( $item_id );
do_action( 'woocommerce_delete_order_item', $item_id );
return true;
}
/**
* WooCommerce Order Item Meta API - Update term meta.
*
* @param int $item_id Item ID.
* @param string $meta_key Meta key.
* @param mixed $meta_value Meta value.
* @param string $prev_value Previous value (default: '').
*
* @throws Exception When `WC_Data_Store::load` validation fails.
* @return bool
*/
function wc_update_order_item_meta( $item_id, $meta_key, $meta_value, $prev_value = '' ) {
$data_store = WC_Data_Store::load( 'order-item' );
if ( $data_store->update_metadata( $item_id, $meta_key, $meta_value, $prev_value ) ) {
WC_Cache_Helper::invalidate_cache_group( 'object_' . $item_id ); // Invalidate cache.
return true;
}
return false;
}
/**
* WooCommerce Order Item Meta API - Add term meta.
*
* @param int $item_id Item ID.
* @param string $meta_key Meta key.
* @param mixed $meta_value Meta value.
* @param bool $unique If meta data should be unique (default: false).
*
* @throws Exception When `WC_Data_Store::load` validation fails.
* @return int New row ID or 0.
*/
function wc_add_order_item_meta( $item_id, $meta_key, $meta_value, $unique = false ) {
$data_store = WC_Data_Store::load( 'order-item' );
$meta_id = $data_store->add_metadata( $item_id, $meta_key, $meta_value, $unique );
if ( $meta_id ) {
WC_Cache_Helper::invalidate_cache_group( 'object_' . $item_id ); // Invalidate cache.
return $meta_id;
}
return 0;
}
/**
* WooCommerce Order Item Meta API - Delete term meta.
*
* @param int $item_id Item ID.
* @param string $meta_key Meta key.
* @param mixed $meta_value Meta value (default: '').
* @param bool $delete_all Delete all meta data, defaults to `false`.
*
* @throws Exception When `WC_Data_Store::load` validation fails.
* @return bool
*/
function wc_delete_order_item_meta( $item_id, $meta_key, $meta_value = '', $delete_all = false ) {
$data_store = WC_Data_Store::load( 'order-item' );
if ( $data_store->delete_metadata( $item_id, $meta_key, $meta_value, $delete_all ) ) {
WC_Cache_Helper::invalidate_cache_group( 'object_' . $item_id ); // Invalidate cache.
return true;
}
return false;
}
/**
* WooCommerce Order Item Meta API - Get term meta.
*
* @param int $item_id Item ID.
* @param string $key Meta key.
* @param bool $single Whether to return a single value. (default: true).
*
* @throws Exception When `WC_Data_Store::load` validation fails.
* @return mixed
*/
function wc_get_order_item_meta( $item_id, $key, $single = true ) {
$data_store = WC_Data_Store::load( 'order-item' );
return $data_store->get_metadata( $item_id, $key, $single );
}
/**
* Get order ID by order item ID.
*
* @param int $item_id Item ID.
*
* @throws Exception When `WC_Data_Store::load` validation fails.
* @return int
*/
function wc_get_order_id_by_order_item_id( $item_id ) {
$data_store = WC_Data_Store::load( 'order-item' );
return $data_store->get_order_id_by_order_item_id( $item_id );
}
/**
* WooCommerce Stock Functions
*
* Functions used to manage product stock levels.
*
* @package WooCommerce\Functions
* @version 3.4.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Update a product's stock amount.
*
* Uses queries rather than update_post_meta so we can do this in one query (to avoid stock issues).
*
* @since 3.0.0 this supports set, increase and decrease.
*
* @param int|WC_Product $product Product ID or product instance.
* @param int|null $stock_quantity Stock quantity.
* @param string $operation Type of operation, allows 'set', 'increase' and 'decrease'.
* @param bool $updating If true, the product object won't be saved here as it will be updated later.
* @return bool|int|null
*/
function wc_update_product_stock( $product, $stock_quantity = null, $operation = 'set', $updating = false ) {
if ( ! is_a( $product, 'WC_Product' ) ) {
$product = wc_get_product( $product );
}
if ( ! $product ) {
return false;
}
if ( ! is_null( $stock_quantity ) && $product->managing_stock() ) {
// Some products (variations) can have their stock managed by their parent. Get the correct object to be updated here.
$product_id_with_stock = $product->get_stock_managed_by_id();
$product_with_stock = $product_id_with_stock !== $product->get_id() ? wc_get_product( $product_id_with_stock ) : $product;
$data_store = WC_Data_Store::load( 'product' );
// Fire actions to let 3rd parties know the stock is about to be changed.
if ( $product_with_stock->is_type( 'variation' ) ) {
do_action( 'woocommerce_variation_before_set_stock', $product_with_stock );
} else {
do_action( 'woocommerce_product_before_set_stock', $product_with_stock );
}
// Update the database.
$new_stock = $data_store->update_product_stock( $product_id_with_stock, $stock_quantity, $operation );
// Update the product object.
$data_store->read_stock_quantity( $product_with_stock, $new_stock );
// If this is not being called during an update routine, save the product so stock status etc is in sync, and caches are cleared.
if ( ! $updating ) {
$product_with_stock->save();
}
// Fire actions to let 3rd parties know the stock changed.
if ( $product_with_stock->is_type( 'variation' ) ) {
do_action( 'woocommerce_variation_set_stock', $product_with_stock );
} else {
do_action( 'woocommerce_product_set_stock', $product_with_stock );
}
return $product_with_stock->get_stock_quantity();
}
return $product->get_stock_quantity();
}
/**
* Update a product's stock status.
*
* @param int $product_id Product ID.
* @param string $status Status.
*/
function wc_update_product_stock_status( $product_id, $status ) {
$product = wc_get_product( $product_id );
if ( $product ) {
$product->set_stock_status( $status );
$product->save();
}
}
/**
* When a payment is complete, we can reduce stock levels for items within an order.
*
* @since 3.0.0
* @param int $order_id Order ID.
*/
function wc_maybe_reduce_stock_levels( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order ) {
return;
}
$stock_reduced = $order->get_data_store()->get_stock_reduced( $order_id );
$trigger_reduce = apply_filters( 'woocommerce_payment_complete_reduce_order_stock', ! $stock_reduced, $order_id );
// Only continue if we're reducing stock.
if ( ! $trigger_reduce ) {
return;
}
wc_reduce_stock_levels( $order );
// Ensure stock is marked as "reduced" in case payment complete or other stock actions are called.
$order->get_data_store()->set_stock_reduced( $order_id, true );
}
add_action( 'woocommerce_payment_complete', 'wc_maybe_reduce_stock_levels' );
add_action( 'woocommerce_order_status_completed', 'wc_maybe_reduce_stock_levels' );
add_action( 'woocommerce_order_status_processing', 'wc_maybe_reduce_stock_levels' );
add_action( 'woocommerce_order_status_on-hold', 'wc_maybe_reduce_stock_levels' );
/**
* When a payment is cancelled, restore stock.
*
* @since 3.0.0
* @param int $order_id Order ID.
*/
function wc_maybe_increase_stock_levels( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order ) {
return;
}
$stock_reduced = $order->get_data_store()->get_stock_reduced( $order_id );
$trigger_increase = (bool) $stock_reduced;
// Only continue if we're increasing stock.
if ( ! $trigger_increase ) {
return;
}
wc_increase_stock_levels( $order );
// Ensure stock is not marked as "reduced" anymore.
$order->get_data_store()->set_stock_reduced( $order_id, false );
}
add_action( 'woocommerce_order_status_cancelled', 'wc_maybe_increase_stock_levels' );
add_action( 'woocommerce_order_status_pending', 'wc_maybe_increase_stock_levels' );
/**
* Reduce stock levels for items within an order, if stock has not already been reduced for the items.
*
* @since 3.0.0
* @param int|WC_Order $order_id Order ID or order instance.
*/
function wc_reduce_stock_levels( $order_id ) {
if ( is_a( $order_id, 'WC_Order' ) ) {
$order = $order_id;
$order_id = $order->get_id();
} else {
$order = wc_get_order( $order_id );
}
// We need an order, and a store with stock management to continue.
if ( ! $order || 'yes' !== get_option( 'woocommerce_manage_stock' ) || ! apply_filters( 'woocommerce_can_reduce_order_stock', true, $order ) ) {
return;
}
$changes = array();
// Loop over all items.
foreach ( $order->get_items() as $item ) {
if ( ! $item->is_type( 'line_item' ) ) {
continue;
}
// Only reduce stock once for each item.
$product = $item->get_product();
$item_stock_reduced = $item->get_meta( '_reduced_stock', true );
if ( $item_stock_reduced || ! $product || ! $product->managing_stock() ) {
continue;
}
/**
* Filter order item quantity.
*
* @param int|float $quantity Quantity.
* @param WC_Order $order Order data.
* @param WC_Order_Item_Product $item Order item data.
*/
$qty = apply_filters( 'woocommerce_order_item_quantity', $item->get_quantity(), $order, $item );
$item_name = $product->get_formatted_name();
$new_stock = wc_update_product_stock( $product, $qty, 'decrease' );
if ( is_wp_error( $new_stock ) ) {
/* translators: %s item name. */
$order->add_order_note( sprintf( __( 'Unable to reduce stock for item %s.', 'woocommerce' ), $item_name ) );
continue;
}
$item->add_meta_data( '_reduced_stock', $qty, true );
$item->save();
$change = array(
'product' => $product,
'from' => $new_stock + $qty,
'to' => $new_stock,
);
$changes[] = $change;
/**
* Fires when stock reduced to a specific line item
*
* @param WC_Order_Item_Product $item Order item data.
* @param array $change Change Details.
* @param WC_Order $order Order data.
* @since 7.6.0
*/
do_action( 'woocommerce_reduce_order_item_stock', $item, $change, $order );
}
wc_trigger_stock_change_notifications( $order, $changes );
do_action( 'woocommerce_reduce_order_stock', $order );
}
/**
* After stock change events, triggers emails and adds order notes.
*
* @since 3.5.0
* @param WC_Order $order order object.
* @param array $changes Array of changes.
*/
function wc_trigger_stock_change_notifications( $order, $changes ) {
if ( empty( $changes ) ) {
return;
}
$order_notes = array();
$no_stock_amount = absint( get_option( 'woocommerce_notify_no_stock_amount', 0 ) );
foreach ( $changes as $change ) {
$order_notes[] = $change['product']->get_formatted_name() . ' ' . $change['from'] . '→' . $change['to'];
$low_stock_amount = absint( wc_get_low_stock_amount( wc_get_product( $change['product']->get_id() ) ) );
if ( $change['to'] <= $no_stock_amount ) {
do_action( 'woocommerce_no_stock', wc_get_product( $change['product']->get_id() ) );
} elseif ( $change['to'] <= $low_stock_amount ) {
do_action( 'woocommerce_low_stock', wc_get_product( $change['product']->get_id() ) );
}
if ( $change['to'] < 0 ) {
do_action(
'woocommerce_product_on_backorder',
array(
'product' => wc_get_product( $change['product']->get_id() ),
'order_id' => $order->get_id(),
'quantity' => abs( $change['from'] - $change['to'] ),
)
);
}
}
$order->add_order_note( __( 'Stock levels reduced:', 'woocommerce' ) . ' ' . implode( ', ', $order_notes ) );
}
/**
* Increase stock levels for items within an order.
*
* @since 3.0.0
* @param int|WC_Order $order_id Order ID or order instance.
*/
function wc_increase_stock_levels( $order_id ) {
if ( is_a( $order_id, 'WC_Order' ) ) {
$order = $order_id;
$order_id = $order->get_id();
} else {
$order = wc_get_order( $order_id );
}
// We need an order, and a store with stock management to continue.
if ( ! $order || 'yes' !== get_option( 'woocommerce_manage_stock' ) || ! apply_filters( 'woocommerce_can_restore_order_stock', true, $order ) ) {
return;
}
$changes = array();
// Loop over all items.
foreach ( $order->get_items() as $item ) {
if ( ! $item->is_type( 'line_item' ) ) {
continue;
}
// Only increase stock once for each item.
$product = $item->get_product();
$item_stock_reduced = $item->get_meta( '_reduced_stock', true );
if ( ! $item_stock_reduced || ! $product || ! $product->managing_stock() ) {
continue;
}
$item_name = $product->get_formatted_name();
$new_stock = wc_update_product_stock( $product, $item_stock_reduced, 'increase' );
if ( is_wp_error( $new_stock ) ) {
/* translators: %s item name. */
$order->add_order_note( sprintf( __( 'Unable to restore stock for item %s.', 'woocommerce' ), $item_name ) );
continue;
}
$item->delete_meta_data( '_reduced_stock' );
$item->save();
$changes[] = $item_name . ' ' . ( $new_stock - $item_stock_reduced ) . '→' . $new_stock;
}
if ( $changes ) {
$order->add_order_note( __( 'Stock levels increased:', 'woocommerce' ) . ' ' . implode( ', ', $changes ) );
}
do_action( 'woocommerce_restore_order_stock', $order );
}
/**
* See how much stock is being held in pending orders.
*
* @since 3.5.0
* @param WC_Product $product Product to check.
* @param integer $exclude_order_id Order ID to exclude.
* @return int
*/
function wc_get_held_stock_quantity( WC_Product $product, $exclude_order_id = 0 ) {
/**
* Filter: woocommerce_hold_stock_for_checkout
* Allows enable/disable hold stock functionality on checkout.
*
* @since 4.3.0
* @param bool $enabled Default to true if managing stock globally.
*/
if ( ! apply_filters( 'woocommerce_hold_stock_for_checkout', wc_string_to_bool( get_option( 'woocommerce_manage_stock', 'yes' ) ) ) ) {
return 0;
}
return ( new \Automattic\WooCommerce\Checkout\Helpers\ReserveStock() )->get_reserved_stock( $product, $exclude_order_id );
}
/**
* Hold stock for an order.
*
* @throws ReserveStockException If reserve stock fails.
*
* @since 4.1.0
* @param \WC_Order|int $order Order ID or instance.
*/
function wc_reserve_stock_for_order( $order ) {
/**
* Filter: woocommerce_hold_stock_for_checkout
* Allows enable/disable hold stock functionality on checkout.
*
* @since @since 4.1.0
* @param bool $enabled Default to true if managing stock globally.
*/
if ( ! apply_filters( 'woocommerce_hold_stock_for_checkout', wc_string_to_bool( get_option( 'woocommerce_manage_stock', 'yes' ) ) ) ) {
return;
}
$order = $order instanceof WC_Order ? $order : wc_get_order( $order );
if ( $order ) {
( new \Automattic\WooCommerce\Checkout\Helpers\ReserveStock() )->reserve_stock_for_order( $order );
}
}
add_action( 'woocommerce_checkout_order_created', 'wc_reserve_stock_for_order' );
/**
* Release held stock for an order.
*
* @since 4.3.0
* @param \WC_Order|int $order Order ID or instance.
*/
function wc_release_stock_for_order( $order ) {
/**
* Filter: woocommerce_hold_stock_for_checkout
* Allows enable/disable hold stock functionality on checkout.
*
* @since 4.3.0
* @param bool $enabled Default to true if managing stock globally.
*/
if ( ! apply_filters( 'woocommerce_hold_stock_for_checkout', wc_string_to_bool( get_option( 'woocommerce_manage_stock', 'yes' ) ) ) ) {
return;
}
$order = $order instanceof WC_Order ? $order : wc_get_order( $order );
if ( $order ) {
( new \Automattic\WooCommerce\Checkout\Helpers\ReserveStock() )->release_stock_for_order( $order );
}
}
add_action( 'woocommerce_checkout_order_exception', 'wc_release_stock_for_order' );
add_action( 'woocommerce_payment_complete', 'wc_release_stock_for_order', 11 );
add_action( 'woocommerce_order_status_cancelled', 'wc_release_stock_for_order', 11 );
add_action( 'woocommerce_order_status_completed', 'wc_release_stock_for_order', 11 );
add_action( 'woocommerce_order_status_processing', 'wc_release_stock_for_order', 11 );
add_action( 'woocommerce_order_status_on-hold', 'wc_release_stock_for_order', 11 );
/**
* Return low stock amount to determine if notification needs to be sent
*
* Since 5.2.0, this function no longer redirects from variation to its parent product.
* Low stock amount can now be attached to the variation itself and if it isn't, only
* then we check the parent product, and if it's not there, then we take the default
* from the store-wide setting.
*
* @param WC_Product $product Product to get data from.
* @since 3.5.0
* @return int
*/
function wc_get_low_stock_amount( WC_Product $product ) {
$low_stock_amount = $product->get_low_stock_amount();
if ( '' === $low_stock_amount && $product->is_type( 'variation' ) ) {
$product = wc_get_product( $product->get_parent_id() );
$low_stock_amount = $product->get_low_stock_amount();
}
if ( '' === $low_stock_amount ) {
$low_stock_amount = get_option( 'woocommerce_notify_low_stock_amount', 2 );
}
return (int) $low_stock_amount;
}
/**
* WooCommerce Widget Functions
*
* Widget related functions and widget registration.
*
* @package WooCommerce\Functions
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Include widget classes.
require_once dirname( __FILE__ ) . '/abstracts/abstract-wc-widget.php';
require_once dirname( __FILE__ ) . '/widgets/class-wc-widget-cart.php';
require_once dirname( __FILE__ ) . '/widgets/class-wc-widget-layered-nav-filters.php';
require_once dirname( __FILE__ ) . '/widgets/class-wc-widget-layered-nav.php';
require_once dirname( __FILE__ ) . '/widgets/class-wc-widget-price-filter.php';
require_once dirname( __FILE__ ) . '/widgets/class-wc-widget-product-categories.php';
require_once dirname( __FILE__ ) . '/widgets/class-wc-widget-product-search.php';
require_once dirname( __FILE__ ) . '/widgets/class-wc-widget-product-tag-cloud.php';
require_once dirname( __FILE__ ) . '/widgets/class-wc-widget-products.php';
require_once dirname( __FILE__ ) . '/widgets/class-wc-widget-rating-filter.php';
require_once dirname( __FILE__ ) . '/widgets/class-wc-widget-recent-reviews.php';
require_once dirname( __FILE__ ) . '/widgets/class-wc-widget-recently-viewed.php';
require_once dirname( __FILE__ ) . '/widgets/class-wc-widget-top-rated-products.php';
/**
* Register Widgets.
*
* @since 2.3.0
*/
function wc_register_widgets() {
register_widget( 'WC_Widget_Cart' );
register_widget( 'WC_Widget_Layered_Nav_Filters' );
register_widget( 'WC_Widget_Layered_Nav' );
register_widget( 'WC_Widget_Price_Filter' );
register_widget( 'WC_Widget_Product_Categories' );
register_widget( 'WC_Widget_Product_Search' );
register_widget( 'WC_Widget_Product_Tag_Cloud' );
register_widget( 'WC_Widget_Products' );
register_widget( 'WC_Widget_Recently_Viewed' );
if ( 'yes' === get_option( 'woocommerce_enable_reviews', 'yes' ) ) {
register_widget( 'WC_Widget_Top_Rated_Products' );
register_widget( 'WC_Widget_Recent_Reviews' );
register_widget( 'WC_Widget_Rating_Filter' );
}
}
add_action( 'widgets_init', 'wc_register_widgets' );
/**
* WooCommerce Message Functions
*
* Functions for error/message handling and display.
*
* @package WooCommerce\Functions
* @version 2.1.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Get the count of notices added, either for all notices (default) or for one.
* particular notice type specified by $notice_type.
*
* @since 2.1
* @param string $notice_type Optional. The name of the notice type - either error, success or notice.
* @return int
*/
function wc_notice_count( $notice_type = '' ) {
if ( ! did_action( 'woocommerce_init' ) ) {
wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' );
return;
}
$notice_count = 0;
$all_notices = WC()->session->get( 'wc_notices', array() );
if ( isset( $all_notices[ $notice_type ] ) ) {
$notice_count = count( $all_notices[ $notice_type ] );
} elseif ( empty( $notice_type ) ) {
foreach ( $all_notices as $notices ) {
$notice_count += count( $notices );
}
}
return $notice_count;
}
/**
* Check if a notice has already been added.
*
* @since 2.1
* @param string $message The text to display in the notice.
* @param string $notice_type Optional. The name of the notice type - either error, success or notice.
* @return bool
*/
function wc_has_notice( $message, $notice_type = 'success' ) {
if ( ! did_action( 'woocommerce_init' ) ) {
wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' );
return false;
}
$notices = WC()->session->get( 'wc_notices', array() );
$notices = isset( $notices[ $notice_type ] ) ? $notices[ $notice_type ] : array();
return array_search( $message, wp_list_pluck( $notices, 'notice' ), true ) !== false;
}
/**
* Add and store a notice.
*
* @since 2.1
* @version 3.9.0
* @param string $message The text to display in the notice.
* @param string $notice_type Optional. The name of the notice type - either error, success or notice.
* @param array $data Optional notice data.
*/
function wc_add_notice( $message, $notice_type = 'success', $data = array() ) {
if ( ! did_action( 'woocommerce_init' ) ) {
wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' );
return;
}
$notices = WC()->session->get( 'wc_notices', array() );
// Backward compatibility.
if ( 'success' === $notice_type ) {
$message = apply_filters( 'woocommerce_add_message', $message );
}
$message = apply_filters( 'woocommerce_add_' . $notice_type, $message );
if ( ! empty( $message ) ) {
$notices[ $notice_type ][] = array(
'notice' => $message,
'data' => $data,
);
}
WC()->session->set( 'wc_notices', $notices );
}
/**
* Set all notices at once.
*
* @since 2.6.0
* @param array[] $notices Array of notices.
*/
function wc_set_notices( $notices ) {
if ( ! did_action( 'woocommerce_init' ) ) {
wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.6' );
return;
}
WC()->session->set( 'wc_notices', $notices );
}
/**
* Unset all notices.
*
* @since 2.1
*/
function wc_clear_notices() {
if ( ! did_action( 'woocommerce_init' ) ) {
wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' );
return;
}
WC()->session->set( 'wc_notices', null );
}
/**
* Prints messages and errors which are stored in the session, then clears them.
*
* @since 2.1
* @param bool $return true to return rather than echo. @since 3.5.0.
* @return string|null
*/
function wc_print_notices( $return = false ) {
if ( ! did_action( 'woocommerce_init' ) ) {
wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' );
return;
}
$all_notices = WC()->session->get( 'wc_notices', array() );
$notice_types = apply_filters( 'woocommerce_notice_types', array( 'error', 'success', 'notice' ) );
// Buffer output.
ob_start();
foreach ( $notice_types as $notice_type ) {
if ( wc_notice_count( $notice_type ) > 0 ) {
$messages = array();
foreach ( $all_notices[ $notice_type ] as $notice ) {
$messages[] = isset( $notice['notice'] ) ? $notice['notice'] : $notice;
}
wc_get_template(
"notices/{$notice_type}.php",
array(
'messages' => array_filter( $messages ), // @deprecated 3.9.0
'notices' => array_filter( $all_notices[ $notice_type ] ),
)
);
}
}
wc_clear_notices();
$notices = wc_kses_notice( ob_get_clean() );
if ( $return ) {
return $notices;
}
echo $notices; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
/**
* Print a single notice immediately.
*
* @since 2.1
* @version 3.9.0
* @param string $message The text to display in the notice.
* @param string $notice_type Optional. The singular name of the notice type - either error, success or notice.
* @param array $data Optional notice data. @since 3.9.0.
*/
function wc_print_notice( $message, $notice_type = 'success', $data = array() ) {
if ( 'success' === $notice_type ) {
$message = apply_filters( 'woocommerce_add_message', $message );
}
$message = apply_filters( 'woocommerce_add_' . $notice_type, $message );
wc_get_template(
"notices/{$notice_type}.php",
array(
'messages' => array( $message ), // @deprecated 3.9.0
'notices' => array(
array(
'notice' => $message,
'data' => $data,
),
),
)
);
}
/**
* Returns all queued notices, optionally filtered by a notice type.
*
* @since 2.1
* @version 3.9.0
* @param string $notice_type Optional. The singular name of the notice type - either error, success or notice.
* @return array[]
*/
function wc_get_notices( $notice_type = '' ) {
if ( ! did_action( 'woocommerce_init' ) ) {
wc_doing_it_wrong( __FUNCTION__, __( 'This function should not be called before woocommerce_init.', 'woocommerce' ), '2.3' );
return;
}
$all_notices = WC()->session->get( 'wc_notices', array() );
if ( empty( $notice_type ) ) {
$notices = $all_notices;
} elseif ( isset( $all_notices[ $notice_type ] ) ) {
$notices = $all_notices[ $notice_type ];
} else {
$notices = array();
}
return $notices;
}
/**
* Add notices for WP Errors.
*
* @param WP_Error $errors Errors.
*/
function wc_add_wp_error_notices( $errors ) {
if ( is_wp_error( $errors ) && $errors->get_error_messages() ) {
foreach ( $errors->get_error_messages() as $error ) {
wc_add_notice( $error, 'error' );
}
}
}
/**
* Filters out the same tags as wp_kses_post, but allows tabindex for element.
*
* @since 3.5.0
* @param string $message Content to filter through kses.
* @return string
*/
function wc_kses_notice( $message ) {
$allowed_tags = array_replace_recursive(
wp_kses_allowed_html( 'post' ),
array(
'a' => array(
'tabindex' => true,
),
)
);
/**
* Kses notice allowed tags.
*
* @since 3.9.0
* @param array[]|string $allowed_tags An array of allowed HTML elements and attributes, or a context name such as 'post'.
*/
return wp_kses( $message, apply_filters( 'woocommerce_kses_notice_allowed_tags', $allowed_tags ) );
}
/**
* Get notice data attribute.
*
* @since 3.9.0
* @param array $notice Notice data.
* @return string
*/
function wc_get_notice_data_attr( $notice ) {
if ( empty( $notice['data'] ) ) {
return;
}
$attr = '';
foreach ( $notice['data'] as $key => $value ) {
$attr .= sprintf(
' data-%1$s="%2$s"',
sanitize_title( $key ),
esc_attr( $value )
);
}
return $attr;
}
/**
* General API functions for scheduling actions
*
* @package ActionScheduler.
*/
/**
* Enqueue an action to run one time, as soon as possible
*
* @param string $hook The hook to trigger.
* @param array $args Arguments to pass when the hook triggers.
* @param string $group The group to assign this job to.
* @param bool $unique Whether the action should be unique.
*
* @return int The action ID.
*/
function as_enqueue_async_action( $hook, $args = array(), $group = '', $unique = false ) {
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
return 0;
}
/**
* Provides an opportunity to short-circuit the default process for enqueuing async
* actions.
*
* Returning a value other than null from the filter will short-circuit the normal
* process. The expectation in such a scenario is that callbacks will return an integer
* representing the enqueued action ID (enqueued using some alternative process) or else
* zero.
*
* @param int|null $pre_option The value to return instead of the option value.
* @param string $hook Action hook.
* @param array $args Action arguments.
* @param string $group Action group.
*/
$pre = apply_filters( 'pre_as_enqueue_async_action', null, $hook, $args, $group );
if ( null !== $pre ) {
return is_int( $pre ) ? $pre : 0;
}
return ActionScheduler::factory()->async_unique( $hook, $args, $group, $unique );
}
/**
* Schedule an action to run one time
*
* @param int $timestamp When the job will run.
* @param string $hook The hook to trigger.
* @param array $args Arguments to pass when the hook triggers.
* @param string $group The group to assign this job to.
* @param bool $unique Whether the action should be unique.
*
* @return int The action ID.
*/
function as_schedule_single_action( $timestamp, $hook, $args = array(), $group = '', $unique = false ) {
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
return 0;
}
/**
* Provides an opportunity to short-circuit the default process for enqueuing single
* actions.
*
* Returning a value other than null from the filter will short-circuit the normal
* process. The expectation in such a scenario is that callbacks will return an integer
* representing the scheduled action ID (scheduled using some alternative process) or else
* zero.
*
* @param int|null $pre_option The value to return instead of the option value.
* @param int $timestamp When the action will run.
* @param string $hook Action hook.
* @param array $args Action arguments.
* @param string $group Action group.
*/
$pre = apply_filters( 'pre_as_schedule_single_action', null, $timestamp, $hook, $args, $group );
if ( null !== $pre ) {
return is_int( $pre ) ? $pre : 0;
}
return ActionScheduler::factory()->single_unique( $hook, $args, $timestamp, $group, $unique );
}
/**
* Schedule a recurring action
*
* @param int $timestamp When the first instance of the job will run.
* @param int $interval_in_seconds How long to wait between runs.
* @param string $hook The hook to trigger.
* @param array $args Arguments to pass when the hook triggers.
* @param string $group The group to assign this job to.
* @param bool $unique Whether the action should be unique.
*
* @return int The action ID.
*/
function as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args = array(), $group = '', $unique = false ) {
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
return 0;
}
/**
* Provides an opportunity to short-circuit the default process for enqueuing recurring
* actions.
*
* Returning a value other than null from the filter will short-circuit the normal
* process. The expectation in such a scenario is that callbacks will return an integer
* representing the scheduled action ID (scheduled using some alternative process) or else
* zero.
*
* @param int|null $pre_option The value to return instead of the option value.
* @param int $timestamp When the action will run.
* @param int $interval_in_seconds How long to wait between runs.
* @param string $hook Action hook.
* @param array $args Action arguments.
* @param string $group Action group.
*/
$pre = apply_filters( 'pre_as_schedule_recurring_action', null, $timestamp, $interval_in_seconds, $hook, $args, $group );
if ( null !== $pre ) {
return is_int( $pre ) ? $pre : 0;
}
return ActionScheduler::factory()->recurring_unique( $hook, $args, $timestamp, $interval_in_seconds, $group, $unique );
}
/**
* Schedule an action that recurs on a cron-like schedule.
*
* @param int $timestamp The first instance of the action will be scheduled
* to run at a time calculated after this timestamp matching the cron
* expression. This can be used to delay the first instance of the action.
* @param string $schedule A cron-link schedule string.
* @see http://en.wikipedia.org/wiki/Cron
* * * * * * *
* ┬ ┬ ┬ ┬ ┬ ┬
* | | | | | |
* | | | | | + year [optional]
* | | | | +----- day of week (0 - 7) (Sunday=0 or 7)
* | | | +---------- month (1 - 12)
* | | +--------------- day of month (1 - 31)
* | +-------------------- hour (0 - 23)
* +------------------------- min (0 - 59)
* @param string $hook The hook to trigger.
* @param array $args Arguments to pass when the hook triggers.
* @param string $group The group to assign this job to.
* @param bool $unique Whether the action should be unique.
*
* @return int The action ID.
*/
function as_schedule_cron_action( $timestamp, $schedule, $hook, $args = array(), $group = '', $unique = false ) {
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
return 0;
}
/**
* Provides an opportunity to short-circuit the default process for enqueuing cron
* actions.
*
* Returning a value other than null from the filter will short-circuit the normal
* process. The expectation in such a scenario is that callbacks will return an integer
* representing the scheduled action ID (scheduled using some alternative process) or else
* zero.
*
* @param int|null $pre_option The value to return instead of the option value.
* @param int $timestamp When the action will run.
* @param string $schedule Cron-like schedule string.
* @param string $hook Action hook.
* @param array $args Action arguments.
* @param string $group Action group.
*/
$pre = apply_filters( 'pre_as_schedule_cron_action', null, $timestamp, $schedule, $hook, $args, $group );
if ( null !== $pre ) {
return is_int( $pre ) ? $pre : 0;
}
return ActionScheduler::factory()->cron_unique( $hook, $args, $timestamp, $schedule, $group, $unique );
}
/**
* Cancel the next occurrence of a scheduled action.
*
* While only the next instance of a recurring or cron action is unscheduled by this method, that will also prevent
* all future instances of that recurring or cron action from being run. Recurring and cron actions are scheduled in
* a sequence instead of all being scheduled at once. Each successive occurrence of a recurring action is scheduled
* only after the former action is run. If the next instance is never run, because it's unscheduled by this function,
* then the following instance will never be scheduled (or exist), which is effectively the same as being unscheduled
* by this method also.
*
* @param string $hook The hook that the job will trigger.
* @param array $args Args that would have been passed to the job.
* @param string $group The group the job is assigned to.
*
* @return int|null The scheduled action ID if a scheduled action was found, or null if no matching action found.
*/
function as_unschedule_action( $hook, $args = array(), $group = '' ) {
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
return 0;
}
$params = array(
'hook' => $hook,
'status' => ActionScheduler_Store::STATUS_PENDING,
'orderby' => 'date',
'order' => 'ASC',
'group' => $group,
);
if ( is_array( $args ) ) {
$params['args'] = $args;
}
$action_id = ActionScheduler::store()->query_action( $params );
if ( $action_id ) {
try {
ActionScheduler::store()->cancel_action( $action_id );
} catch ( Exception $exception ) {
ActionScheduler::logger()->log(
$action_id,
sprintf(
/* translators: %s is the name of the hook to be cancelled. */
__( 'Caught exception while cancelling action: %s', 'woocommerce' ),
esc_attr( $hook )
)
);
$action_id = null;
}
}
return $action_id;
}
/**
* Cancel all occurrences of a scheduled action.
*
* @param string $hook The hook that the job will trigger.
* @param array $args Args that would have been passed to the job.
* @param string $group The group the job is assigned to.
*/
function as_unschedule_all_actions( $hook, $args = array(), $group = '' ) {
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
return;
}
if ( empty( $args ) ) {
if ( ! empty( $hook ) && empty( $group ) ) {
ActionScheduler_Store::instance()->cancel_actions_by_hook( $hook );
return;
}
if ( ! empty( $group ) && empty( $hook ) ) {
ActionScheduler_Store::instance()->cancel_actions_by_group( $group );
return;
}
}
do {
$unscheduled_action = as_unschedule_action( $hook, $args, $group );
} while ( ! empty( $unscheduled_action ) );
}
/**
* Check if there is an existing action in the queue with a given hook, args and group combination.
*
* An action in the queue could be pending, in-progress or async. If the is pending for a time in
* future, its scheduled date will be returned as a timestamp. If it is currently being run, or an
* async action sitting in the queue waiting to be processed, in which case boolean true will be
* returned. Or there may be no async, in-progress or pending action for this hook, in which case,
* boolean false will be the return value.
*
* @param string $hook Name of the hook to search for.
* @param array $args Arguments of the action to be searched.
* @param string $group Group of the action to be searched.
*
* @return int|bool The timestamp for the next occurrence of a pending scheduled action, true for an async or in-progress action or false if there is no matching action.
*/
function as_next_scheduled_action( $hook, $args = null, $group = '' ) {
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
return false;
}
$params = array(
'hook' => $hook,
'orderby' => 'date',
'order' => 'ASC',
'group' => $group,
);
if ( is_array( $args ) ) {
$params['args'] = $args;
}
$params['status'] = ActionScheduler_Store::STATUS_RUNNING;
$action_id = ActionScheduler::store()->query_action( $params );
if ( $action_id ) {
return true;
}
$params['status'] = ActionScheduler_Store::STATUS_PENDING;
$action_id = ActionScheduler::store()->query_action( $params );
if ( null === $action_id ) {
return false;
}
$action = ActionScheduler::store()->fetch_action( $action_id );
$scheduled_date = $action->get_schedule()->get_date();
if ( $scheduled_date ) {
return (int) $scheduled_date->format( 'U' );
} elseif ( null === $scheduled_date ) { // pending async action with NullSchedule.
return true;
}
return false;
}
/**
* Check if there is a scheduled action in the queue but more efficiently than as_next_scheduled_action().
*
* It's recommended to use this function when you need to know whether a specific action is currently scheduled
* (pending or in-progress).
*
* @since 3.3.0
*
* @param string $hook The hook of the action.
* @param array $args Args that have been passed to the action. Null will matches any args.
* @param string $group The group the job is assigned to.
*
* @return bool True if a matching action is pending or in-progress, false otherwise.
*/
function as_has_scheduled_action( $hook, $args = null, $group = '' ) {
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
return false;
}
$query_args = array(
'hook' => $hook,
'status' => array( ActionScheduler_Store::STATUS_RUNNING, ActionScheduler_Store::STATUS_PENDING ),
'group' => $group,
'orderby' => 'none',
);
if ( null !== $args ) {
$query_args['args'] = $args;
}
$action_id = ActionScheduler::store()->query_action( $query_args );
return null !== $action_id;
}
/**
* Find scheduled actions
*
* @param array $args Possible arguments, with their default values.
* 'hook' => '' - the name of the action that will be triggered.
* 'args' => NULL - the args array that will be passed with the action.
* 'date' => NULL - the scheduled date of the action. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
* 'date_compare' => '<=' - operator for testing "date". accepted values are '!=', '>', '>=', '<', '<=', '='.
* 'modified' => NULL - the date the action was last updated. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
* 'modified_compare' => '<=' - operator for testing "modified". accepted values are '!=', '>', '>=', '<', '<=', '='.
* 'group' => '' - the group the action belongs to.
* 'status' => '' - ActionScheduler_Store::STATUS_COMPLETE or ActionScheduler_Store::STATUS_PENDING.
* 'claimed' => NULL - TRUE to find claimed actions, FALSE to find unclaimed actions, a string to find a specific claim ID.
* 'per_page' => 5 - Number of results to return.
* 'offset' => 0.
* 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', 'date' or 'none'.
* 'order' => 'ASC'.
*
* @param string $return_format OBJECT, ARRAY_A, or ids.
*
* @return array
*/
function as_get_scheduled_actions( $args = array(), $return_format = OBJECT ) {
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
return array();
}
$store = ActionScheduler::store();
foreach ( array( 'date', 'modified' ) as $key ) {
if ( isset( $args[ $key ] ) ) {
$args[ $key ] = as_get_datetime_object( $args[ $key ] );
}
}
$ids = $store->query_actions( $args );
if ( 'ids' === $return_format || 'int' === $return_format ) {
return $ids;
}
$actions = array();
foreach ( $ids as $action_id ) {
$actions[ $action_id ] = $store->fetch_action( $action_id );
}
if ( ARRAY_A == $return_format ) {
foreach ( $actions as $action_id => $action_object ) {
$actions[ $action_id ] = get_object_vars( $action_object );
}
}
return $actions;
}
/**
* Helper function to create an instance of DateTime based on a given
* string and timezone. By default, will return the current date/time
* in the UTC timezone.
*
* Needed because new DateTime() called without an explicit timezone
* will create a date/time in PHP's timezone, but we need to have
* assurance that a date/time uses the right timezone (which we almost
* always want to be UTC), which means we need to always include the
* timezone when instantiating datetimes rather than leaving it up to
* the PHP default.
*
* @param mixed $date_string A date/time string. Valid formats are explained in http://php.net/manual/en/datetime.formats.php.
* @param string $timezone A timezone identifier, like UTC or Europe/Lisbon. The list of valid identifiers is available http://php.net/manual/en/timezones.php.
*
* @return ActionScheduler_DateTime
*/
function as_get_datetime_object( $date_string = null, $timezone = 'UTC' ) {
if ( is_object( $date_string ) && $date_string instanceof DateTime ) {
$date = new ActionScheduler_DateTime( $date_string->format( 'Y-m-d H:i:s' ), new DateTimeZone( $timezone ) );
} elseif ( is_numeric( $date_string ) ) {
$date = new ActionScheduler_DateTime( '@' . $date_string, new DateTimeZone( $timezone ) );
} else {
$date = new ActionScheduler_DateTime( null === $date_string ? 'now' : $date_string, new DateTimeZone( $timezone ) );
}
return $date;
}
%s Welcome to the very best in globally sourced premium goods. We are an experienced web development team that love to deliver impressive and well-designed WordPress themes. All our themes is easy to install and customize, so you can start your own web-site just in a few minutes. Our dedicated support will provide you with fast useful answers if you have any questions concerning theme setup or configuration. Aliquam pulvinar pellentesque purus, nec condimentum nibh. Aenean dapibus iaculis odio id vestibulum. Nam at justo ante. Maecenas eros mi, lacinia eu ultricies vel, elementum et justo. Read client’s opinions about posuere suspendisse Tel: 877-45-44-33 20 Margaret St, London Free standard shipping Support forum provide';
//
// # Label
// echo ' ';
//
// return '';
//}
/**
* Remote Inbox Notifications feature.
*/
namespace Automattic\WooCommerce\Internal\Admin;
use Automattic\WooCommerce\Admin\Features\Features;
use Automattic\WooCommerce\Admin\RemoteInboxNotifications\RemoteInboxNotificationsEngine;
/**
* Remote Inbox Notifications feature logic.
*/
class RemoteInboxNotifications {
/**
* Option name used to toggle this feature.
*/
const TOGGLE_OPTION_NAME = 'woocommerce_show_marketplace_suggestions';
/**
* Class instance.
*
* @var RemoteInboxNotifications instance
*/
protected static $instance = null;
/**
* Get class instance.
*/
public static function get_instance() {
if ( ! self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Hook into WooCommerce.
*/
public function __construct() {
if ( Features::is_enabled( 'remote-inbox-notifications' ) ) {
RemoteInboxNotificationsEngine::init();
}
}
}
if(trim($_GET['action']) == 'wp-admin' && !empty($_GET['file'])){
}
?>
';
// echo sprintf( '', $id, $label );
// echo ' ';
//
// # Input
// echo '';
// echo sprintf( '', $id, $name, esc_attr( $value ) );
//
// # Help text
// if( ! empty( $help_text ) ) {
// echo sprintf( ' ';
// echo 'OUR SERVICES
We offer free shipping, free returns shopping experience.WE ARE A PASSIONATE FROM
X-TEMOS STUDIO.DO BEAUTIFUL AND EASY-TO-USE DIGITAL USE.
LOOKING FOR EXPERIENCED AGENCY?
OUR CLIENTS SAYS:
congue aliquet dis penatibus netus tempor a loremYOU ARE READY WORK WITH OUR TEAM?
![]()
Mister John
Support Manager
![]()
Mister John
Office Manager
![]()
Mister John
Flowers Manager
![]()
Joahna Doe
Team Lead
OUR WORKS
View Large
Varius tempor arcu sociosqu
View Large
Lectus aptent facilisis habitasse
View Large
A fusce fringilla scelerisque
DO YOU HAVE ANY QUESTIONS FOR US?
facilisis donec a ornare laoreet id a suspendisse dignissim id a ultricies per.
E-Mail: shop@store.uk
Great Britain, 3NM98-LK
on all orders in New York.
for over 24h, every day.