UserManager
extends Manager
in package
uses
SaveTrait
Abstract front manager generic over the entity type and its service.
Tags
Table of Contents
Properties
- $service : UserService
- $appContext : AppContext
- $cacheTagInvalidator : CacheTagInvalidator|null
- Post-commit invalidator of the wire-payload query cache (tag bump per entity class).
- $languageContext : LanguageContext|null
- $paramsConfig : Config|null
- Neon parameters (`%params%`: server paths and directories), set by the decorator (`decorators.neon`) like `setAppContext()`.
- $presenterContext : PresenterContext
- $settingContext : SettingContext
Methods
- __construct() : mixed
- activateUser() : Result
- Account activation from the e-mailed link (called by `RegistrationPresenter`).
- cancelDeletion() : Result
- Cancel by the e-mailed key or by the ticket from a refused sign-in.
- confirmDeletion() : Result
- Confirmation link of an account without a password.
- confirmExternalLink() : Result
- Confirms pairing the provider identity from the e-mailed link and signs in.
- deauthorizeExternal() : Result
- emailExists() : bool|null
- E-mail counterpart of {@see self::usernameExists()}, same contract.
- find() : SingleQuery<string|int, T>
- Finds one entity by ID and returns a `SingleQuery` object.
- findAll() : Query<string|int, T>
- Finds all entities and returns a `Query` object.
- findBy() : SingleQuery<string|int, T>
- Finds one entity by filters and returns a `SingleQuery` object.
- findPublicProfile() : PublicProfile|null
- Returns the public profile of another user.
- findPublicProfiles() : array<int, PublicProfile>
- Returns public profiles in bulk for lists.
- getAppContext() : AppContext
- getLanguageContext() : LanguageContext|null
- getPresenterContext() : PresenterContext
- getSettingContext() : SettingContext
- getSettings() : array<int, array<string, mixed>>
- getTotalCount() : int|null
- Returns the total count of the last `findAll()` of this manager's service, computed only when the query asked for it (`findAll(..., computeTotalCount: true)`); otherwise the last stored value.
- initializeAllContexts() : void
- login() : Result
- `$deviceToken` = cookie of a known device, verified by the Api.
- loginExternal() : Result
- referralOverview() : Result
- Affiliate program for the "My account" page (`:Api:System:User:referralOverview`).
- requestDeletion() : Result
- resetPassword() : Result
- New password from the one-time "lost password" link (e-mail + key).
- revealPhone() : string
- Returns the raw phone of one user, on request.
- save() : Result
- sendActivationEmail() : Result
- sendNewPassword() : Result
- Asks the Api to send a new password (replaced `generateNewPassword(int $userId)` called by `LostPasswordFormComponent`).
- setAppContext() : $this
- setCacheTagInvalidator() : static
- setLanguageContext() : $this
- setParamsConfig() : static
- setPresenterContext() : $this
- setSettingContext() : $this
- updateColumn() : Result
- updateColumns() : Result
- updatePassword() : Result
- Own password change; Api verifies `$currentPassword`, revokes the other sessions and returns a fresh `token` + `refreshToken` + `payload` in `data`.
- usernameExists() : bool|null
- The only way for the front end to find out whether a username/e-mail is taken.
- bumpCacheTags() : void
- Bumps cache tags for the entity after commit: its class, the owned-cascade classes from metadata and the optional `additionalCacheTags()` of the manager.
- bumpCacheTagsExplicit() : void
- Bumps the given classes explicitly (raw-DBAL paths with a cross-entity effect).
- bumpCacheTagsForClass() : void
- Bumps cache tags by class name when there is no instance (bulk delete, `updateColumns()`, raw DBAL, tree operations).
- classCacheTags() : array<string|int, string>
- Returns extra tags for a bump that has no entity, typically tree operations ({@see \App\Core\Traits\Api\Models\Managers\TreeTrait::treeTransaction()}) that rewrite `lft`/`rgt` on many rows.
- getService() : TService
- Returns the service for the traits.
Properties
$service
public
UserService
$service
$appContext
protected
AppContext
$appContext
$cacheTagInvalidator
Post-commit invalidator of the wire-payload query cache (tag bump per entity class).
protected
CacheTagInvalidator|null
$cacheTagInvalidator
= null
Set by the decorator (decorators.neon) like setParamsConfig(). Nullable and
fail-open: without wiring (or without Redis) a bump is a no-op.
$languageContext
protected
LanguageContext|null
$languageContext
= NULL
$paramsConfig
Neon parameters (`%params%`: server paths and directories), set by the decorator (`decorators.neon`) like `setAppContext()`.
protected
Config|null
$paramsConfig
= null
Write logic (asset directories) reads paths from here, not from getSettings() or the
setting context, which may be filled by the client without server paths. The property
cannot be named $config: it collides with the promoted $config in some managers.
$presenterContext
protected
PresenterContext
$presenterContext
$settingContext
protected
SettingContext
$settingContext
Methods
__construct()
public
__construct(UserService $service) : mixed
Parameters
- $service : UserService
activateUser()
Account activation from the e-mailed link (called by `RegistrationPresenter`).
public
activateUser(string $email, string $activationKey) : Result
Parameters
- $email : string
- $activationKey : string
Return values
ResultcancelDeletion()
Cancel by the e-mailed key or by the ticket from a refused sign-in.
public
cancelDeletion(string $key) : Result
Parameters
- $key : string
Return values
ResultconfirmDeletion()
Confirmation link of an account without a password.
public
confirmDeletion(string $key) : Result
Parameters
- $key : string
Return values
ResultconfirmExternalLink()
Confirms pairing the provider identity from the e-mailed link and signs in.
public
confirmExternalLink(string $key) : Result
Parameters
- $key : string
Return values
ResultdeauthorizeExternal()
public
deauthorizeExternal(string $provider, string $externalId) : Result
Parameters
- $provider : string
- $externalId : string
Return values
ResultemailExists()
E-mail counterpart of {@see self::usernameExists()}, same contract.
public
emailExists(string $email[, int|null $excludeId = null ]) : bool|null
Parameters
- $email : string
- $excludeId : int|null = null
Return values
bool|nullfind()
Finds one entity by ID and returns a `SingleQuery` object.
public
find(int $id[, string|array<string|int, mixed> $includes = [] ]) : SingleQuery<string|int, T>
Usage:
$query = $manager->find(1, ['translations']);
$entity = $query->include(['routes'])->execute(); // or ->get()
$title = $query->getTitle(); // magic call, forwarded to the entity
Parameters
- $id : int
-
entity ID
- $includes : string|array<string|int, mixed> = []
-
relations to load
['translations', 'routes'], or'*'for all
Return values
SingleQuery<string|int, T>findAll()
Finds all entities and returns a `Query` object.
public
findAll([array<string|int, mixed>|null $filters = [] ][, array<string|int, mixed>|null $orderBy = null ][, int|null $offset = null ][, int|null $limit = null ][, array<string|int, mixed>|null $columns = null ][, string|array<string|int, mixed> $includes = [] ][, bool $computeTotalCount = false ]) : Query<string|int, T>
Usage:
$query = $manager->findAll(['active' => true], ['created' => 'desc']);
$items = $query->include(['translations'])->limit(10)->execute();
foreach ($query as $item) { ... } // the query runs lazily on iteration
Parameters
- $filters : array<string|int, mixed>|null = []
-
filters for the where conditions
- $orderBy : array<string|int, mixed>|null = null
-
ordering
['column' => 'ASC/DESC'] - $offset : int|null = null
-
offset for pagination
- $limit : int|null = null
-
result limit
- $columns : array<string|int, mixed>|null = null
-
specific columns to load
- $includes : string|array<string|int, mixed> = []
-
relations to load
['translations', 'routes.translations'], or'*'for all - $computeTotalCount : bool = false
-
whether to compute the total count for pagination
Return values
Query<string|int, T>findBy()
Finds one entity by filters and returns a `SingleQuery` object.
public
findBy([array<string|int, mixed> $filters = [] ][, string|array<string|int, mixed> $includes = [] ]) : SingleQuery<string|int, T>
Usage:
$query = $manager->findBy(['slug' => 'my-page'], ['translations']);
$entity = $query->include(['routes'])->execute(); // or ->get()
$title = $query->getTitle(); // magic call, forwarded to the entity
Parameters
- $filters : array<string|int, mixed> = []
-
filters for the where conditions
- $includes : string|array<string|int, mixed> = []
-
relations to load
['translations', 'routes'], or'*'for all
Return values
SingleQuery<string|int, T>findPublicProfile()
Returns the public profile of another user.
public
findPublicProfile(int $id) : PublicProfile|null
Use it wherever the front end shows a profile of someone other than the signed-in user.
find($id) (inherited from GetTrait) goes to
:Api:System:User:get, which is admin-only and returns the whole entity including
password/salt/email/ip; an anonymous page under internalMode: enforce ends with
an empty Result and a fatal error on render.
It returns the narrow read-only DTO PublicProfile, not User, so personal data
physically never reach the front end (allowlist
UserPresenter::PUBLIC_PROFILE_FIELDS).
Parameters
- $id : int
Return values
PublicProfile|nullfindPublicProfiles()
Returns public profiles in bulk for lists.
public
findPublicProfiles(array<int, int> $ids) : array<int, PublicProfile>
Use it wherever userManager->findAll(['id' => new InFilter('id', $userIds)]) used to be
called: the comment component, the rating component and the discussion list/detail. That
form hits :Api:System:User:getAll, which is admin-only, so under internalMode: enforce
it returned Result::failure and the template fell back to null (silent fail-closed).
Parameters
- $ids : array<int, int>
Return values
array<int, PublicProfile> —key = userId; a user the Api did not return is missing
getAppContext()
public
getAppContext() : AppContext
Return values
AppContextgetLanguageContext()
public
getLanguageContext() : LanguageContext|null
Return values
LanguageContext|nullgetPresenterContext()
public
getPresenterContext() : PresenterContext
Return values
PresenterContextgetSettingContext()
public
getSettingContext() : SettingContext
Return values
SettingContextgetSettings()
public
getSettings() : array<int, array<string, mixed>>
Return values
array<int, array<string, mixed>>getTotalCount()
Returns the total count of the last `findAll()` of this manager's service, computed only when the query asked for it (`findAll(..., computeTotalCount: true)`); otherwise the last stored value.
public
getTotalCount() : int|null
Same value as Query::getTotalCount() of that query.
Return values
int|nullinitializeAllContexts()
public
initializeAllContexts() : void
login()
`$deviceToken` = cookie of a known device, verified by the Api.
public
login(string $username, string $password[, string|null $deviceToken = null ]) : Result
Parameters
- $username : string
- $password : string
- $deviceToken : string|null = null
Return values
ResultloginExternal()
public
loginExternal(string $provider, string $id, string $email, string $firstname, string $lastname[, bool $emailVerified = false ][, string $referralCode = '' ]) : Result
Parameters
- $provider : string
- $id : string
- $email : string
- $firstname : string
- $lastname : string
- $emailVerified : bool = false
- $referralCode : string = ''
Return values
ResultreferralOverview()
Affiliate program for the "My account" page (`:Api:System:User:referralOverview`).
public
referralOverview(int $userId) : Result
Parameters
- $userId : int
Return values
ResultrequestDeletion()
public
requestDeletion(int $userId, string $password) : Result
Parameters
- $userId : int
- $password : string
Return values
ResultresetPassword()
New password from the one-time "lost password" link (e-mail + key).
public
resetPassword(string $email, string $key, string $password) : Result
Parameters
- $email : string
- $key : string
- $password : string
Return values
ResultrevealPhone()
Returns the raw phone of one user, on request.
public
revealPhone(int $id) : string
IMPORTANT: call it only from UserPresenter::handleShowPhone()
(a Nette signal with the automatic same-origin guard), never from render*()/action*():
otherwise the raw phone would get into the regular profile HTML, which
findPublicProfile() and PublicProfile exist to rule out.
Returns '' when the Api refuses (guard, rate limit) or the phone does not exist; the
caller (signal) does not switch the display on '' and keeps the masked value.
Parameters
- $id : int
Return values
stringsave()
public
save(BaseEntity $entity[, array<string, mixed> $meta = [] ]) : Result
Parameters
- $entity : BaseEntity
- $meta : array<string, mixed> = []
Return values
ResultsendActivationEmail()
public
sendActivationEmail(string $username) : Result
Parameters
- $username : string
Return values
ResultsendNewPassword()
Asks the Api to send a new password (replaced `generateNewPassword(int $userId)` called by `LostPasswordFormComponent`).
public
sendNewPassword(string $username) : Result
The front end no longer looks the account up, gets no generated password and sends no
e-mail; all three are done by Api\…\UserManager::sendNewPassword() on the shared data
path (one implementation). The response is constant even for a nonexistent account.
IMPORTANT: the admin password regeneration (:Api:System:User:generateNewPassword,
returns plaintext) stays in the Api layer and the front end deliberately has no bridge to
it; bringing one here would bring back a path on which the password flows back to the browser.
Parameters
- $username : string
Return values
ResultsetAppContext()
public
setAppContext(AppContext $appContext) : $this
Parameters
- $appContext : AppContext
Return values
$thissetCacheTagInvalidator()
public
setCacheTagInvalidator(CacheTagInvalidator $cacheTagInvalidator) : static
Parameters
- $cacheTagInvalidator : CacheTagInvalidator
Return values
staticsetLanguageContext()
public
setLanguageContext(LanguageContext|null $languageContext) : $this
Parameters
- $languageContext : LanguageContext|null
Return values
$thissetParamsConfig()
public
setParamsConfig(Config $paramsConfig) : static
Parameters
- $paramsConfig : Config
Return values
staticsetPresenterContext()
public
setPresenterContext(PresenterContext $presenterContext) : $this
Parameters
- $presenterContext : PresenterContext
Return values
$thissetSettingContext()
public
setSettingContext(SettingContext $settingContext) : $this
Parameters
- $settingContext : SettingContext
Return values
$thisupdateColumn()
public
updateColumn(int|array<string|int, mixed> $entityId, string $property, mixed $value) : Result
Parameters
- $entityId : int|array<string|int, mixed>
-
id, or a list of ids / composite-id arrays
- $property : string
- $value : mixed
Return values
ResultupdateColumns()
public
updateColumns(int|array<string|int, mixed> $entityId, array<string, mixed> $values) : Result
Parameters
- $entityId : int|array<string|int, mixed>
-
id, or a list of ids / composite-id arrays
- $values : array<string, mixed>
-
property name => new value
Return values
ResultupdatePassword()
Own password change; Api verifies `$currentPassword`, revokes the other sessions and returns a fresh `token` + `refreshToken` + `payload` in `data`.
public
updatePassword(int $userId, string $currentPassword, string $password) : Result
Parameters
- $userId : int
- $currentPassword : string
- $password : string
Return values
ResultusernameExists()
The only way for the front end to find out whether a username/e-mail is taken.
public
usernameExists(string $username[, int|null $excludeId = null ]) : bool|null
Use it wherever findBy([new EqualFilter('username', …)]) and a null test used to be
done. That form hits :Api:System:User:getBy, which is admin-only, so under enforce it
returns nothing through FailSoftReadTrait; that was read as "free" and the duplicate
check was dead.
Parameters
- $username : string
- $excludeId : int|null = null
Return values
bool|null —true = taken, false = free, null = could not be determined.
Never turn null into false: that would bring fail-open back; the
caller must treat null as a failed validation.
bumpCacheTags()
Bumps cache tags for the entity after commit: its class, the owned-cascade classes from metadata and the optional `additionalCacheTags()` of the manager.
protected
bumpCacheTags(object $entity) : void
Fail-open (the invalidator swallows exceptions). Called from the manager Save/Delete/Tree traits after the commit.
Parameters
- $entity : object
bumpCacheTagsExplicit()
Bumps the given classes explicitly (raw-DBAL paths with a cross-entity effect).
protected
bumpCacheTagsExplicit(array<string|int, string> $classes) : void
Parameters
- $classes : array<string|int, string>
bumpCacheTagsForClass()
Bumps cache tags by class name when there is no instance (bulk delete, `updateColumns()`, raw DBAL, tree operations).
protected
bumpCacheTagsForClass(class-string $rootClass[, array<string|int, string> $extraTags = [] ]) : void
Bumps the root class and its owned-cascade classes.
Parameters
- $rootClass : class-string
- $extraTags : array<string|int, string> = []
classCacheTags()
Returns extra tags for a bump that has no entity, typically tree operations ({@see \App\Core\Traits\Api\Models\Managers\TreeTrait::treeTransaction()}) that rewrite `lft`/`rgt` on many rows.
protected
classCacheTags() : array<string|int, string>
IMPORTANT: additionalCacheTags(object) receives an entity, so a class-level bump cannot
use it; without this hook a delete would lose the cross-entity tag (Comment to
CommentThread). A manager whose cross-entity tag does not depend on a particular
entity returns it here.
NOTE: unlike additionalCacheTags(), this hook is declared (with an empty default)
instead of being an opt-in through method_exists(); method_exists() is always true in
a manager that has the method, which phpstan reports as alreadyNarrowedType.
Return values
array<string|int, string>getService()
Returns the service for the traits.
protected
getService() : TService