EntitlementRepository
\Benecaster\Entitlement\EntitlementRepository
Benecaster’s record of non-tier access: which episodes or bundles a person holds outside any membership tier. This is the access record only. Prices, refunds and receipts belong to the add-on’s own tables.
Grants belong to the person, never to a token. A grant survives a token being revoked, reset or converted. expires_at NULL means a lifetime grant, not an unknown one. Both dates are UTC.
Holding a grant is a fact, not a ledger. There is one row per person, show and grant slug, so granting a slug already held extends the existing row and can never shorten it: a lifetime grant stays a lifetime grant, a dated one only moves later. An add-on that needs purchase history keeps it in its own tables.
For access decisions, read the published functions, not this class. benecaster_get_user_grants() and benecaster_user_holds_grant() resolve through the feed and are the recommended surface for a gate. This repository’s own read methods talk directly to the table and are for Benecaster’s own use and for the personal-data export.
Methods
| Method | Visibility | Since | Description |
|---|---|---|---|
find_live_grant_slugs( int $user_id, int $show_id ): array |
Public | — | The grant slugs the person currently holds on the show. Expired grants are excluded. |
show_grant_slugs( int $show_id ): array |
Public | — | Which named sets this show has sold: the distinct grant slugs with a live row on the show. This is not an access check and must never be used as one. It says nothing about any person, and a slug an add-on supplies through benecaster_entitlement_grant_slugs with no row in this table is invisible to it. Its one caller is the selector-less [benecaster_access_gate] in the feed, where that miss makes the gate take its else branch. |
user_holds_any_grant( int $user_id, int $show_id ): bool |
Public | — | Whether the person holds at least one live grant on the show. |
user_holds_grant( int $user_id, int $show_id, string $grant_slug ): bool |
Public | — | Whether the person holds this specific live grant on the show. |
grant( int $user_id, int $show_id, string $grant_slug, ?string $expires_at = null, string $source = 'core', ?string $external_ref = null ): bool |
Public | — | Grants access, or extends an existing grant. $expires_at is a UTC Y-m-d H:i:s string, or null for a lifetime grant. Re-granting never shortens: passing a date to a lifetime grant leaves it lifetime. Returns true when a row was written. |
revoke_grant( int $user_id, int $show_id, string $grant_slug ): bool |
Public | — | Removes a grant outright. This is the refund, chargeback or mistake path, not the expiry path: a grant that ran out is left in place with its expires_at in the past, so the add-on can still see the person once held it. |
find_all_for_user( int $user_id ): array |
Public | — | Every grant row the person has ever held, across every show, live AND expired, oldest first. For the personal-data export only — it deliberately ignores expires_at, because a subject-access request asks what is held about the person, not what they can currently redeem. Anything deciding what someone may hear must use GrantSlugResolver or the published benecaster_get_user_grants() / benecaster_user_holds_grant() functions instead. |
erase_for_user( int $user_id ): int |
Public | — | Deletes every grant the person holds, on every show, and returns the row count. The right-to-erasure path only: erases, never anonymises, and is never called by the nightly retention sweep, because entitlements are exempt from the configurable retention policy — only a genuine erasure request calls this. |
Constants
| Name | Value | Description |
|---|---|---|
SOURCE_CORE |
'core' |
The default source recorded on a grant. Add-ons pass their own slug. |