Skip to content

Commit

Permalink
feat(woocommerce-subscriptions): add url redirect for wc subscription…
Browse files Browse the repository at this point in the history
… renewals (#3525)

This PR adds handling for a new `my-account/renew-subscription` endpoint to redirect readers to the first available pending renewal checkout, otherwise the subscriptions my account page.
  • Loading branch information
chickenn00dle authored Dec 2, 2024
1 parent a2e4042 commit 5b14aeb
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 11 deletions.
127 changes: 127 additions & 0 deletions includes/plugins/woocommerce-subscriptions/class-renewal.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php
/**
* WooCommerce Subscriptions renewal class.
*
* @package Newspack
*/

namespace Newspack;

defined( 'ABSPATH' ) || exit;

/**
* Main class.
*/
class Renewal {
/**
* Renewal endpoint.
*
* @var string
*/
const RENEWAL_ENDPOINT = 'renew-subscription';

/**
* Initialize hooks and filters.
*/
public static function init() {
if ( ! WooCommerce_Subscriptions::is_active() ) {
return;
}

add_action( 'init', [ __CLASS__, 'add_renewal_endpoint' ] );
if ( ! is_admin() ) {
add_filter( 'woocommerce_get_query_vars', [ __CLASS__, 'add_renewal_query_var' ] );
add_filter( 'pre_get_posts', [ __CLASS__, 'maybe_redirect_renewal_endpoint' ] );
}
}

/**
* Add renewal endpoint.
*/
public static function add_renewal_endpoint() {
add_rewrite_endpoint( self::RENEWAL_ENDPOINT, EP_ROOT | EP_PAGES );
self::flush_rewrite_rules();
}

/**
* Add renewal query var.
*
* @param array $query_vars Query vars.
*
* @return array
*/
public static function add_renewal_query_var( $query_vars ) {
$query_vars[ self::RENEWAL_ENDPOINT ] = self::RENEWAL_ENDPOINT;
return $query_vars;
}

/**
* Get the URL for the My Account > Subscriptions page.
*
* @return string
*/
public static function get_subscriptions_url() {
return wc_get_account_endpoint_url( 'subscriptions' );
}

/**
* Returns true when on the My Account > Subscriptions front end page.
*
* @return bool
*/
public static function is_subscriptions_page() {
if ( ! WooCommerce_Subscriptions::is_active() ) {
return false;
}
return is_wc_endpoint_url( 'subscriptions' );
}

/**
* Conditionally redirects the renewal endpoint url.
*
* @param \WP_Query $query Query object.
*/
public static function maybe_redirect_renewal_endpoint( $query ) { // phpcs:ignore WordPressVIPMinimum.Hooks.AlwaysReturnInFilter.VoidReturn, WordPressVIPMinimum.Hooks.AlwaysReturnInFilter.MissingReturnStatement
if (
! $query->is_main_query() ||
! isset( $query->query_vars[ self::RENEWAL_ENDPOINT ] )
) {
return;
}
$redirect_url = wc_get_account_endpoint_url( 'subscriptions' );
if ( is_user_logged_in() ) {
$pending_renewal = wcs_get_subscriptions(
[
'customer_id' => get_current_user_id(),
'subscription_status' => [
'pending',
'on-hold',
],
]
);
if ( count( $pending_renewal ) === 1 ) {
$orders = array_pop( $pending_renewal )->get_related_orders( 'all', 'renewal' );
foreach ( $orders as $order ) {
if ( $order->needs_payment() ) {
$redirect_url = $order->get_checkout_payment_url();
break;
}
}
}
} else {
$redirect_url .= '?redirect=' . wc_get_account_endpoint_url( self::RENEWAL_ENDPOINT );
}
wp_safe_redirect( $redirect_url );
exit();
}

/**
* Refresh permalinks the first time this feature is enabled.
*/
private static function flush_rewrite_rules() {
if ( ! get_option( 'newspack_subscriptions_renewal_permalinks_refreshed', false ) ) {
flush_rewrite_rules(); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.flush_rewrite_rules_flush_rewrite_rules
update_option( 'newspack_subscriptions_renewal_permalinks_refreshed', true );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,25 @@ class WooCommerce_Subscriptions {
* Initialize hooks and filters.
*/
public static function init() {
add_action( 'plugins_loaded', [ __CLASS__, 'woocommerce_subscriptions_integration_init' ] );
}

/**
* Initialize WooCommerce Subscriptions Integration.
*/
public static function woocommerce_subscriptions_integration_init() {
// To be included only if WooCommerce Subscriptions Integration is enabled.
// See is_enabled() method.
if ( self::is_enabled() ) {
include_once __DIR__ . '/class-on-hold-duration.php';

On_Hold_Duration::init();
}

include_once __DIR__ . '/class-renewal.php';
Renewal::init();
}


/**
* Check if WooCommerce Subscriptions is active.
*
Expand All @@ -36,12 +48,15 @@ public static function is_active() {
/**
* Check if WooCommerce Subscriptions Integration is enabled.
*
* Enalbed if Reader activation is enabled and the feature flag is defined.
* True if:
* - WooCommerce Subscriptions is active and,
* - Reader Activation is enabled and,
* - The NEWSPACK_SUBSCRIPTIONS_EXPIRATION feature flag is defined
*
* @return bool
*/
public static function is_enabled() {
return Reader_Activation::is_enabled() && defined( 'NEWSPACK_SUBSCRIPTIONS_EXPIRATION' ) && NEWSPACK_SUBSCRIPTIONS_EXPIRATION;
return self::is_active() && Reader_Activation::is_enabled() && defined( 'NEWSPACK_SUBSCRIPTIONS_EXPIRATION' ) && NEWSPACK_SUBSCRIPTIONS_EXPIRATION;
}
}
WooCommerce_Subscriptions::init();
15 changes: 11 additions & 4 deletions includes/reader-activation/class-reader-activation.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use Newspack\Recaptcha;
use Newspack\Reader_Activation\Sync;
use Newspack\Renewal;

defined( 'ABSPATH' ) || exit;

Expand Down Expand Up @@ -1330,10 +1331,16 @@ public static function render_auth_form( $in_modal = true ) {

$referer = \wp_parse_url( \wp_get_referer() );
$labels = self::get_reader_activation_labels( 'signin' );
$auth_callback_url = '#';
// If we are already on the my account page, set the my account URL so the page reloads on submit.
if ( function_exists( 'wc_get_page_permalink' ) && function_exists( 'is_account_page' ) && \is_account_page() ) {
$auth_callback_url = \wc_get_page_permalink( 'myaccount' );
// If there is a redirect parameter, use it as the auth callback URL.
$auth_callback_url = filter_input( INPUT_GET, 'redirect', FILTER_SANITIZE_URL ) ?? '#';
if ( '#' === $auth_callback_url ) {
if ( Renewal::is_subscriptions_page() ) {
// If we are on the subscriptions page, set the auth callback URL to the subscriptions page.
$auth_callback_url = Renewal::get_subscriptions_url();
} elseif ( function_exists( 'wc_get_page_permalink' ) && function_exists( 'is_account_page' ) && \is_account_page() ) {
// If we are already on the my account page, set the my account URL so the page reloads on submit.
$auth_callback_url = \wc_get_page_permalink( 'myaccount' );
}
}
?>
<div class="newspack-ui newspack-reader-auth">
Expand Down
6 changes: 2 additions & 4 deletions src/reader-activation-auth/auth-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,12 +323,10 @@ window.newspackRAS.push( function ( readerActivation ) {
container.querySelector( '.success-description' ).innerHTML =
labels.success_description || '';
const callbackButton = container.querySelector( '.auth-callback' );
if ( callbackButton ) {
if ( callbackButton && callback ) {
callbackButton.addEventListener( 'click', ev => {
ev.preventDefault();
if ( callback ) {
callback( message, data );
}
callback( message, data );
} );
}

Expand Down

0 comments on commit 5b14aeb

Please sign in to comment.