Developer Hooks

Reserved Stock Pro for WooCommerce has plenty of developer hooks available for you to customize the features to your needs.

Keep in mind that these are examples only. You’ll need to customize the snippets to your own use case. You should add them to your child themes functions.php file or a custom plugin.

Get reserved quantities

You can use the rsp_get_stock_amounts function to get the stock amounts for any product ID.

// Make sure we have our function.
if ( function_exists( 'rsp_get_stock_amounts' ) ) {
	$stock_amounts = rsp_get_stock_amounts( 100 ); // Product ID.

	$stock_amounts['available']; // Integer: Available for reservations.
	$stock_amounts['reserved']; // Integer: Amount reserved.
	$stock_amounts['inventory']; // Integer: Inventory in stock.
	$stock_amounts['status']; // String: out_of_stock or fully_reserved or partially_reserved or none_reserved
}Code language: PHP (php)

How do I limit what products are stock controlled in the cart?

/**
 * Skip specific products from stock resveration. $product is the entire product object.
 */
function puri_reserved_stock_pro_should_handle_product_stock( $should_handle, $product ) {

	// Check if the product ID equals 100.
    if ( $product->get_id() === 100 ) {
		$should_handle = false; // Don't reserve stock for product 100.
	}

	// Check if product belongs to a category.
    if ( has_term( 'shirts', 'product_cat', $product->get_id() ) {
		$should_handle = false; // Don't reserve for the product category 'shirts'.
	}

	return $should_handle;
}
add_filter( 'reserved_stock_pro_should_handle_product_stock', 'puri_reserved_stock_pro_should_handle_product_stock', 10, 2 );Code language: PHP (php)

You can use the reserved_stock_pro_should_handle_product_stock filter to specifically exclude products from Cart & Stock Control. The example below checks if the product has an ID of 100 and then skips it.

Enable reservations for a specific category only.

We are often asked how to enabled Reserved Stock Pro to handle reservations for specific product categories.
Here’s an example snippet, you can modify it with your own categories.

/**
 * Skip specific products from stock reservation. $product is the entire product object.
 */
function puri_reserved_stock_pro_should_handle_product_stock( $should_handle, $product ) {

    // Check if product belongs to a category.
    if ( has_term( 'shirts', 'product_cat', $product->get_id() ) ) {
        $should_handle = true; // Only Reserve products in the category of shirts.
    } else {
        $should_handle = false; // Disable reservations for all other products.
    }

    return $should_handle;
}
add_filter( 'reserved_stock_pro_should_handle_product_stock', 'puri_reserved_stock_pro_should_handle_product_stock', 10, 2 );Code language: PHP (php)

How do I customize the messages per product?

You can change the messages that appear in WooCommerce per product using the product id. You’ll need to hook into the cart_control_filter_reserved_until_message filter. Here’s an example.

/**
 * Change the text on reserved products the cart.
 */
function puri_reserved_stock_pro_filter_reserved_until_message( $message, $product_id ) {

	if ( $product_id === 100 ) {
		$message = 'Custom reserved until {expiration_date}'; // Only for the product with an ID of 100.
	}

	return $message;
}
add_filter( 'reserved_stock_pro_filter_reserved_until_message', 'puri_reserved_stock_pro_filter_reserved_until_message', 10, 2 );Code language: PHP (php)

These filters will allow you to change the other messages dynamically in the same manner as above.

  • reserved_stock_pro_filter_added_to_cart_notice
  • reserved_stock_pro_filter_removed_from_cart_notice
  • reserved_stock_pro_filter_not_enough_stock_notice
  • reserved_stock_pro_filter_single_all_stock_reserved_message
  • reserved_stock_pro_filter_single_single_all_stock_available_message
  • reserved_stock_pro_filter_single_has_reserved_stock_message
  • reserved_stock_pro_filter_out_of_stock_text

Translating with WPML

For those who require specific text for each language in WPML, you can use the following snippet to change the text for the current WPML language code.
Replace the shortcode language code with the ones from your WPML install.

Use WPML to translate the countdown text.

/**
 * Configure the options of the Reserved Stock Pro countdown.
 *
 * @param array $options
 * @return array $options
 */
function custom_rsp_countdown_options( $options ) {

	$current_lang = apply_filters( 'wpml_current_language', null );

	if ( $current_lang === 'en' ) {
		$options['countingHtml'] = 'Cart items are reserved for {minutes} minutes and {seconds} seconds.';
		$options['expiredHtml'] = 'Your cart item reservations have expired';
	}

	if ( $current_lang === 'pl' ) {
		$options['countingHtml'] = 'Cart items are reserved for {minutes} minutes and {seconds} seconds.';
		$options['expiredHtml'] = 'Your cart item reservations have expired';
	}

	return $options;

}
add_filter( 'rsp_countdown_options', 'custom_rsp_countdown_options', 10, 1 );Code language: PHP (php)
/**
 * Change the text on reserved products the cart.
 */
function puri_reserved_stock_pro_filter_reserved_until_message( $message, $product_id, $cart_item_key ) {

	$current_lang = apply_filters( 'wpml_current_language', null );

	if ( $current_lang === 'en' ) {
		$message = 'Custom reserved until {expiration_date}';
	}

	if ( $current_lang === 'pl' ) {
		$message = 'Custom reserved until {expiration_date}';
	}

	return $message;
}
add_filter( 'reserved_stock_pro_filter_reserved_until_message', 'puri_reserved_stock_pro_filter_reserved_until_message', 10, 3 );Code language: PHP (php)
/**
 * Configure the fully reserved text.
 */
function custom_rsp_out_of_stock_text( $message, $product_id) {

	$current_lang = apply_filters( 'wpml_current_language', null );

	if ( $current_lang === 'en' ) {
	  $message = 'Stock reserved';
	}

	if ( $current_lang === 'pl' ) {
	  $message = 'Stock reserved';
	}

	return $message;
}
add_filter( 'reserved_stock_pro_filter_out_of_stock_text', 'custom_rsp_out_of_stock_text', 10, 2 );Code language: PHP (php)
/**
 * Configure the partially_reserved text.
 */
function custom_rsp_partially_reserved_text( $message, $product_id) {

	$current_lang = apply_filters( 'wpml_current_language', null );

	if ( $current_lang === 'en' ) {
	  $message = '{reserved_quantity} already reserved. {product_name} can only be held for {minutes} minutes. Get yours now!';
	}

	if ( $current_lang === 'pl' ) {
	  $message = '{reserved_quantity} already reserved. {product_name} can only be held for {minutes} minutes. Get yours now!';
	}

	return $message;
}
add_filter( 'reserved_stock_pro_filter_single_has_reserved_stock_message', 'custom_rsp_partially_reserved_text', 10, 2 );Code language: PHP (php)
/**
 * Configure the none_reserved text - all available.
 */
function custom_rsp_none_reserved_text( $message, $product_id) {

	$current_lang = apply_filters( 'wpml_current_language', null );

	if ( $current_lang === 'en' ) {
	  $message = 'Reserve {product_name} now for {minutes} minutes before anyone else does!';
	}

	if ( $current_lang === 'pl' ) {
	  $message = 'Reserve {product_name} now for {minutes} minutes before anyone else does!';
	}

	return $message;
}
add_filter( 'reserved_stock_pro_filter_single_single_all_stock_available_message', 'custom_rsp_none_reserved_text', 10, 2 );Code language: PHP (php)
/**
 * Configure the fully_reserved text - all reserved.
 */
function custom_rsp_fully_reserved_text( $message, $product_id) {

	$current_lang = apply_filters( 'wpml_current_language', null );

	if ( $current_lang === 'en' ) {
	  $message = 'All {reserved_quantity} stock is currently reserved. {product_name} can only be reserved for a maximum of {minutes} minutes. Check back soon.';
	}

	if ( $current_lang === 'pl' ) {
	  $message = 'All {reserved_quantity} stock is currently reserved. {product_name} can only be reserved for a maximum of {minutes} minutes. Check back soon.';
	}

	return $message;
}
add_filter( 'reserved_stock_pro_filter_single_all_stock_reserved_message', 'custom_rsp_fully_reserved_text', 10, 2 );Code language: PHP (php)
/**
 * Configure the added_to_cart_notice
 */
function custom_rsp_added_to_cart_notice( $message, $product_id) {

	$current_lang = apply_filters( 'wpml_current_language', null );

	if ( $current_lang === 'en' ) {
	  $message = 'You can hold {product_name} for maximum of {minutes} minutes.';
	}

	if ( $current_lang === 'pl' ) {
	  $message = 'You can hold {product_name} for maximum of {minutes} minutes.';
	}

	return $message;
}
add_filter( 'reserved_stock_pro_filter_added_to_cart_notice', 'custom_rsp_added_to_cart_notice', 10, 2 );Code language: PHP (php)
/**
 * Configure the removed_from_cart_notice
 */
function custom_rsp_removed_from_cart_notice( $message, $product_id) {

	$current_lang = apply_filters( 'wpml_current_language', null );

	if ( $current_lang === 'en' ) {
	  $message = '{product_name} has been removed from your cart. Products can only be held for a maximum of {minutes} minutes.';
	}

	if ( $current_lang === 'pl' ) {
	  $message = '{product_name} has been removed from your cart. Products can only be held for a maximum of {minutes} minutes.';
	}

	return $message;
}
add_filter( 'reserved_stock_pro_filter_removed_from_cart_notice', 'custom_rsp_removed_from_cart_notice', 10, 2 );Code language: PHP (php)
/**
 * Configure the not_enough_stock_notice
 */
function custom_rsp_not_enough_stock_notice( $message, $product_id) {

	$current_lang = apply_filters( 'wpml_current_language', null );

	if ( $current_lang === 'en' ) {
	  $message = 'Cannot add {added_quantity} × {product_name}. There is {available_quantity} available right now.';
	}

	if ( $current_lang === 'pl' ) {
	  $message = 'Cannot add {added_quantity} × {product_name}. There is {available_quantity} available right now.';
	}

	return $message;
}
add_filter( 'reserved_stock_pro_filter_not_enough_stock_notice', 'custom_rsp_not_enough_stock_notice', 10, 2 );Code language: PHP (php)

How do I add support for a custom product type?

You can use the reserved_stock_pro_supported_product_types filter. We use this filter to make sure Reserved Stock Pro doesn’t try to control the stock of product types that aren’t fully tested or supported yet.

Make sure that you completely test that everything is working well with your custom product type before you enable reservations for product types on a production site.

/**
 * Add or remove specific product types from stock reservations.
 */
function puri_reserved_stock_pro_supported_product_types( $supported_array ) {

	array_push( $supported_array, 'custom_product_type' ); // Replace with the name of your product type.

	return $supported_array;
}
add_filter( 'reserved_stock_pro_supported_product_types', 'puri_reserved_stock_pro_supported_product_types', 10 );Code language: PHP (php)

[Experimental] Enable WooCommerce subscription products types: subscription & variable-subscription

/**
 * Add or remove specific product types from stock reservations.
 */
function puri_custom_rsp_supported_product_types( $supported_array ) {

	array_push( $supported_array, 'subscription' ); // Simple Subscription Products.
	array_push( $supported_array, 'variable-subscription' ); // Variable Subscription products.

	return $supported_array;
}
add_filter( 'reserved_stock_pro_supported_product_types', 'puri_custom_rsp_supported_product_types', 10 );
Code language: PHP (php)

Change the date format

You can change the date format of the expiration date on the product in the cart via this PHP snippet. The date format uses the standard PHP date format. You can reference the format options https://www.php.net/manual/en/datetime.format.php and https://www.php.net/manual/en/function.date.php

/**
 * Change the date format the expiration date appears.
 * Find examples of PHP date formats here: https://www.php.net/manual/en/function.date.php
 */
function custom_reserved_stock_pro_date_format( $format ) {

	$format = 'g:i a, F j, Y'; // New PHP Date format without the timezone.

	return $format;
}
add_filter( 'reserved_stock_pro_filter_date_format', 'custom_reserved_stock_pro_date_format', 10 );Code language: PHP (php)

Remove Defaults

Remove any defaults so you can provide your own if needed.

/**
 * Remove defaults in Reserved Stock Pro.
 * So you can safely add your own styles without overriding.
 */

// Remove the default CSS.
add_filter( 'rsp_default_countdown_css', '__return_false' );
// Remove the default countdown location.
add_filter( 'rsp_default_countdown_location', '__return_false' );Code language: PHP (php)

Custom Countdown Location

Reserved Stock Pro will display the countdown as a sticky popup timer on every page. We believe this is the best default to have for most sites. Don’t worry you can still do custom countdowns easily. Just make sure to remove the default countdown location and CSS if needed before creating a custom location.

Here is an example for making the RSP countdown into a top bar/banner across the site.

/**
 * Makes the Reserved Stock Pro countdown display as a top bar.
 * Add your own CSS inline or copy it into your themes custom CSS.
 *
 * Note: This method requires your theme to support 'wp_body_open'.
 */
function puri_rsp_countdown_bar() {

	// New custom CSS. Can be place here or in your theme.
	// Make sure you've removed the default styles first.
	$css = '
	.rsp-countdown-wrapper {
		background: black;
    	color: white;
		text-align: center;
		padding: 15px 0;
		width: 100%;
	}

	.rsp-countdown-wrapper.rsp-no-reservations {
		display: none;
	}

	.rsp-countdown-wrapper.rsp-is-counting {

	}
	.rsp-countdown-wrapper.rsp-is-expired {
		color:red;
	}
	';

	echo '<style>' . $css . '</style>';
	// End of custom css.

	// Output the Resvered Stock Pro Countdown.
	echo do_shortcode( '[rsp_countdown]' );
}
add_action( 'wp_body_open', 'puri_rsp_countdown_bar' );Code language: PHP (php)

Change add to cart buttons based on stock

The add to cart button text on the shop page, may still displayed “add to cart” in your theme. if you click the button on a product that is out of stock, then WooCommerce will attempt to add the product to cart and display the notice stating thare is no stock left.

You can the button text based on stock availability using this snippet as an example. Note that changing the button with the woocommerce_loop_add_to_cart_link filter will also change the button html. Therefore the button will no longer add to cart when clicked. Customers will simply be redirected to the product page instead.

Example of add to cart buttons changed based on stock levels.

/**
 * Change Add to cart buttons when all stock is reserved.
 * Buttons will link to the product instead of trying to add to cart.
 * If the product is already in cart, the button text will be "Already in cart".
 *
 * @param [type] $add_to_cart_html
 * @param [type] $product
 * @return void
 */
function puri_custom_add_to_cart_button( $default_button_html, $product ) {

	// Make sure we have our function.
	if ( function_exists( 'rsp_get_stock_amounts' ) ) {

		$new_button_text = false;

		$stock_total = rsp_get_stock_amounts( $product->get_id() );

		if ( $stock_total && ! empty( $stock_total['status'] ) ) {
			// if stock is zero or less then sold out.
			if ( $stock_total['status'] === 'out_of_stock' ) {
				$new_button_text = 'Sold Out'; // Change here.
			}

			if ( $stock_total['status'] === 'fully_reserved' ) {
				// Check if product is already in cart.
				$cart_contents = WC()->cart->get_cart_contents();
				
				foreach ( $cart_contents as $cart_item ) {
					if ( $cart_item['product_id'] === $product->get_id() ) {
						$new_button_text = 'Already in cart'; // Change here.
						break;
					}
				}
				if ( ! $new_button_text ) {
					$new_button_text = 'Last Stock Reserved'; // Change here.
				}
			}
		}

		if ( $new_button_text ) {
			// Product link without adding to cart.
			$button_html = '<a class="button" href="' . $product->get_permalink() . '">' . $new_button_text . '</a>';

			return $button_html;
		}
	}

	return $default_button_html;
}

add_filter( 'woocommerce_loop_add_to_cart_link', 'puri_custom_add_to_cart_button', 100, 2 );Code language: PHP (php)

Display Product Stock Status via shortcode

We’ve made a shortcode that will allow you to display a dynamic message based on the product’s reserved stock levels. You can place this anywhere, even on custom landing pages.

Make sure to set the following in the shortcode

  • product_id (optional if used in a query loop)
  • out_of_stock_text
  • fully_reserved_text
  • available_text
[rsp_product_stock_status product_id="2362" out_of_stock_text="Currently out of stock" fully_reserved_text="All stock reserved - Check back in a few minutes" available_text="{available_quantity} is available"]Code language: JSON / JSON with Comments (json)

Disable automatic page cache integrations

Reserved Stock Pro has automatic integrations with several caching plugins. The integration is on by default. This setting relates to page cache only!

What does it do?

The integration makes sure that the page cache of the product is purged every time the reservation quantity of a product changes. This is to make sure that customers see the correct stock quantities and not the old cache.

Why disable it?

  1. If you are not displaying the stock numbers or any related reservation quantity information on the frontend, then you can disable the integration.
  2. If you are running a large store where your customers are continuously adding the same products to their cart. Highly frequent reservation changes will result in the page cache being purged quickly without having time to rebuild. In this situation, you may want to disable this feature and remove related reservation quantity from the product page.

Note: The built-in countdown for stock reservations uses the WooCommerce cart fragments and object caching. It’s not affected by the page cache or this setting.

add_filter( 'rsp_enable_page_cache_plugin_integrations', '__return_false' ); Code language: JavaScript (javascript)

Disable Object caching

Object caching is used to speed performance by reducing calls to the database.

Object Caching are used for the following:

  • The quantity of a product that is currently reserved.
  • The current customer reservation expiration timestamp.
  • Product IDs curently reserved by the customer.
add_filter( 'reserved_stock_pro_disable_object_cache', '__return_true' ); Code language: JavaScript (javascript)

Hook when reserved quantity changes

If you need to do something when the reserved quantity of a product changes then you can use the below hook.

/**
 * Reserved Stock Pro - Do something when stock reservations change per product.
 *
 * @param int $product_id Product ID.
 */
function custom_reservation_quantity_changed( $product_id ) {
	// Do something..
}

add_action( 'reserved_stock_pro_reserved_stock_quantity_changed', 'custom_reservation_quantity_changed', 10, 1 );
Code language: PHP (php)

Disable Variation in Dropdown when fully reserved/out of stock.

Screenshot of disabled variation dropdown.
Single product variation not selectable.

On single product pages you can disable variations that are fully reserved or out of stock. Each of those variations will be disabled and appear greyed out. Customers will not be able to select the variations.

/**
 * Disables the variation in the single product dropdown if the variation is fully reserved or out of stock.
 *
 * @param bool   $is_active should variation be active or disabled.
 * @param object $variation product object.
 * @return bool
 */
function rsp_maybe_disable_variation( $is_active, $variation ) {

	if ( ! $is_active ) {
		return $is_active;
	}

	if ( function_exists( 'rsp_get_stock_amounts' ) ) {

		$data = rsp_get_stock_amounts( $variation->get_id() );

		if ( ! empty( $data ) ) {

			if ( $data['status'] === 'fully_reserved' || $data['status'] === 'out_of_stock' ) {
				return false;
			}
		}
	}

	return $is_active;
}

add_filter( 'woocommerce_variation_is_active', 'rsp_maybe_disable_variation', 10, 2 );Code language: PHP (php)

Modify frontend variation display based on reservations.

The woocommerce_available_variation hook allows you to change various variation data used to create the frontend dropdown.
We recommend that you fully test this hook to make sure you don’t create conflicts with other plugins that could be using it as well.

The below snippet does a couple of things. You should modify it to fit your needs.

  • Disable the add to cart button when a variation is “Out of stock” and “Fully Reserved”
  • Adds a custom message to variations that are “Fully Reserved”.
/**
 * Reserved Stock Pro - Apply various of things single product variations.
 *
 * Hook in use: https://github.com/woocommerce/woocommerce/blob/5007d17596855a685bd3ec3c8791e689a4e707f5/includes/class-wc-product-variable.php#L363
 *
 * @param array  $variation_data data used to display the available variations.
 * @param object $product product object.
 * @param object $variation variation product.
 * @return bool
 */
function rsp_filter_variation_data_for_single( $variation_data, $product, $variation ) {

	if ( is_admin() || ! is_single() ) {
		return $variation_data;
	}

	if ( function_exists( 'rsp_get_stock_amounts' ) ) {

		$data = rsp_get_stock_amounts( $variation->get_id() );

		if ( ! empty( $data ) ) {
			if ( $data['status'] === 'out_of_stock' ) {
				// Disable the variation "add to cart" button.
				$variation_data['is_purchasable'] = false;
			}

			if ( $data['status'] === 'fully_reserved' ) {
				// Disable the variation "add to cart" button.
				$variation_data['is_purchasable'] = false;
				// Add a custom message when fully reserved.
				$variation_data['variation_description'] = $variation_data['variation_description'] . 'All items reserved. Check back in a few minutes.';
			}
		}
	}

	return $variation_data;
}

add_filter( 'woocommerce_available_variation', 'rsp_filter_variation_data_for_single', 10, 3 );
Code language: PHP (php)

Change the Reservation Message Placement

You can change the default hook placement of the reservation messages.

This snippet will move the stock messages from below the “add to cart” buttons, to above the “add to cart” buttons on single product pages. You can replace with any hooks on the single product page.

If you return false the stock message will not be rendered at all. Instead you can manually place it with a shortcode mentioned above.

/**
 * Change the placement of the reservation messages on single product pages.
 */
function custom_rsp_single_product_stock_message_placement( $placement_hook ) {

	$placement_hook = 'woocommerce_before_add_to_cart_form';

	return $placement_hook;
}

add_filter( 'reserved_stock_pro_stock_message_placement', 'custom_rsp_single_product_stock_message_placement', 10, 1 );Code language: PHP (php)
Was this page helpful?