Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Switch Subscription - Add Directly To Cart

I'm trying to bypass the single product page so I've created a custom template page for my subscriptions. On this page I'm generating the buttons to either allow users to signup for a specific subscription or switch their subscription. The problem I'm running into is getting the Switch Subscription URL to go to cart instead of the single product page.

The function below will test whether the user is logged in, if they are not show the add subscription to cart URL. If they are show the switch subscription url which I'm trying to just add it to cart ( or go straight to checkout ).

/**
 * Get Subscription URL ( Initial or Switch Subscription ) by Subscription ID
 *
 * @param Integer $subscription_id
 *
 * @return void
 */
function woo_subscriptions_checkout_url( $subscription_id, $echo = true ) {

    $subscription_id    = intval( $subscription_id );
    $subscription_url   = do_shortcode( '[add_to_cart_url id="' . $subscription_id . '"]' );

    if( is_user_logged_in() && function_exists( 'wcs_get_users_subscriptions' ) ) {

        $user_subscriptions = wcs_get_users_subscriptions();

        if( ! empty( $user_subscriptions ) ) {

            foreach( $user_subscriptions as $subscription ) {

                $subscription_order_id  = $subscription->get_parent_id();
                $subscription_key       = wcs_get_old_subscription_key( $subscription );

                if( ! empty( $subscription_key ) ) {

                    $plan_parent_id     = wp_get_post_parent_id( $subscription_id );
                    $subscription_url   = WC_Subscriptions_Switcher::add_switch_query_arg_post_link( get_permalink( wc_get_page_id( 'subscriptions' ) ), $plan_parent_id );

                    // Failed Test, Goes to Product
                    // $subscription_url    = WC_Subscriptions_Switcher::get_switch_url( $subscription_order_id, array( 'product_id' => $plan_parent_id ), $subscription );

                }

            }

        }

    }

    if( $echo ) {
        echo $subscription_url;
    } else {
        return $subscription_url;
    }

}

Additional information: There is 1 product with subscriptions as variations. I'm passing the Variation ID to this function in hopes of generating the correct URL.

like image 865
Howdy_McGee Avatar asked Jan 18 '18 17:01

Howdy_McGee


1 Answers

Here's what we got. We can add it to cart with specific URL arguments: Product, User Subscription ID, New Subscription ID, Subscription Order Line Number, and a nonce. Do not we did this on a single product with subscriptions as variations. This may need to be tweaked in other subscription cases but hopefully it's helpful to someone down the road:

/**
 * Generate cart button based on subscription variation ID
 *
 * @param Array $args
 *
 * @return void
 */
function prefix_subscriptions_checkout_button( $args = array() ) {

    $button_arr = wp_parse_args( $args, array(
        'variation_id'  => 0,
        'btn_class'     => array( 'button', 'button-primary' ),
        'btn_text'      => __( 'Sign Up' ),
        'btn_atts'      => array(),
    ) );

    $button_arr['btn_url'] = do_shortcode( '[add_to_cart_url id="' . intval( $button_arr['variation_id'] ) . '"]' );

    if( is_user_logged_in() && function_exists( 'wcs_get_users_subscriptions' ) ) {

        // Grab an array of user subscriptions
        $user_subscriptions = wcs_get_users_subscriptions();

        if( ! empty( $user_subscriptions ) ) {

            // Array( 'Subscription ID' => WC_Subscriptions Object );
            foreach( $user_subscriptions as $user_subscription_id => $subscription ) {

                // Loop through the users subscription order items to get the subscription order line item
                foreach( $subscription->get_items() as $item_line_number => $item_arr ) {

                    if( $user_subscription_id == $item_arr['order_id'] ) {

                        if( $item_arr['variation_id'] == $button_arr['variation_id'] ) {

                            // Change button based on status
                            switch( $subscription->get_status() ) {

                                case 'on-hold':
                                    $button_arr['btn_text']     = __( 'On Hold' );
                                    $button_arr['btn_class']    = array( 'button', 'button-secondary' );
                                    $button_arr['btn_url']      = 'javascript:void(0);';
                                  break;

                                case 'active':
                                    $button_arr['btn_text']     = __( 'Current' );
                                    $button_arr['btn_class']    = array( 'button', 'button-secondary' );
                                    $button_arr['btn_url']      = 'javascript:void(0);';
                                  break;

                                default:
                                    $button_arr['btn_url'] = add_query_arg( array(
                                            'add-to-cart'           => $item_arr['product_id'],
                                            'switch-subscription'   => $user_subscription_id,
                                            'variation_id'          => $button_arr['variation_id'],
                                            'item'                  => $item_line_number,
                                            '_wcsnonce'             => wp_create_nonce( 'wcs_switch_request' )
                                        ),
                                        wc_get_cart_url()
                                    );
                            }

                        }

                    }

                }

            }

        }

    }

    // Create button attributes
    $button_atts = '';
    if( ! empty( $button_arr['btn_atts'] ) && is_array( $button_arr['btn_atts'] ) ) {
        foreach( $button_arr['btn_atts'] as $attribute => $value ) {
            $button_atts .= sprintf( ' %1$s="%2$s"', esc_attr( $attribute ), esc_attr( $value ) );
        }
    }

    // Create button Classes
    if( ! empty( $button_arr['btn_class'] ) && is_array( $button_arr['btn_class'] ) ) {
        array_walk( $button_arr['btn_class'], 'esc_attr' );
        $button_arr['btn_class'] = implode( ' ', $button_arr['btn_class'] );
    }

    // Display Button
    printf( '<a href="%1$s" class="%2$s"%3$s>%4$s</a>',
        $button_arr['btn_url'],
        esc_attr( $button_arr['btn_class'] ),
        ( ! empty( $button_atts ) ) ? $button_atts : '',
        $button_arr['btn_text']
    );

}
like image 171
Howdy_McGee Avatar answered Sep 30 '22 06:09

Howdy_McGee