Created
November 3, 2022 22:41
-
-
Save danieliser/1a8837af4b8effa4accae18512c4a268 to your computer and use it in GitHub Desktop.
EDD Subscription Cancellation UX using Gravity Forms & WP Fusion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Assumptions: | |
* - Form ID is #28 | |
* - Page ID is 406200 | |
* - Fields include radio for reason & extra details where needed. | |
*/ | |
namespace CustomCode; | |
# Filter EDD sub cancellation link to custom page. | |
add_filter( 'edd_subscription_cancel_url', __NAMESPACE__ . '\\modify_edd_subscription_cancel_url', 10, 2 ); | |
# During template redirect check if the user is trying to cancel a valid subscription of theirs. | |
add_action( 'template_redirect', __NAMESPACE__ . '\\protect_subscription_cancellation_page' ); | |
# Checks if validation for hidden field #3 fails, if so moves its error to the main top error spot. | |
add_filter( 'gform_validation_message_28', __NAMESPACE__ . '\\modify_error_message_locations_28', 10, 2 ); | |
# Hook into gravity form validation for form #28, check that field #3 is a valid sub_id | |
add_filter( 'gform_field_validation_28_3', __NAMESPACE__ . '\\validate_sub_cancellation_sub_id', 10, 4 ); | |
# After gravity form #28 submission, get sub_id from field 3, and use it to cancel easy digital downloads subscription | |
add_action( 'gform_after_submission_28', __NAMESPACE__ . '\\cancel_edd_subscription', 10, 2 ); | |
# After submission, if user skipped survey, tag them for future follow up. | |
add_filter( 'wpf_gravity_forms_apply_tags_28', __NAMESPACE__ . '\\add_tags_for_users_without_survey_submission', 10, 4 ); | |
/** | |
* Modify the cancel URL to go to the custom cancel page | |
* | |
* @since 2022-11-03 | |
* | |
* @param string $url | |
* @param EDD_Subscription $EDD_Subscription | |
* | |
* @return string URL pointing to the cancel page | |
*/ | |
function modify_edd_subscription_cancel_url( $url, $EDD_Subscription = null ) { | |
$cancel_id = ( defined( 'IS_LOCAL_DEV' ) && IS_LOCAL_DEV ) ? 406200 : 406200; | |
$url = add_query_arg( array( 'sub_id' => $EDD_Subscription->id ), get_permalink( $cancel_id ) ); | |
return $url; | |
} | |
/** | |
* Prevent access to the subscription without | |
* | |
* @since 2022-11-03 | |
*/ | |
function protect_subscription_cancellation_page() { | |
$cancel_page = 406200; | |
// If not the cancel page, we don't need to do anything. | |
if ( ! is_page( $cancel_page ) ) { | |
return; | |
} | |
// If no sub id redirect to subscriptions page. | |
if ( ! isset( $_GET['sub_id'] ) ) { | |
wp_safe_redirect( 'https://wppopupmaker.com/your-account/subscriptions/' ); | |
} | |
// Get sub id from url. | |
$sub_id = absint( $_GET['sub_id'] ); | |
$subscription = new \EDD_Subscription( $sub_id ); | |
# Verify subscription is cancelable & by this user. | |
if ( ! $subscription->can_cancel() || (int) $subscription->customer->user_id !== (int) get_current_user_id() ) { | |
wp_die( sprintf( 'No subscription #%d was found for your account. Please go back and try again.', $sub_id ) ); | |
} | |
} | |
/** | |
* Check if the hidden field has an error message, if ss, set that error as the main form error. | |
* | |
* @since 2022-11-03 | |
*/ | |
function modify_error_message_locations_28( $message, $form ) { | |
$has_other_error = false; | |
$custom_error_field = false; | |
foreach ( $form['fields'] as $field ) { | |
if ( ! $field->failed_validation ) { | |
continue; | |
} | |
if ( ( $field->visibility === 'hidden' || $field->get_input_type() === 'hidden' ) && $field->id === 3 ) { | |
$custom_error_field = $field; | |
} else { | |
$has_other_error = true; | |
} | |
} | |
if ( $custom_error_field && ! $has_other_error ) { | |
$message = sprintf( '<h2 class="gform_submission_error hide_summary"><span class="gform-icon gform-icon--close"></span>%s</h2>', $custom_error_field->validation_message ); | |
} | |
return $message; | |
} | |
/** | |
* Validate the hidden sub_id field has a valid subscription ID and the current user can cancel it. | |
* | |
* @since 2022-11-03 | |
*/ | |
function validate_sub_cancellation_sub_id( $result, $value, $form, $field ) { | |
$subscription = new \EDD_Subscription( absint( $value ) ); | |
# Verify subscription is cancelable | |
if ( ! $subscription->can_cancel() || (int) $subscription->customer->user_id !== (int) get_current_user_id() ) { | |
$result['is_valid'] = false; | |
$result['message'] = sprintf( 'No subscription #%d was found with your account. Please go back and try again.', absint( $value ) ); | |
} | |
return $result; | |
} | |
/** | |
* Helper function for setting a static flag throughout the submission process. | |
*/ | |
function submission_flagged( $set_flag = null ) { | |
static $flag = false; | |
if ( null !== $set_flag ) { | |
$flag = $set_flag; | |
} | |
return $flag; | |
} | |
/** | |
* Cancel subscription and add nots for customer reasons. | |
* | |
* @since 2022-11-03 | |
*/ | |
function cancel_edd_subscription( $entry, $form ) { | |
$sub_id = rgar( $entry, '3' ); | |
$subscription = new \EDD_Subscription( absint( $sub_id ) ); | |
# Verify subscription is cancelable & by this user. | |
if ( ! $subscription->can_cancel() || (int) $subscription->customer->user_id !== (int) get_current_user_id() ) { | |
wp_die( sprintf( 'No active subscription #%d was found for your account. Please go back and try again.', $sub_id ) ); | |
} | |
$gateway = edd_recurring()->get_gateway_class( $subscription->gateway ); | |
$can_edd_mark_cancelled = true; | |
// Try and cancel at the gateway. | |
if ( $gateway ) { | |
$can_edd_mark_cancelled = false; | |
$gateway_obj = new $gateway(); | |
$can_edd_mark_cancelled = $gateway_obj->cancel( $subscription, true ); | |
} | |
if ( ! $can_edd_mark_cancelled ) { | |
wp_die( sprintf( 'There was an error cancelling your subscription #%d. Please contact us for assistance.', $sub_id ) ); | |
} | |
// Cancel in EDD. | |
$subscription->cancel(); | |
# Prepare reasoning. | |
$reason = rgar( $entry, '4' ); | |
// Depending on $reason type, generate note text. | |
switch( $reason ) { | |
case 'expensive': | |
$reason_note = __( 'User found it too expensive' ); | |
$enjoyed = (bool) rgar( $entry, '4' ); | |
if ( ! $enjoyed ) { | |
$reasoning = sanitize_text_field( rgar( $entry, '5') ); | |
if ( ! empty( $reasoning ) ) { | |
$reason_note .= sprintf( __( ' and said: %s' ), $reasoning ); | |
} | |
} | |
break; | |
case 'do-not-use': | |
$reason_note = __( 'User was no longer using the product' ); | |
$reasoning = sanitize_text_field( rgar( $entry, '9') ); | |
if ( ! empty( $reasoning ) ) { | |
$reason_note .= sprintf( __( ' and said: %s' ), $reasoning ); | |
} | |
break; | |
case 'unhappy': | |
$reason_note = __( 'User was unhappy with the product' ); | |
$reasoning = sanitize_text_field( rgar( $entry, '5') ); | |
if ( ! empty( $reasoning ) ) { | |
$reason_note .= sprintf( __( ' and said: %s' ), $reasoning ); | |
} | |
break; | |
case 'other': | |
$reason_note = __( 'User had other reasons' ); | |
$reasoning = sanitize_text_field( rgar( $entry, '8') ); | |
if ( ! empty( $reasoning ) ) { | |
$reason_note .= sprintf( __( ' and said: %s' ), $reasoning ); | |
} | |
break; | |
default: | |
submission_flagged( true ); | |
$reason_note = __( 'User did not provide a reason' ); | |
break; | |
} | |
# Create formatted sub cancellation note. | |
$sub_cancel_note = sprintf( __( 'Cancellation Reason: %s' ), $reason_note ); | |
# Add note to subscription. | |
$subscription->add_note( $sub_cancel_note ); | |
# Get cancelled product name. | |
$product_name = edd_get_download_name( $subscription->product_id ); | |
# Create formatted note for customer profile. | |
$customer_cancel_note = sprintf( | |
__( 'Subscription #<a href="%s">%d</a> for %s cancelled. %s' ), | |
admin_url( 'edit.php?post_type=download&page=edd-subscriptions&id=' . $subscription->id ), | |
$sub_id, | |
$product_name, | |
$sub_cancel_note | |
); | |
# Add customer note | |
$subscription->customer->add_note( $customer_cancel_note ); | |
} | |
/** | |
* Tags users who did not fill out the survey in our CRM for follow up later. | |
* | |
* @since 2022-11-03 | |
*/ | |
function add_tags_for_users_without_survey_submission( $apply_tags, $user_id, $contact_id, $form_id ) { | |
if ( submission_flagged() ) { | |
$apply_tags[] = 'Skipped Subscription Cancellation Survey'; | |
} | |
return $apply_tags; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment