Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
This snippet adds a subscription toggle to products with a linked subscription.
<?php
/**
* Read the full post:
* https://wptheming.com/2017/08/subscription-toggle-in-woocommerce/
*
* This snippet adds a subscription toggle to products with a linked subscription.
*/
/**
* Adds an option under "Linked Products" on the product edit page.
*/
function example_product_options_related() {
global $post;
$meta_id = 'linked_subscription_id';
?>
<div class="options_group">
<p class="form-field">
<label for="<?php echo $meta_id; ?>"><?php _e( 'Linked Subscription', 'example' ); ?></label>
<select class="wc-product-search" style="width: 50%;" id="<?php echo $meta_id; ?>" name="<?php echo $meta_id; ?>[]" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'example' ); ?>" data-action="woocommerce_json_search_products_and_variations" data-exclude="<?php echo intval( $post->ID ); ?>">
<?php
$product_ids = get_post_meta( $post->ID, $meta_id, true );
foreach ( $product_ids as $product_id ) {
$product = wc_get_product( $product_id );
if ( is_object( $product ) ) {
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . wp_kses_post( $product->get_formatted_name() ) . '</option>';
}
}
?>
</select>
<?php echo wc_help_tip( __( 'Enables customer to choose subscription option from product page.', 'example' ) ); ?>
</p>
</div>
<?php }
add_action( 'woocommerce_product_options_related', 'example_product_options_related' );
/**
* Sanitizes and save the linked subscription product id
*/
function example_process_linked_subscription_meta( $post_id ) {
if ( ! ( isset( $_POST['woocommerce_meta_nonce'], $_POST[$meta_id] ) || wp_verify_nonce( sanitize_key( $_POST['woocommerce_meta_nonce'] ), 'woocommerce_save_data' ) ) ) {
return false;
}
$meta_id = 'linked_subscription_id';
$linked_subscription_id = isset( $_POST[$meta_id] ) ? array_map( 'intval', (array) $_POST[$meta_id] ) : array();
update_post_meta( $post_id, $meta_id, $linked_subscription_id );
}
add_action( 'woocommerce_process_product_meta', 'example_process_linked_subscription_meta' );
/**
* Adds a subscription toggle option for products that have a linked subscription.
* Including javascript inline for clarity.
*/
function example_add_subscription_option() {
global $product;
$display = false;
$linked_id = $product->get_meta( 'linked_subscription_id' );
if ( isset( $linked_id ) && $linked_id[0] ) {
$linked_product = wc_get_product( $linked_id[0] );
// If linked object is an actual product, set $display to true
if ( is_object( $linked_product ) ) {
$display = true;
}
}
?>
<?php
// Display the subscription toggle markup
if ( $display ) :
$onetime = array(
'id' => $product->get_id(),
'label' => 'One Time Order',
'button' => 'Add to Cart',
'price_html' => $product->get_price_html()
);
$subscription = array(
'id' => $linked_product->get_id(),
'label' => 'Subscribe and Save 15% (cancel anytime)',
'button' => 'Subscribe',
'price_html' => $linked_product->get_price_html()
);
?>
<div class="subscription-toggle">
<div class="radio-select">
<fieldset>
<div class="option option-onetime-order" data-product="<?php echo $onetime['id']; ?>" data-button="<?php echo $onetime['button']; ?>" data-price="<?php echo esc_html( $onetime['price_html'] ); ?>">
<input class="sub-switch" checked="checked" name="onetime-order" type="radio" />
<label for="onetime-order"><?php echo $onetime['label']; ?></label>
</div>
<div class="option option-subscription" data-product="<?php echo $subscription['id']; ?>" data-button="<?php echo $subscription['button']; ?>" data-price="<?php echo esc_html( $subscription['price_html'] ); ?>">
<input class="sub-switch" name="subscription-order" type="radio" />
<label name="subscription-order"><?php echo $subscription['label']; ?></label>
</div>
</fieldset>
</div>
</div>
<script>
jQuery(document).ready(function($) {
$('.subscription-toggle .option').on( 'click', function() {
$('.subscription-toggle input').prop('checked', false);
var $option = $(this).find('input');
var product = $(this).data('product');
var button = $(this).data('button');
var price = $(this).data('price');
$option.prop('checked', true);
$('.single_add_to_cart_button').text(button);
$('.price').html(price);
$('input[name=add-to-cart]').val(product);
});
});
</script>
<?php endif; ?>
<?php }
add_action( 'woocommerce_single_product_summary', 'example_add_subscription_option', 25 );
@lordspace
Copy link

lordspace commented Apr 17, 2018

Thanks for the cool article.
FYI: $meta_id is not defined before this check

( ! ( isset( $_POST['woocommerce_meta_nonce'], $_POST[$meta_id] )

@dumitriuxyz
Copy link

dumitriuxyz commented Jan 24, 2019

Hi,

Thanks for this great solution. Do you have something similar to work with Variable product?

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment