CoolCMS API

UserManager extends Manager
in package
uses SaveTrait

Abstract front manager generic over the entity type and its service.

Tags
extends

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

$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.

$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.

Methods

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
Result

cancelDeletion()

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
Result

confirmDeletion()

Confirmation link of an account without a password.

public confirmDeletion(string $key) : Result
Parameters
$key : string
Return values
Result

Confirms pairing the provider identity from the e-mailed link and signs in.

public confirmExternalLink(string $key) : Result
Parameters
$key : string
Return values
Result

deauthorizeExternal()

public deauthorizeExternal(string $provider, string $externalId) : Result
Parameters
$provider : string
$externalId : string
Return values
Result

emailExists()

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|null

find()

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|null

findPublicProfiles()

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

getSettings()

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|null

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
Result

loginExternal()

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
Result

referralOverview()

Affiliate program for the "My account" page (`:Api:System:User:referralOverview`).

public referralOverview(int $userId) : Result
Parameters
$userId : int
Return values
Result

requestDeletion()

public requestDeletion(int $userId, string $password) : Result
Parameters
$userId : int
$password : string
Return values
Result

resetPassword()

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
Result

revealPhone()

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
string

sendActivationEmail()

public sendActivationEmail(string $username) : Result
Parameters
$username : string
Return values
Result

sendNewPassword()

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
Result

setParamsConfig()

public setParamsConfig(Config $paramsConfig) : static
Parameters
$paramsConfig : Config
Return values
static

updateColumn()

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
Result

updateColumns()

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
Result

updatePassword()

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
Result

usernameExists()

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
Return values
TService
On this page

Search results