UserAccountDeletionTrait
Account deletion — the parts that touch the `cms_system_users` row itself and therefore live on {@see \App\UI\Api\System\Models\Managers\UserManager} (e-mails with links need the language and presenter context, the avatar removal its file helpers). The flow itself — tokens, steps of the other modules, audit — is {@see \App\UI\Api\System\Models\Managers\AccountDeletionManager}.
Requires on the host: $emailManager, $userRefreshTokenManager, $userService, updateColumns(),
bumpCacheTagsForClass(), getPresenterContext(), $languageContext, resolveAvatarAbsPath(), deleteAsset().
Table of Contents
Constants
- ACCOUNT_DELETION_PAGE_SLUG : int = \App\Core\Routers\PageId::SYSTEM_ACCOUNT_DELETION
- Page "Account deletion" (`Page:form` with the `accountDeletion` component) — target of the e-mailed links.
Methods
- anonymizeAccountRow() : Result
- Wipes the personal data of the account row (the row stays — orders, documents and posts refer to it). Placeholder e-mail/username free the originals for a new registration, the password becomes unusable, the account inactive; sessions are revoked and deleted.
- cancelAccountDeletion() : bool
- Compare-and-set cancel of the pending request the caller has read. `false` = refused (anonymized, claimed by a running anonymization, cancelled or requested again in the meantime) — nothing was written.
- claimAccountDeletion() : bool
- Atomic claim of the pending request the caller has just read (time + nonce). Only the run that gets `true` may take irreversible steps; it then owns the account by `$claimNonce` ({@see self::holdsAccountDeletionClaim()}).
- deliverAccountDeletionConfirm() : Result
- `SY_ACCOUNT_DELETION_CONFIRM` — an account without a password confirms its deletion request by this link.
- deliverAccountDeletionRequested() : Result
- `SY_ACCOUNT_DELETION_REQUESTED` — "your account will be deleted on the scheduled date, if it was not you, cancel it: <link>". The only place the plain cancel token leaves the server.
- getAccountDeletionGraceDays() : int
- Grace period from the setting `account.deletion.graceDays` (module 1), default 7 days.
- holdsAccountDeletionClaim() : bool
- Whether the run still owns the account (claim not lost).
- isSignInAllowedNow() : bool
- Fresh scalar check of the stored row right before tokens are handed out.
- buildAccountDeletionLink() : string|null
- sendAccountDeletionEmail() : Result
Constants
ACCOUNT_DELETION_PAGE_SLUG
Page "Account deletion" (`Page:form` with the `accountDeletion` component) — target of the e-mailed links.
public
int
ACCOUNT_DELETION_PAGE_SLUG
= \App\Core\Routers\PageId::SYSTEM_ACCOUNT_DELETION
Methods
anonymizeAccountRow()
Wipes the personal data of the account row (the row stays — orders, documents and posts refer to it). Placeholder e-mail/username free the originals for a new registration, the password becomes unusable, the account inactive; sessions are revoked and deleted.
public
anonymizeAccountRow(User $user, DateTimeInterface $now, string $claimNonce) : Result
The avatar file is removed only after its path was cleared.
IMPORTANT: one conditional UPDATE guarded by the claim of the run ($claimNonce). A
cancel that won the race, a new request or another run that took over a stale claim
leaves the row untouched and the result is INVALID_STATE.
Parameters
- $user : User
- $now : DateTimeInterface
- $claimNonce : string
Return values
ResultcancelAccountDeletion()
Compare-and-set cancel of the pending request the caller has read. `false` = refused (anonymized, claimed by a running anonymization, cancelled or requested again in the meantime) — nothing was written.
public
cancelAccountDeletion(User $user, DateTimeInterface $now) : bool
Parameters
- $user : User
- $now : DateTimeInterface
Return values
boolclaimAccountDeletion()
Atomic claim of the pending request the caller has just read (time + nonce). Only the run that gets `true` may take irreversible steps; it then owns the account by `$claimNonce` ({@see self::holdsAccountDeletionClaim()}).
public
claimAccountDeletion(User $user, string $claimNonce, DateTimeInterface $now) : bool
Parameters
- $user : User
- $claimNonce : string
- $now : DateTimeInterface
Return values
booldeliverAccountDeletionConfirm()
`SY_ACCOUNT_DELETION_CONFIRM` — an account without a password confirms its deletion request by this link.
public
deliverAccountDeletionConfirm(User $user, string $plainToken) : Result
Parameters
- $user : User
- $plainToken : string
Return values
ResultdeliverAccountDeletionRequested()
`SY_ACCOUNT_DELETION_REQUESTED` — "your account will be deleted on the scheduled date, if it was not you, cancel it: <link>". The only place the plain cancel token leaves the server.
public
deliverAccountDeletionRequested(User $user, DateTimeInterface $scheduledAt, string $plainToken) : Result
Parameters
- $user : User
- $scheduledAt : DateTimeInterface
- $plainToken : string
Return values
ResultgetAccountDeletionGraceDays()
Grace period from the setting `account.deletion.graceDays` (module 1), default 7 days.
public
getAccountDeletionGraceDays() : int
Return values
intholdsAccountDeletionClaim()
Whether the run still owns the account (claim not lost).
public
holdsAccountDeletionClaim(int $userId, string $claimNonce) : bool
Parameters
- $userId : int
- $claimNonce : string
Return values
boolisSignInAllowedNow()
Fresh scalar check of the stored row right before tokens are handed out.
public
isSignInAllowedNow(int $userId) : bool
Parameters
- $userId : int
Return values
boolbuildAccountDeletionLink()
private
buildAccountDeletionLink(array<string, string> $params) : string|null
Parameters
- $params : array<string, string>
Return values
string|nullsendAccountDeletionEmail()
private
sendAccountDeletionEmail(User $user, string $emailKey, array<string, string> $values) : Result
Parameters
- $user : User
- $emailKey : string
- $values : array<string, string>