PaymentItems
extends BaseComponent
in package
uses
ModalAwareTrait, PrivilegeGuardTrait, OwnerContextGuardTrait
Admin management of the payments (topping) of one discussion message ({@see PaymentItem}).
Keyed by messageId; rendered in the "Payments" tab of the message edit form via
{control paymentItems $messageId}, next to the comment and rating tabs. The list is a flat
table. Adding and editing run in the shared admin
ModalWindow: a signal renders
_modal.latte to a string, fills the modal and opens it from PHP (showModal()). The
form submits via AJAX, the modal stays open for the confirmation and {snippet itemList}
is redrawn.
messageId travels in a hidden field, not a persistent parameter, because the form's
link('this') does not carry it; without the field an insert would get messageId 0.
Saving goes through the Admin PaymentItemManager and ApiBridge to the Api manager.
The save sends the meta recalcTopedUntil, so the Api afterSave sets the message's
toped_until absolutely (it can shorten it, or set null when deactivating, shortening the
validity or removing the last active item). Front and gateway paths stay monotonic (extend only).
Table of Contents
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
- $adding : bool
- Whether a new payment is being added (modal with an empty form).
- $editId : int|null
- Edited item, set by `handleEdit()` or the submit for the modal re-render (null when adding).
- $justSaved : bool
- Whether the payment was just saved; the modal then shows the confirmation instead of the form.
- $messageId : int
- Message whose payments the component manages. Not a persistent parameter: it is passed explicitly in every signal (`{link add! messageId => …}`) and into the submit through the hidden `messageId` field.
- $ownerContextProvider : callable(): mixed|null
- $paymentItemManager : PaymentItemManager
- $tariffManager : TariffManager
Methods
- __call() : mixed
- Dispatches `renderXyz()` to `render('Xyz', ...$args)`.
- __construct() : mixed
- createComponent() : IComponent|null
- createComponentPaymentForm() : Form
- 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
- handleAdd() : void
- Opens the shared modal for adding a payment.
- handleDelete() : void
- Hard-deletes a payment item (the entity has no `deleted` flag).
- handleEdit() : void
- Opens the shared modal for editing a payment.
- hasServiceByType() : bool
- Returns whether the container has a service of the given type.
- initializeAllContexts() : void
- injectDeviceDetector() : void
- onCreate() : void
- onPaymentFormError() : void
- Redraws the modal body with errors after a failed validation (missing tariff, expired CSRF).
- onPaymentFormSuccess() : void
- render() : void
- setAppContext() : $this
- setComponentParameter() : void
- Sets a component parameter.
- setCurrencyContext() : $this
- setLanguageContext() : $this
- setLocalizationContext() : $this
- setOwnerContext() : static
- Sets the host callback returning the id of the owner currently being edited (advert or post).
- setSettingContext() : $this
- setThemeContext() : $this
- setup() : void
- setupAppContext() : void
- typedComponent() : T
- Returns a subcomponent with a verified type.
- contextOwnerId() : int|null
- Owner id from the host context; null when the host edits nothing (fail-closed).
- frontPresenter() : BasePresenter|null
- Returns the front presenter the component is attached to (null outside the front end or when detached).
- getModalWindow() : ModalWindow
- getTranslator() : ITranslator
- isTargetAllowed() : bool
- Returns whether the logged-in user may open the given admin target. For visibility (tiles, autocomplete, buttons); it does not throw.
- requireContextOwner() : int
- Signal gate: an owner id from a hand-built URL is usable only when it equals the host context; otherwise 403.
- requirePrivilege() : void
- Throws 403 when the logged-in user lacks the given admin privilege.
- resolvePageTarget() : string|null
- Returns the RBAC key of the target page: `<presenter>:<action>`, e.g. `:Admin:System:User:show`.
- setTemplateFile() : void
- setTranslator() : self
- submittedOwnerId() : int|null
- Owner for a form submit: the host context, or null when it is missing or the posted hidden id differs from it (a forged form of another record).
- 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).
- findItem() : PaymentItem|null
- Returns one item by id (for the edit prefill, the managed update on submit and the delete), only within the edited message. A foreign item or a missing host context counts as not found.
- loadItems() : array<int, PaymentItem>
- Returns the message's payments ordered by insert time, newest first.
- renderModalContent() : string
- Renders the modal content (form or confirmation) to a string for `ModalWindow`.
- showModal() : void
- Fills and opens the shared admin `ModalWindow` with the current state (form or confirmation).
- tariffOptions() : array<int, NotTranslate>
- Returns a map of `tariffId` to tariff name (current language, falling back to the first non-empty name) for the select and the list. All tariffs are loaded at once (there are few).
- tr() : NotTranslate
- Translates a key in the component domain and wraps it in `NotTranslate`.
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.discussion.components.paymentItems'
$adding
Whether a new payment is being added (modal with an empty form).
private
bool
$adding
= false
$editId
Edited item, set by `handleEdit()` or the submit for the modal re-render (null when adding).
private
int|null
$editId
= null
$justSaved
Whether the payment was just saved; the modal then shows the confirmation instead of the form.
private
bool
$justSaved
= false
$messageId
Message whose payments the component manages. Not a persistent parameter: it is passed explicitly in every signal (`{link add! messageId => …}`) and into the submit through the hidden `messageId` field.
private
int
$messageId
= 0
$ownerContextProvider
private
callable(): mixed|null
$ownerContextProvider
= null
$paymentItemManager read-only
private
PaymentItemManager
$paymentItemManager
$tariffManager read-only
private
TariffManager
$tariffManager
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(PaymentItemManager $paymentItemManager, TariffManager $tariffManager) : mixed
Parameters
- $paymentItemManager : PaymentItemManager
- $tariffManager : TariffManager
createComponent()
public
createComponent(string $name) : IComponent|null
Parameters
- $name : string
Return values
IComponent|nullcreateComponentPaymentForm()
public
createComponentPaymentForm() : Form
Return values
FormgetAppContext()
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|nullhandleAdd()
Opens the shared modal for adding a payment.
public
handleAdd(int $messageId) : void
Parameters
- $messageId : int
handleDelete()
Hard-deletes a payment item (the entity has no `deleted` flag).
public
handleDelete(int $messageId, int $id) : void
The link is not AJAX because the styled data-grid-confirm does not work with Naja .ajax,
so the handler redirects back to the edit page; the browser keeps the #msg-tab-payments
fragment across the 302 and the Payments tab stays open.
NOTE: after the delete, the Api PaymentItemManager::delete() recalculates the
message's toped_until absolutely, downwards
(PaymentItemManager::recalcTopedUntilForMessages(); a deleted active item no
longer tops, and with no active items it becomes null). Delete and recalculation run
atomically in one transaction; gateway and front paths stay monotonic.
Parameters
- $messageId : int
- $id : int
Attributes
- #[Requires]
- $methods: 'POST'
handleEdit()
Opens the shared modal for editing a payment.
public
handleEdit(int $messageId, int $id) : void
Parameters
- $messageId : int
- $id : int
hasServiceByType()
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
onPaymentFormError()
Redraws the modal body with errors after a failed validation (missing tariff, expired CSRF).
public
onPaymentFormError(Form $form) : void
Parameters
- $form : Form
onPaymentFormSuccess()
public
onPaymentFormSuccess(Form $form, ArrayHash<string|int, mixed> $values) : void
Parameters
- $form : Form
- $values : ArrayHash<string|int, mixed>
render()
public
render([int|null $messageId = null ]) : void
Parameters
- $messageId : int|null = null
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
$thissetOwnerContext()
Sets the host callback returning the id of the owner currently being edited (advert or post).
public
setOwnerContext(callable(): mixed $provider) : static
It is called on every use, so a value from an earlier request never lingers.
Parameters
- $provider : callable(): mixed
Return values
staticsetSettingContext()
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
TcontextOwnerId()
Owner id from the host context; null when the host edits nothing (fail-closed).
protected
contextOwnerId() : int|null
Return values
int|nullfrontPresenter()
Returns the front presenter the component is attached to (null outside the front end or when detached).
protected
frontPresenter() : BasePresenter|null
Return values
BasePresenter|nullgetModalWindow()
protected
getModalWindow() : ModalWindow
Return values
ModalWindowgetTranslator()
protected
getTranslator() : ITranslator
Return values
ITranslatorisTargetAllowed()
Returns whether the logged-in user may open the given admin target. For visibility (tiles, autocomplete, buttons); it does not throw.
protected
isTargetAllowed(string|null $key) : bool
IMPORTANT: fail-closed like requirePrivilege(): an empty key and a presenter
without isAllowed() both mean no. A component that skips this question lists the
target to everyone.
Parameters
- $key : string|null
Return values
boolrequireContextOwner()
Signal gate: an owner id from a hand-built URL is usable only when it equals the host context; otherwise 403.
protected
requireContextOwner(int $ownerId) : int
Parameters
- $ownerId : int
Return values
intrequirePrivilege()
Throws 403 when the logged-in user lacks the given admin privilege.
protected
requirePrivilege(string $key) : void
Call it as the first statement of a mutating signal, before loading data, so the check cannot be bypassed by something being written first.
Parameters
- $key : string
resolvePageTarget()
Returns the RBAC key of the target page: `<presenter>:<action>`, e.g. `:Admin:System:User:show`.
protected
static resolvePageTarget(object|null $page) : string|null
Same interpretation as Menu::filterByPrivileges(), BasePresenter::authorizeListing() and PrivilegeCheckTrait::checkCurrentPrivilege(). The key is derived from the page target only, never from a file or class name.
Returns null when the page is missing or has no presenter, so there is nothing to allow.
Parameters
- $page : object|null
-
AdminPageentity (hydrated, hence justobject)
Return values
string|nullsetTemplateFile()
protected
setTemplateFile(string $dir, string $filename) : void
Parameters
- $dir : string
- $filename : string
setTranslator()
protected
setTranslator(ITranslator $translator) : self
Parameters
- $translator : ITranslator
Return values
selfsubmittedOwnerId()
Owner for a form submit: the host context, or null when it is missing or the posted hidden id differs from it (a forged form of another record).
protected
submittedOwnerId(mixed $postedOwnerId) : int|null
Parameters
- $postedOwnerId : mixed
Return values
int|nullcreateMultiplierComponent()
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|nullfindItem()
Returns one item by id (for the edit prefill, the managed update on submit and the delete), only within the edited message. A foreign item or a missing host context counts as not found.
private
findItem(int $id) : PaymentItem|null
Parameters
- $id : int
Return values
PaymentItem|nullloadItems()
Returns the message's payments ordered by insert time, newest first.
private
loadItems() : array<int, PaymentItem>
Return values
array<int, PaymentItem>renderModalContent()
Renders the modal content (form or confirmation) to a string for `ModalWindow`.
private
renderModalContent() : string
Return values
stringshowModal()
Fills and opens the shared admin `ModalWindow` with the current state (form or confirmation).
private
showModal() : void
Idempotent: it is called again after the submit and redraws only the body.
tariffOptions()
Returns a map of `tariffId` to tariff name (current language, falling back to the first non-empty name) for the select and the list. All tariffs are loaded at once (there are few).
private
tariffOptions() : array<int, NotTranslate>
Return values
array<int, NotTranslate>tr()
Translates a key in the component domain and wraps it in `NotTranslate`.
private
tr(string $key) : NotTranslate
IMPORTANT: the result goes to setPrompt() / setRequired() on a field with
setTranslator(null). The prompt and items respect the per-control override, but Nette
getLabel() and Validator::formatMessage() always take the translator from the form.
Without NotTranslate the finished text would be translated again as a key and Tracy
would report a missing translation.
Parameters
- $key : string