DashboardAttention
extends BaseComponent
in package
Dashboard band of cards for what waits for action in the admin.
A card exists only when its count is nonzero; the empty state is one "nothing waits" sentence. Rules:
- Zero counts are not shown (a row of ten zero cards looks like a broken page).
- Nothing is counted that the user cannot see:
isAllowed()is asked before counting, not in the template, so no query runs for a user without the list privilege. - A link leads to where there is something to do: when the grid has a matching search column,
the filter is passed via
grid-filters.
Each card costs one count query plus one single-row select (limit: 1, computeTotalCount: true).
Counts are deliberately not cached: a stale value on a to-do counter is worse than an extra query.
The admin layer does not touch Api or Front, so payment states are a local copy of
App\UI\Api\System\Enums\PaymentStatus in PAYMENT_STATUS_START; when the code list
changes, change it here too.
Table of Contents
Constants
- KEY_STATE_EXPIRED : mixed = 'expired'
- KEY_STATE_EXPIRING : mixed = 'expiring'
- Application key states as returned by the Api in `keys[].state`.
- PAYMENT_STATUS_START : mixed = 2
- Payment in the "started" state: the customer left for the gateway and never came back.
- STUCK_PAYMENT_HOURS : mixed = 1
- Hours in the "started" state after which a payment counts as stuck. A card payment finishes within a minute and a bank transfer within two days, so one hour is a safe threshold that does not catch normal traffic.
Properties
- $container : Container
- $routerDispatcher : RouterDispatcher
- $translator : ITranslator
- $appContext : AppContext
- $componentParameters : array<string, mixed>
- $currencyContext : CurrencyContext|null
- $deviceDetector : DeviceDetector|null
- $languageContext : LanguageContext|null
- $localizationContext : LocalizationContext|null
- $settingContext : SettingContext
- $themeContext : ThemeContext|null
- $translatorDomain : string|null
- $apiClientManager : ApiClientManager
-
$apiOverview
: array{clients: list
>, defaultLimits: array }|null|false - Overview of applications with Api access, loaded once for both key cards.
- $bazaarAdvertManager : AdvertManager
- $bazaarResponseManager : ResponseManager
- $comcatAdvertManager : AdvertManager
- $comcatResponseManager : ResponseManager
- $commentManager : CommentManager
- $complaintManager : ComplaintManager
- $emailQueueManager : EmailQueueManager
- $invoiceManager : InvoiceManager
- $orderManager : OrderManager
- $paymentManager : PaymentManager
- $ratingManager : RatingManager
Methods
- __call() : mixed
- Dispatches `renderXyz()` to `render('Xyz', ...$args)`.
- __construct() : mixed
- countKeysInState() : int
- Counts keys in state `$state` of clients that are not revoked. The key state (`active`/`expiring`/`expired`/`revoked`) is computed by the Api; the "soon" threshold lives only there (`Api\ApiClientManager::EXPIRING_SOON_DAYS`) and is not duplicated here.
- createComponent() : IComponent|null
- getAppContext() : AppContext
- getComponentParameter() : mixed
- Returns a component parameter, or null when it is not set.
- getContainer() : Container
- getCurrencyContext() : CurrencyContext|null
- getLanguageContext() : LanguageContext|null
- getLocalizationContext() : LocalizationContext|null
- getRouterDispatcher() : RouterDispatcher
- getSettingContext() : SettingContext
- getSettings() : array<int, array<string, mixed>>
- getThemeContext() : ThemeContext|null
- hasServiceByType() : bool
- Returns whether the container has a service of the given type.
- initializeAllContexts() : void
- injectDeviceDetector() : void
- onCreate() : void
- render() : void
- setAppContext() : $this
- setComponentParameter() : void
- Sets a component parameter.
- setCurrencyContext() : $this
- setLanguageContext() : $this
- setLocalizationContext() : $this
- setSettingContext() : $this
- setThemeContext() : $this
- setup() : void
- setupAppContext() : void
- typedComponent() : T
- Returns a subcomponent with a verified type.
- frontPresenter() : BasePresenter|null
- Returns the front presenter the component is attached to (null outside the front end or when detached).
- getTranslator() : ITranslator
- setTemplateFile() : void
- setTranslator() : self
- buildHref() : string|null
- Returns the link to the target list, or `null` when the target does not exist in this installation.
- collectCards() : array<int, array{key: string, icon: string, count: int, href: string, tone: string}>
- Cards with a nonzero count in order of urgency: money and customer first, cleanup last.
- countApiKeys() : int
- Returns the number of application keys in the given state; on an Api read failure returns 0 and logs.
- countBy() : int
- Counts records matching the filters.
- createMultiplierComponent() : Multiplier<string|int, IComponent>
- Creates a multiplier for the component.
- createNewComponentInstance() : IComponent|null
- Creates a new component instance without adding it to the presenter; used by the multiplier.
- createStandardComponent() : IComponent|null
- Creates a standard component (not a multiplier).
-
definitions()
: array<int, array{key: string, privilege: string, icon: string, tone: string, destination: string, params: array
, count: callable}> - Card definitions. Array order is page order.
- isAllowedDestination() : bool
- Whether the user may open the target list. Read from the array loaded in the presenter's `startup()`, no extra query.
- logDashboardFailure() : void
- A failure of one card is logged and the rest continues. Without the log a query error would show only as a vanished card, indistinguishable from "nothing to do".
- pluralLabel() : string
- Returns the card label in the right plural form for the count.
Constants
KEY_STATE_EXPIRED
private
mixed
KEY_STATE_EXPIRED
= 'expired'
KEY_STATE_EXPIRING
Application key states as returned by the Api in `keys[].state`.
private
mixed
KEY_STATE_EXPIRING
= 'expiring'
PAYMENT_STATUS_START
Payment in the "started" state: the customer left for the gateway and never came back.
private
mixed
PAYMENT_STATUS_START
= 2
Matches App\UI\Api\System\Enums\PaymentStatus::START.
STUCK_PAYMENT_HOURS
Hours in the "started" state after which a payment counts as stuck. A card payment finishes within a minute and a bank transfer within two days, so one hour is a safe threshold that does not catch normal traffic.
private
mixed
STUCK_PAYMENT_HOURS
= 1
Properties
$container
public
Container
$container
Attributes
- #[Inject]
$routerDispatcher
public
RouterDispatcher
$routerDispatcher
$translator
public
ITranslator
$translator
Tags
$appContext
protected
AppContext
$appContext
$componentParameters
protected
array<string, mixed>
$componentParameters
= []
component parameters set by setComponentParameter()
$currencyContext
protected
CurrencyContext|null
$currencyContext
= NULL
$deviceDetector
protected
DeviceDetector|null
$deviceDetector
= NULL
$languageContext
protected
LanguageContext|null
$languageContext
= NULL
$localizationContext
protected
LocalizationContext|null
$localizationContext
= NULL
$settingContext
protected
SettingContext
$settingContext
$themeContext
protected
ThemeContext|null
$themeContext
= NULL
$translatorDomain
protected
string|null
$translatorDomain
= 'admin.system.components.dashboardAttention'
$apiClientManager read-only
private
ApiClientManager
$apiClientManager
$apiOverview
Overview of applications with Api access, loaded once for both key cards.
private
array{clients: list>, defaultLimits: array}|null|false
$apiOverview
= false
false means not loaded yet (null is a valid value: the Api returned no data).
$bazaarAdvertManager read-only
private
AdvertManager
$bazaarAdvertManager
$bazaarResponseManager read-only
private
ResponseManager
$bazaarResponseManager
$comcatAdvertManager read-only
private
AdvertManager
$comcatAdvertManager
$comcatResponseManager read-only
private
ResponseManager
$comcatResponseManager
$commentManager read-only
private
CommentManager
$commentManager
$complaintManager read-only
private
ComplaintManager
$complaintManager
$emailQueueManager read-only
private
EmailQueueManager
$emailQueueManager
$invoiceManager read-only
private
InvoiceManager
$invoiceManager
$orderManager read-only
private
OrderManager
$orderManager
$paymentManager read-only
private
PaymentManager
$paymentManager
$ratingManager read-only
private
RatingManager
$ratingManager
Methods
__call()
Dispatches `renderXyz()` to `render('Xyz', ...$args)`.
public
__call(string $name, array<string|int, mixed> $args) : mixed
Called only when the component has no renderXyz() method of its own.
Parameters
- $name : string
- $args : array<string|int, mixed>
__construct()
public
__construct(OrderManager $orderManager, ComplaintManager $complaintManager, InvoiceManager $invoiceManager, PaymentManager $paymentManager, AdvertManager $bazaarAdvertManager, ResponseManager $bazaarResponseManager, AdvertManager $comcatAdvertManager, ResponseManager $comcatResponseManager, CommentManager $commentManager, RatingManager $ratingManager, EmailQueueManager $emailQueueManager, ApiClientManager $apiClientManager) : mixed
Parameters
- $orderManager : OrderManager
- $complaintManager : ComplaintManager
- $invoiceManager : InvoiceManager
- $paymentManager : PaymentManager
- $bazaarAdvertManager : AdvertManager
- $bazaarResponseManager : ResponseManager
- $comcatAdvertManager : AdvertManager
- $comcatResponseManager : ResponseManager
- $commentManager : CommentManager
- $ratingManager : RatingManager
- $emailQueueManager : EmailQueueManager
- $apiClientManager : ApiClientManager
countKeysInState()
Counts keys in state `$state` of clients that are not revoked. The key state (`active`/`expiring`/`expired`/`revoked`) is computed by the Api; the "soon" threshold lives only there (`Api\ApiClientManager::EXPIRING_SOON_DAYS`) and is not duplicated here.
public
static countKeysInState(array<int, array<string, mixed>> $clients, string $state) : int
Parameters
- $clients : array<int, array<string, mixed>>
-
rows from the Api overview
- $state : string
Return values
intcreateComponent()
public
createComponent(string $name) : IComponent|null
Parameters
- $name : string
Return values
IComponent|nullgetAppContext()
public
getAppContext() : AppContext
Return values
AppContextgetComponentParameter()
Returns a component parameter, or null when it is not set.
public
getComponentParameter(string $name) : mixed
Parameters
- $name : string
getContainer()
public
getContainer() : Container
Return values
ContainergetCurrencyContext()
public
getCurrencyContext() : CurrencyContext|null
Return values
CurrencyContext|nullgetLanguageContext()
public
getLanguageContext() : LanguageContext|null
Return values
LanguageContext|nullgetLocalizationContext()
public
getLocalizationContext() : LocalizationContext|null
Return values
LocalizationContext|nullgetRouterDispatcher()
public
getRouterDispatcher() : RouterDispatcher
Return values
RouterDispatchergetSettingContext()
public
getSettingContext() : SettingContext
Return values
SettingContextgetSettings()
public
getSettings() : array<int, array<string, mixed>>
Return values
array<int, array<string, mixed>>getThemeContext()
public
getThemeContext() : ThemeContext|null
Return values
ThemeContext|nullhasServiceByType()
Returns whether the container has a service of the given type.
public
hasServiceByType(string $className) : bool
The name is composed dynamically (module plus component), so class_exists() runs first, and
a true result guarantees a valid type.
Parameters
- $className : string
Tags
Return values
boolinitializeAllContexts()
public
initializeAllContexts() : void
injectDeviceDetector()
public
injectDeviceDetector(DeviceDetector $detector) : void
Parameters
- $detector : DeviceDetector
onCreate()
public
onCreate() : void
render()
public
render() : void
setAppContext()
public
setAppContext(AppContext $appContext) : $this
Parameters
- $appContext : AppContext
Return values
$thissetComponentParameter()
Sets a component parameter.
public
setComponentParameter(string $name, mixed $value) : void
Parameters
- $name : string
- $value : mixed
setCurrencyContext()
public
setCurrencyContext(CurrencyContext|null $currencyContext) : $this
Parameters
- $currencyContext : CurrencyContext|null
Return values
$thissetLanguageContext()
public
setLanguageContext(LanguageContext|null $languageContext) : $this
Parameters
- $languageContext : LanguageContext|null
Return values
$thissetLocalizationContext()
public
setLocalizationContext(LocalizationContext|null $localizationContext) : $this
Parameters
- $localizationContext : LocalizationContext|null
Return values
$thissetSettingContext()
public
setSettingContext(SettingContext $settingContext) : $this
Parameters
- $settingContext : SettingContext
Return values
$thissetThemeContext()
public
setThemeContext(ThemeContext|null $themeContext) : $this
Parameters
- $themeContext : ThemeContext|null
Return values
$thissetup()
public
setup(BasePresenter|BasePresenter $presenter) : void
Parameters
- $presenter : BasePresenter|BasePresenter
setupAppContext()
public
setupAppContext(AppContext $appContext) : void
Parameters
- $appContext : AppContext
typedComponent()
Returns a subcomponent with a verified type.
public
typedComponent(string $name, T> $type) : T
Use it instead of an inline @var above $this['x'] (which does not narrow the type) and
instead of the generic IComponent that $this['x'] returns. See
Form::typedComponent().
Parameters
- $name : string
- $type : T>
Tags
Return values
TfrontPresenter()
Returns the front presenter the component is attached to (null outside the front end or when detached).
protected
frontPresenter() : BasePresenter|null
Return values
BasePresenter|nullgetTranslator()
protected
getTranslator() : ITranslator
Return values
ITranslatorsetTemplateFile()
protected
setTemplateFile(string $dir, string $filename) : void
Parameters
- $dir : string
- $filename : string
setTranslator()
protected
setTranslator(ITranslator $translator) : self
Parameters
- $translator : ITranslator
Return values
selfbuildHref()
Returns the link to the target list, or `null` when the target does not exist in this installation.
private
buildHref(string $destination, array<string, mixed> $params) : string|null
Not every project has all modules; a link to a missing presenter would break the whole dashboard
with InvalidLinkException, so the card is dropped.
Parameters
- $destination : string
- $params : array<string, mixed>
Return values
string|nullcollectCards()
Cards with a nonzero count in order of urgency: money and customer first, cleanup last.
private
collectCards() : array<int, array{key: string, icon: string, count: int, href: string, tone: string}>
Return values
array<int, array{key: string, icon: string, count: int, href: string, tone: string}>countApiKeys()
Returns the number of application keys in the given state; on an Api read failure returns 0 and logs.
private
countApiKeys(string $state) : int
Parameters
- $state : string
Return values
intcountBy()
Counts records matching the filters.
private
countBy(Manager $manager, array<int, object> $filters) : int
limit: 1: getTotalCount() runs execute() internally, so without a limit the whole table
would be loaded for one number.
An error (missing module, renamed column) is swallowed to zero: the dashboard must not break admin entry because of a supplementary card. A missing card behaves the same as a zero count.
Parameters
- $manager : Manager
- $filters : array<int, object>
Return values
intcreateMultiplierComponent()
Creates a multiplier for the component.
private
createMultiplierComponent(string $name) : Multiplier<string|int, IComponent>
Parameters
- $name : string
Return values
Multiplier<string|int, IComponent>createNewComponentInstance()
Creates a new component instance without adding it to the presenter; used by the multiplier.
private
createNewComponentInstance(string $baseName[, int|string|null $uniqueKey = null ]) : IComponent|null
Parameters
- $baseName : string
- $uniqueKey : int|string|null = null
Return values
IComponent|nullcreateStandardComponent()
Creates a standard component (not a multiplier).
private
createStandardComponent(string $name) : IComponent|null
Parameters
- $name : string
Return values
IComponent|nulldefinitions()
Card definitions. Array order is page order.
private
definitions() : array<int, array{key: string, privilege: string, icon: string, tone: string, destination: string, params: array, count: callable}>
tone sets the color by what the card means:
urgent— someone waits for money or goods,review— waits for an admin decision,notice— operational notice, can wait until tomorrow.
Return values
array<int, array{key: string, privilege: string, icon: string, tone: string, destination: string, params: arrayisAllowedDestination()
Whether the user may open the target list. Read from the array loaded in the presenter's `startup()`, no extra query.
private
isAllowedDestination(string $privilege) : bool
Fail-closed: a presenter without isAllowed() (theoretically another context) hides the card
instead of exposing the count.
Parameters
- $privilege : string
Return values
boollogDashboardFailure()
A failure of one card is logged and the rest continues. Without the log a query error would show only as a vanished card, indistinguishable from "nothing to do".
private
logDashboardFailure(Throwable $e) : void
Parameters
- $e : Throwable
pluralLabel()
Returns the card label in the right plural form for the count.
private
pluralLabel(string $key, int $count) : string
The label needs several plural forms (one / few / many) and a wrong form makes the page look
unfinished. The translation holds the forms in Symfony notation ({1} … |[2,4] … |]4,Inf[ …),
the translator picks by the second argument.
Translated in PHP, not in the template: in Latte the count would have to be passed through {_}
and the notation would become unreadable.
Parameters
- $key : string
- $count : int