TokenManager::regenerate_for_resubscriber()
BenecasterTokenTokenManager::regenerate_for_resubscriber( int $user_id, int $show_id, string $tier_slug ): void
Mints a fresh token for a returning subscriber by deleting their prior token row and inserting a new one. Ships in feature/built-in-membership-lifecycle.
When It Is Called
Called by SubscriptionListener::handle_activation() when $source === 'resubscribe'. All other activation sources ('new', 'migration', and unknown values) continue to route through generate_or_reactivate(), which reactivates an existing revoked row when possible.
What It Does
- Deletes any prior token row for the
(user_id, show_id)pair — regardless of whether the row isactiveorrevoked. - Calls
generate()to mint a new token — new hash, new prefix, new feed URL. - Fires
benecaster_token_generatedwith the new plaintext token, causingEmailTriggersto queue the standard welcome email.
Why a New Token (Not Reactivation)
A resubscribing subscriber cancelled a previous subscription. Their prior feed URL may have been shared or compromised. Issuing a fresh token ensures:
- The prior feed URL stops working (the old row is gone).
- The subscriber gets a clean start, consistent with re-joining rather than pausing.
- This is consistent with external bridge behavior — bridges such as MemberPress and WooCommerce Subscriptions do not reactivate old tokens;
benecaster_subscription_cancelledfires when the subscriber leaves,benecaster_subscription_activatedfires when they return.
Breaking Change for Existing Listeners
Prior to this method shipping, generate_or_reactivate() was used for all sources including resubscribes — meaning the subscriber’s prior token and feed URL were preserved across the cancellation → resubscribe boundary. Any listener that cached the feed URL or token prefix for a resubscribing subscriber must now treat $source === 'resubscribe' as a new-token event and refresh those cached values.
See benecaster_subscription_activated for the full resubscribe contract.