RevocationReasons
\Benecaster\Token\RevocationReasons
The set of reason strings recorded in a token’s revocation_reason column, and the one question the token lifecycle asks of them: may a later subscription activation bring this token back? It is a final class of constants and two static methods, and is never instantiated.
The distinction is between a token that lapsed and one a podcaster removed. Automated reasons are recoverable: a subscriber whose bridge subscription ended and who then resubscribes gets the same feed URL back. An admin revoke is not: a membership plugin must never be able to undo a podcaster’s deliberate decision. Nor is the deletion of the person’s WordPress account. When reactivation is refused, TokenManager::generate_or_reactivate() fires benecaster_token_reactivation_blocked instead of benecaster_token_reactivated.
A revoked row with a NULL or empty reason is treated as recoverable, so rows revoked before reasons were recorded are not stranded. The class has no public function wrapper. The supported extension point is the benecaster_token_reactivation_recoverable_reasons filter, which adds your own reason to the recoverable list.
Methods
| Method | Visibility | Since | Description |
|---|---|---|---|
static recoverable(): array |
Public | — | Returns the list of reasons that permit reactivation: bridge_cancellation, grace_timeout, promote_grace_expired and manual_grant_expired, passed through the benecaster_token_reactivation_recoverable_reasons filter. After the filter runs, non-string entries and duplicates are removed and the list is re-indexed. |
static is_recoverable( ?string $reason ): bool |
Public | — | Returns true when a stored reason permits reactivation. NULL and an empty string return true. Any other string must appear in recoverable(); a reason that is not listed, including one you introduce and do not add to the filter, returns false and blocks reactivation. |
Constants
| Name | Value | Description |
|---|---|---|
BRIDGE_CANCELLATION |
'bridge_cancellation' |
A bridge reported the subscription as ended, or the sweep of lapsed bridge tokens found one. Recoverable. |
GRACE_TIMEOUT |
'grace_timeout' |
The license grace period ended in a hard cutoff and active tokens were revoked; they are restored when the license recovers. Recoverable. |
PROMOTE_GRACE_EXPIRED |
'promote_grace_expired' |
A promote-to-bridge grace window ran out without payment recovery. Recoverable. |
MANUAL_GRANT_EXPIRED |
'manual_grant_expired' |
A time-limited manual grant reached its end date and the listener held no standalone purchase. Recoverable. |
ADMIN_REVOKED |
'admin_revoked' |
The podcaster clicked Remove, or bulk Revoke, on the Subscribers screen. Not recoverable: a bridge activation cannot undo it, and Reset Token is the way to restore access. It is also, apart from account deletion, the one revocation path that does not convert a listener who holds standalone purchases to a purchaser token. Every automatic ending keeps such a listener's purchased feed alive; Remove removes it, including the purchased feed. |
ACCOUNT_DELETED |
'account_deleted' |
The person's WordPress account was deleted. Benecaster revokes each of their active tokens with this reason, firing benecaster_token_revoked, and then deletes the token rows and their purchase records in the same request, so a listener on that action is the only code that ever sees it. Not recoverable: an account that no longer exists holds no feed. |
Hooks Fired
Notes
An add-on with its own automated revoke path should write its own reason string and add it to the recoverable list through benecaster_token_reactivation_recoverable_reasons, rather than reusing BRIDGE_CANCELLATION. A reason left off the list behaves like ADMIN_REVOKED.
Never add ADMIN_REVOKED to the recoverable list. It removes the protection silently: everything appears to work, and a podcaster's revokes stop holding.
PauseReasons is the billing-side counterpart. It tags subscriptions the plugin pauses rather than tokens it revokes, and GRACE_TIMEOUT appears in both with the same string because one license cutoff is recorded once against access and once against billing.