KMP PHP API Reference

MembersController extends AppController
in package
uses QueuedMailerAwareTrait, MailerAwareTrait, DataverseGridTrait, WorkflowDispatchTrait

Manages member CRUD, authentication, profiles, and member discovery.

Handles login/logout, password reset, registration, member search, mobile card display, and verification workflows. Uses DataverseGridTrait for index listing with server-side filtering.

Table of Contents

Constants

MOBILE_QUEUE_DEFAULT_PER_PAGE  : int = 25
MOBILE_QUEUE_MAX_PER_PAGE  : int = 50
VIEW_DATA_EVENT  : string = 'KMP.plugins.callForViewData'
VIEW_PLUGIN_EVENT  : string = 'KMP.plugins.callForViewCells'
MEMBERSHIP_CARD_REUPLOAD_CONTACT_EMAIL  : mixed = 'amp-secretary@webminister.ansteorra.org'
PROFILE_PHOTO_CACHE_CONTROL  : mixed = 'private, max-age=3600, must-revalidate'
QUICK_LOGIN_LOCKOUT_SECONDS  : mixed = 300
Quick PIN lockout window in seconds.
QUICK_LOGIN_MAX_PIN_ATTEMPTS  : mixed = 5
Maximum failed quick PIN attempts before temporary lockout.
QUICK_LOGIN_SETUP_SESSION_KEY  : mixed = 'QuickLoginSetup'
Session key for deferred quick-login PIN setup.

Properties

$inject  : array<string|int, string>
$Members  : MembersTable
$csvExportService  : CsvExportService
$isCsvRequest  : bool
$mailer  : Mailer
$pluginViewCells  : array<string|int, mixed>
$pluginViewCellsEnabledForFragment  : bool
Whether an intentionally fragment-style response still needs plugin view cells.
$quickLoginDisabledEmailForRequest  : string
Request-scoped email used to prefill password login after quick-login reset.
$quickLoginDisabledForRequest  : bool
Request-scoped flag to instruct login UI to clear stale quick-login config.

Methods

add()  : Response|null|void
Create new member with age-based status and email notifications.
autoComplete()  : mixed
Auto complete.
beforeFilter()  : void
Configure authorization and authentication filters.
beforeRender()  : Response|null|void
Finalize view-only data after the action has run.
changePassword()  : mixed
Change password.
delete()  : Response|null
Delete method
edit()  : Response|null|void
Edit method
editAdditionalInfo()  : mixed
Edit additional info.
emailTaken()  : mixed
Email taken.
forgotPassword()  : mixed
Forgot password.
gatheringsGridData()  : Response|null|void
Gathering attendances grid data for Gatherings tab in member profile.
gridData()  : Response|null|void
Dataverse grid data endpoint for members listing.
impersonate()  : Response|null
Begin impersonating another member (super user only).
importExpirationDates()  : Response|null
Import membership or background-check expiration dates from CSV.
index()  : Response|null|void
Display member listing with Dataverse grid (saved views, filters, sorting).
initialize()  : void
Load shared components: Authentication, Authorization, Flash.
isCsvRequest()  : bool
Check if current request is for CSV export.
login()  : mixed
login logic
logout()  : mixed
Logout.
membershipCard()  : Response
Stream a membership verification card after verifier authorization.
mobileCardPhoto()  : Response
Stream the authenticated member's mobile profile photo.
mobileCardUploadProfilePhoto()  : Response
Upload a profile photo from the mobile card flow.
partialEdit()  : mixed
Partial edit.
profile()  : Response|null|void
Profile method
profilePhoto()  : Response
Stream a member profile photo document inline.
publicProfile()  : mixed
Public profile.
register()  : mixed
Register.
removeProfilePhoto()  : Response
Remove a member profile photo and underlying document atomically.
removeQuickLoginDevice()  : Response
Remove an enrolled quick-login device.
requestMembershipCardReupload()  : Response|null
Remove an unreadable membership card and request a replacement from the member.
resetPassword()  : mixed
Reset password.
revokeSessions()  : mixed
Revoke all sessions and PIN devices using the existing password-management permission.
rolesGridData()  : Response|null|void
Member roles grid data for Roles tab in member profile.
searchMembers()  : mixed
Search members.
security()  : Response|null
Render member-authorized security actions in the shared dialog.
sendMobileCardEmail()  : mixed
Send mobile card email.
setupQuickLoginPin()  : Response|null|void
Collect and save a quick-login PIN after a successful password login.
stopImpersonating()  : Response|null
Stop impersonating and restore original super user identity.
submitScaMemberInfo()  : mixed
Submit sca member info.
subRow()  : void
Return sub-row content for expandable grid rows.
switchView()  : Response
Switch between mobile and desktop view modes.
uploadProfilePhoto()  : Response
Upload and assign a member profile photo.
verifyMembership()  : mixed
Verify membership.
verifyQueue()  : Response|null|void
Display member verification queue for administrative processing.
verifyQueueGridData()  : Response|null|void
Dataverse grid data endpoint for verification queue.
view()  : Response|null|void
Display detailed member profile with relationships and management tools.
viewCard()  : mixed
View card.
viewCardJson()  : mixed
View card json.
viewMobileCard()  : mixed
View mobile card.
viewMobileCardJson()  : mixed
View mobile card json.
_addRolesSelectAndContain()  : mixed
Internal: add roles select and contain.
applyCustomFilterHandlers()  : SelectQuery
Apply custom filter handlers for columns with complex filtering logic
applyVerifyQueueBaseFilter()  : SelectQuery
Apply base filter for verification queue (all items needing verification)
appSettingImageDataUri()  : string|null
Resolve shared tenant branding for the online and cached mobile templates.
assertSafeContextUrl()  : string
Ensure URL is same-origin relative path + query only.
authorizeCurrentUrl()  : void
Authorize the current URL/action via Authorization component.
buildDataverseGridSearchCondition()  : array<string, mixed>|null
Build a search condition for one Dataverse grid column.
buildDataverseGridState()  : array<string|int, mixed>
Build complete grid state object (single source of truth)
buildExportDataFromEntities()  : array<string|int, mixed>
Build export data from pre-processed entities (Data Mode)
buildExportDataFromQuery()  : array<string|int, mixed>
Build export data from database query (Query Mode)
buildGridDataUrlFromPageContext()  : string
Build grid-data URL preserving query string from page context.
consumeFlashForStream()  : array<string, mixed>
Read flash from session and clear it for stream rendering.
convertDateBoundaryToUtc()  : string
Convert a date boundary string from kingdom timezone to UTC for SQL comparison.
dispatchWorkflowEvent()  : void
Fire a workflow event without fallback. Silently logs on failure.
dispatchWorkflowOrFail()  : array<int, mixed>
Dispatch to the workflow engine and fail when no active definition is available.
enablePluginViewCellsForFragment()  : void
Include route-matched plugin cells in an AJAX or other fragment response.
extractContextValue()  : mixed
Extract a matching value from the workflow context or its nested payload arrays.
extractExportValue()  : string
Extract export value from entity using column metadata
extractFilterFromExpression()  : mixed
Recursively extract a filter value from an expression tree
extractFilterFromSystemView()  : mixed
Extract a specific filter value from a system view configuration
extractFilterFromViewConfig()  : mixed
Extract a specific filter value from a saved user view's config
extractFilterGrouping()  : array<string|int, mixed>
Extract filter grouping information from expression tree
extractLockedDateRangeDefaults()  : array<string, array{value: string|null, operator: string}>
Extract canonical bounds for active date-range filters whose fields are locked.
extractNumericContextValue()  : int|null
Extract a numeric value from top-level or nested workflow context arrays.
extractStringContextValue()  : string|null
Extract a string value from top-level or nested workflow context arrays.
extractSystemViewDefaults()  : array{filters: array, dateRange: array, dateRangeOperators: array, search: ?string, skipFilterColumns: array}
Extract default filters/search metadata for a system view configuration
formatExportValue()  : string
Format value for CSV export
getPageContextUrl()  : string|null
Posted page context URL (path + query), validated.
getVerifyQueueSystemViewCounts()  : array<string, int>
Get record counts for each verify queue system view.
handleCsvExport()  : Response
Handle CSV export from grid result
isCsvExportRequest()  : bool
Check if the current request is for CSV export
isDataverseTableFrameRequest()  : bool
isGridOriginRequest()  : bool
Whether POST originated from a grid index (stay on list).
loadAvailableViews()  : array<int, mixed>
Load and cache available views for the current request.
loadFilterOptions()  : array<string|int, mixed>
Load filter options from a data source
loadFilterOptionsCached()  : array<int, array{value: string, label: string}>
Load filter options with per-request cache.
matchesGridIndexPath()  : bool
Whether page context path matches a grid index route pattern.
mobileQueuePagination()  : array<string, int|bool>
Build shared pagination values for mobile actionable queues.
mobileQueuePaginationPayload()  : array<string, int|bool>
Remove internal pagination values before sending the mobile JSON payload.
organizeViewCells()  : array<string|int, mixed>
Organize view cells by type and display order.
processDataverseGrid()  : array<string|int, mixed>
Process dataverse grid request with unified logic
queueMail()  : Mailer
Returns a mailer instance.
queueMailJob()  : void
Queues a mail job to be processed later.
renderDataverseGridResponse()  : void
Render consistent dataverse grid responses for outer/table turbo frames.
renderDataverseTableRowElement()  : string
Render a single Dataverse grid row element (Turbo Stream replace target HTML).
renderTurboCloseModal()  : Response
Render turbo-stream: flash + replace table frame with lazy reload src.
renderTurboFlashOnly()  : Response
Render turbo-stream flash messages without forcing a grid or frame reload.
renderTurboReloadFrame()  : Response
Stream that reloads an edit turbo-frame (validation errors).
renderTurboRemoveGridRow()  : Response
Render turbo-stream: flash + remove a grid row (no longer matches current filters).
renderTurboReplaceGridRow()  : Response
Render turbo-stream: flash + replace a single grid row by DOM id.
resolveBranchIdFromContextMember()  : int|null
Resolve a branch ID from member identifiers carried in workflow context.
resolveDataverseGridQueryContext()  : DataverseGridQueryContext
Resolve Dataverse grid column context for early query construction.
resolveKingdomId()  : int|null
Resolve the kingdom ID from the authenticated member or workflow context.
resolveKingdomIdFromBranch()  : int|null
Walk the branch parent chain to find the kingdom-type ancestor.
resolveNestedValue()  : mixed
Resolve nested value from entity using dot notation path
sendMailNow()  : Mailer
Returns a mailer instance.
wantsTurboStreamRequest()  : bool
Whether the client expects a turbo-stream response.
withPageContextQuery()  : T
Run a callback with query params from the posted page context URL.
applyDataverseGridSort()  : SelectQuery
Apply a standard field sort or delegate to a column-specific sort handler.
attemptQuickPinLogin()  : Response|null
Attempt authentication using quick-login PIN credentials from the login form.
cleanupMembershipCardUpload()  : void
Remove a newly uploaded card after its owning workflow fails.
clearPendingQuickLoginSetup()  : void
Clear any pending quick-login setup state from the current session.
collectDataverseExpressionColumnKeys()  : void
columnKeyForDataverseField()  : string
defaultPostLoginRedirectTarget()  : array<string, string>
Determine the default post-login destination based on device type.
enforcePublicLookupRateLimit()  : Response|null
Apply rate limits to anonymous member lookup helpers.
extractDataverseGridConfigColumnKeys()  : array<int, string>
extractWorkflowDispatchFailure()  : string|null
Extract the first workflow dispatch failure from trigger results.
findActiveDefinition()  : WorkflowDefinition|null
Find an active workflow definition by slug.
flagQuickLoginOutOfSync()  : void
Mark quick login as out of sync and prompt password re-authentication.
getProxyHeaders()  : array<string, string>
Extract proxy headers relevant for geolocation from the current request.
invalidateOfflineTrust()  : void
Deliver local invalidation even when the browser follows a redirect immediately.
isDataverseGridNumericSearchColumn()  : bool
isQuickLoginAccountEligible()  : bool
Check whether a member is eligible for quick-login PIN authentication.
isSafeInternalRedirectPath()  : bool
Validate whether a redirect path is an internal URL safe for post-login navigation.
legacyIndex()  : mixed
Legacy paginated member listing (deprecated, use index with Dataverse grid).
markQuickPinLoginSuccess()  : void
Reset lockout counters and timestamps after successful quick PIN login.
maybeQueueQuickLoginPinSetup()  : Response|null
Queue quick-login PIN setup after successful password login when requested.
membershipCardReference()  : string|null
Build a stable opaque reference for stale membership-card form detection.
normalizeDataverseGridColumnConfig()  : array<int, string>
normalizeLockedDateBoundary()  : string|null
Normalize a persisted date boundary while retaining an intentionally open bound.
redirectAfterSuccessfulLogin()  : Response
Redirect after successful login.
requestEtagMatches()  : bool
Check If-None-Match using weak comparison semantics.
resolveDataverseGridActiveColumns()  : array<int, string>
Resolve hidden-but-active query dependency columns.
resolveDataverseGridViewContext()  : array{selectedSystemView: array|null, currentView: mixed}
Resolve active saved/system view enough for pre-query column dependency planning.
resolveDataverseGridVisibleColumns()  : array<int, string>
Resolve UI-visible columns using the same precedence as processDataverseGrid().
resolvePostLoginRedirectTarget()  : array<string|int, mixed>|string
Resolve where the member should land after a successful sign-in.
serveProfilePhoto()  : Response
Serve a cached profile-photo thumbnail after action-level authorization.
setAddFormViewVars()  : void
Populate shared view vars for the admin add-member form.
setRegisterFormViewVars()  : void
Populate shared view vars for the public registration form.
withProfilePhotoCacheHeaders()  : Response
Apply private browser caching and content hardening headers.

Constants

MOBILE_QUEUE_DEFAULT_PER_PAGE

public int MOBILE_QUEUE_DEFAULT_PER_PAGE = 25

Shared default page size for mobile actionable queues.

MOBILE_QUEUE_MAX_PER_PAGE

public int MOBILE_QUEUE_MAX_PER_PAGE = 50

Shared maximum page size for mobile actionable queues.

VIEW_DATA_EVENT

public string VIEW_DATA_EVENT = 'KMP.plugins.callForViewData'

Event for plugin view data enhancement

VIEW_PLUGIN_EVENT

public string VIEW_PLUGIN_EVENT = 'KMP.plugins.callForViewCells'

Event for plugin view cell registration

MEMBERSHIP_CARD_REUPLOAD_CONTACT_EMAIL

private mixed MEMBERSHIP_CARD_REUPLOAD_CONTACT_EMAIL = 'amp-secretary@webminister.ansteorra.org'

PROFILE_PHOTO_CACHE_CONTROL

private mixed PROFILE_PHOTO_CACHE_CONTROL = 'private, max-age=3600, must-revalidate'

QUICK_LOGIN_LOCKOUT_SECONDS

Quick PIN lockout window in seconds.

private mixed QUICK_LOGIN_LOCKOUT_SECONDS = 300

QUICK_LOGIN_MAX_PIN_ATTEMPTS

Maximum failed quick PIN attempts before temporary lockout.

private mixed QUICK_LOGIN_MAX_PIN_ATTEMPTS = 5

QUICK_LOGIN_SETUP_SESSION_KEY

Session key for deferred quick-login PIN setup.

private mixed QUICK_LOGIN_SETUP_SESSION_KEY = 'QuickLoginSetup'

Properties

$inject

public static array<string|int, string> $inject = [\App\Services\CsvExportService::class]

Service injection configuration

$isCsvRequest

protected bool $isCsvRequest = false

Whether current request is for CSV export (.csv extension)

$pluginViewCells

protected array<string|int, mixed> $pluginViewCells = []

View cells from plugins for current request

$pluginViewCellsEnabledForFragment

Whether an intentionally fragment-style response still needs plugin view cells.

protected bool $pluginViewCellsEnabledForFragment = false

$quickLoginDisabledEmailForRequest

Request-scoped email used to prefill password login after quick-login reset.

private string $quickLoginDisabledEmailForRequest = ''

$quickLoginDisabledForRequest

Request-scoped flag to instruct login UI to clear stale quick-login config.

private bool $quickLoginDisabledForRequest = false

Methods

add()

Create new member with age-based status and email notifications.

public add(TriggerDispatcher $dispatcher) : Response|null|void

Adults get STATUS_ACTIVE with password reset email. Minors get STATUS_UNVERIFIED_MINOR requiring verification. Generates mobile card token and sends appropriate notifications.

Parameters
$dispatcher : TriggerDispatcher
Return values
Response|null|void

beforeFilter()

Configure authorization and authentication filters.

public beforeFilter(EventInterface $event) : void
Parameters
$event : EventInterface

The beforeFilter event

beforeRender()

Finalize view-only data after the action has run.

public beforeRender(EventInterface<string|int, Controller$event) : Response|null|void

Deferring view cells prevents redirect-only requests from executing badge callbacks.

Parameters
$event : EventInterface<string|int, Controller>

Event.

Return values
Response|null|void

changePassword()

Change password.

public changePassword([mixed $id = null ]) : mixed
Parameters
$id : mixed = null

delete()

Delete method

public delete(TriggerDispatcher $dispatcher[, string|null $id = null ]) : Response|null
Parameters
$dispatcher : TriggerDispatcher
$id : string|null = null

Member id.

Tags
throws
RecordNotFoundException

When record not found.

Return values
Response|null

Redirects to index.

edit()

Edit method

public edit([string|null $id = null ]) : Response|null|void
Parameters
$id : string|null = null

Member id.

Tags
throws
RecordNotFoundException

When record not found.

Return values
Response|null|void

Redirects on successful edit, renders view otherwise.

editAdditionalInfo()

Edit additional info.

public editAdditionalInfo([mixed $id = null ]) : mixed
Parameters
$id : mixed = null

gatheringsGridData()

Gathering attendances grid data for Gatherings tab in member profile.

public gatheringsGridData(int $memberId) : Response|null|void
Parameters
$memberId : int

The member ID

Return values
Response|null|void

gridData()

Dataverse grid data endpoint for members listing.

public gridData(CsvExportService $csvExportService) : Response|null|void

Handles toolbar+table frame, table-only frame, and CSV export.

Parameters
$csvExportService : CsvExportService

CSV export service

Return values
Response|null|void

impersonate()

Begin impersonating another member (super user only).

public impersonate(int $memberId, ImpersonationService $impersonationService) : Response|null
Parameters
$memberId : int

Target member ID

$impersonationService : ImpersonationService

Session helper

Tags
throws
ForbiddenException

When current user is not super user

BadRequestException

When impersonation already active or invalid target

Return values
Response|null

index()

Display member listing with Dataverse grid (saved views, filters, sorting).

public index() : Response|null|void
Return values
Response|null|void

initialize()

Load shared components: Authentication, Authorization, Flash.

public initialize() : void

isCsvRequest()

Check if current request is for CSV export.

public isCsvRequest() : bool
Return values
bool

mobileCardUploadProfilePhoto()

Upload a profile photo from the mobile card flow.

public mobileCardUploadProfilePhoto(MemberProfileService $profileService[, string|null $id = null ]) : Response
Parameters
$profileService : MemberProfileService
$id : string|null = null
Return values
Response

Redirect response

partialEdit()

Partial edit.

public partialEdit([mixed $id = null ]) : mixed
Parameters
$id : mixed = null

profile()

Profile method

public profile() : Response|null|void

Shows the current user's profile without changing the URL

Return values
Response|null|void

Renders view

profilePhoto()

Stream a member profile photo document inline.

public profilePhoto(MemberProfileService $profileService[, int|null $id = null ]) : Response
Parameters
$profileService : MemberProfileService
$id : int|null = null

Member ID

Return values
Response

Inline file response

publicProfile()

Public profile.

public publicProfile([mixed $publicId = null ]) : mixed
Parameters
$publicId : mixed = null

removeProfilePhoto()

Remove a member profile photo and underlying document atomically.

public removeProfilePhoto(MemberProfileService $profileService[, int|null $id = null ]) : Response
Parameters
$profileService : MemberProfileService
$id : int|null = null

Member ID

Return values
Response

Redirect response

removeQuickLoginDevice()

Remove an enrolled quick-login device.

public removeQuickLoginDevice([string|null $id = null ]) : Response
Parameters
$id : string|null = null

Quick login device record ID

Return values
Response

requestMembershipCardReupload()

Remove an unreadable membership card and request a replacement from the member.

public requestMembershipCardReupload(MemberRegistrationService $registrationService, TriggerDispatcher $dispatcher[, mixed $id = null ]) : Response|null
Parameters
$registrationService : MemberRegistrationService

Membership-card storage service

$dispatcher : TriggerDispatcher

Workflow trigger dispatcher

$id : mixed = null

Member identifier

Return values
Response|null

rolesGridData()

Member roles grid data for Roles tab in member profile.

public rolesGridData(int $memberId) : Response|null|void
Parameters
$memberId : int

The member ID

Return values
Response|null|void

security()

Render member-authorized security actions in the shared dialog.

public security([mixed $id = null ]) : Response|null
Parameters
$id : mixed = null
Return values
Response|null

subRow()

Return sub-row content for expandable grid rows.

public subRow([string|null $id = null ][, string|null $type = null ]) : void
Parameters
$id : string|null = null

Member ID

$type : string|null = null

Type of sub-row content (e.g., 'warrantreasons')

Tags
throws
NotFoundException

switchView()

Switch between mobile and desktop view modes.

public switchView() : Response

Stores preference in session and redirects to appropriate interface. Mobile redirects to viewMobileCard, desktop to profile.

Return values
Response

Redirect response

verifyQueue()

Display member verification queue for administrative processing.

public verifyQueue() : Response|null|void

Shows members needing verification: card validation, age/parent verification.

Return values
Response|null|void

verifyQueueGridData()

Dataverse grid data endpoint for verification queue.

public verifyQueueGridData() : Response|null|void

Handles toolbar+table frame, table-only frame for members needing verification.

Return values
Response|null|void

view()

Display detailed member profile with relationships and management tools.

public view([string|null $id = null ]) : Response|null|void

Loads roles, branch, parent, current/upcoming/previous role assignments, and gathering attendances. Handles session-based form error display.

Parameters
$id : string|null = null

Member ID to display

Tags
throws
NotFoundException

When member not found

Return values
Response|null|void

viewCard()

View card.

public viewCard([mixed $id = null ]) : mixed
Parameters
$id : mixed = null

viewCardJson()

View card json.

public viewCardJson([mixed $id = null ]) : mixed
Parameters
$id : mixed = null

viewMobileCard()

View mobile card.

public viewMobileCard([mixed $id = null ]) : mixed
Parameters
$id : mixed = null

viewMobileCardJson()

View mobile card json.

public viewMobileCardJson([mixed $id = null ]) : mixed
Parameters
$id : mixed = null

_addRolesSelectAndContain()

Internal: add roles select and contain.

protected _addRolesSelectAndContain(SelectQuery $q) : mixed
Parameters
$q : SelectQuery

applyCustomFilterHandlers()

Apply custom filter handlers for columns with complex filtering logic

protected applyCustomFilterHandlers(SelectQuery $query, array<string|int, mixed> $customFilterColumns, string $tableName, array<string|int, mixed> $currentFilters, mixed $currentView, array<string|int, mixed>|null $selectedSystemView, bool $dirtyFilters) : SelectQuery

Columns can define a customFilterHandler in their metadata to specify a static method that handles their filtering. This allows complex filter logic (like querying multiple tables) to be defined alongside the column definition rather than requiring special controller knowledge.

Filter values are extracted from:

  1. Canonical current filter state (query parameters plus enforced locked values)
  2. Saved user view configuration (when loading a saved view)
  3. System view configuration (when loading a system view)
Parameters
$query : SelectQuery

The query to filter

$customFilterColumns : array<string|int, mixed>

Columns with customFilterHandler defined

$tableName : string

The main table name

$currentFilters : array<string|int, mixed>

Current filter values from query params

$currentView : mixed

Current saved user view (or null)

$selectedSystemView : array<string|int, mixed>|null

Current system view config (or null)

$dirtyFilters : bool

Whether user explicitly modified filters

Return values
SelectQuery

The filtered query

applyVerifyQueueBaseFilter()

Apply base filter for verification queue (all items needing verification)

protected applyVerifyQueueBaseFilter(SelectQuery $query) : SelectQuery
Parameters
$query : SelectQuery

Base query to filter

Return values
SelectQuery

Filtered query

appSettingImageDataUri()

Resolve shared tenant branding for the online and cached mobile templates.

protected appSettingImageDataUri(string $settingName) : string|null
Parameters
$settingName : string
Return values
string|null

assertSafeContextUrl()

Ensure URL is same-origin relative path + query only.

protected assertSafeContextUrl(string $url) : string
Parameters
$url : string
Tags
throws
BadRequestException
Return values
string

authorizeCurrentUrl()

Authorize the current URL/action via Authorization component.

protected authorizeCurrentUrl() : void
Tags
throws
ForbiddenException

When authorization fails

buildDataverseGridSearchCondition()

Build a search condition for one Dataverse grid column.

protected buildDataverseGridSearchCondition(string $field, array<string, mixed>|null $columnMeta, string $searchTerm) : array<string, mixed>|null
Parameters
$field : string

Fully-qualified database field.

$columnMeta : array<string, mixed>|null

Column metadata, when available.

$searchTerm : string

User-entered search term.

Return values
array<string, mixed>|null

buildDataverseGridState()

Build complete grid state object (single source of truth)

protected buildDataverseGridState(mixed $currentView, array<string|int, mixed>|null $selectedSystemView, array<string|int, mixed>|null $systemViews, iterable<string|int, mixed> $availableViews, Member|null $currentMember, string|int|null $preferredViewId, string $search, array<string|int, mixed> $filters, array<string|int, mixed> $filterOptions, array<string|int, mixed> $dropdownFilterColumns, array<string|int, mixed> $dateRangeFilterColumns, array<string|int, mixed> $sort, array<string|int, mixed> $visibleColumns, array<string|int, mixed> $allColumns, string $gridKey, int $pageSize, bool $showAllTab, bool $canAddViews, bool $canFilter, bool $hasSearch, bool $hasDropdownFilters, bool $hasDateRangeFilters, array<string|int, mixed> $skipFilterColumns, bool $canExportCsv, bool $showFilterPills, bool $showViewTabs, bool $enableColumnPicker[, array<string|int, mixed> $lockedFilters = [] ][, bool $enableBulkSelection = false ][, array<string|int, mixed> $bulkSelection = [] ][, array<string|int, mixed> $bulkActions = [] ][, array<string|int, mixed> $bulkSelectionDataFields = [] ][, string|null $bulkSelectionDisabledField = null ][, bool $bulkSelectionHideDisabledControl = false ][, bool $includeViewMetadata = true ][, bool $includeAllColumns = true ]) : array<string|int, mixed>
Parameters
$currentView : mixed

Current saved view entity (null for system views or "All")

$selectedSystemView : array<string|int, mixed>|null

Currently selected system view

$systemViews : array<string|int, mixed>|null

All available system views

$availableViews : iterable<string|int, mixed>

Collection of saved views

$currentMember : Member|null

Authenticated member

$preferredViewId : string|int|null

Preferred view ID from user preferences

$search : string

Current search term

$filters : array<string|int, mixed>

Active filters by column key

$filterOptions : array<string|int, mixed>

Available filter options by column key

$dropdownFilterColumns : array<string|int, mixed>

Metadata for filterable columns

$dateRangeFilterColumns : array<string|int, mixed>
$sort : array<string|int, mixed>

Current sort configuration

$visibleColumns : array<string|int, mixed>

Array of visible column keys

$allColumns : array<string|int, mixed>

Complete column metadata

$gridKey : string

Unique grid identifier

$pageSize : int

Number of rows per page

$showAllTab : bool

Whether to show "All" tab

$canAddViews : bool

Whether users can create custom views

$canFilter : bool

Whether filtering is enabled

$hasSearch : bool
$hasDropdownFilters : bool
$hasDateRangeFilters : bool
$skipFilterColumns : array<string|int, mixed>

Columns with filter UI but not query application

$canExportCsv : bool

Whether CSV export button is shown

$showFilterPills : bool

Whether active filter pills/badges are displayed

$showViewTabs : bool

Whether view tabs are displayed

$enableColumnPicker : bool

Whether column picker is available

$lockedFilters : array<string|int, mixed> = []

Filter column keys that cannot be removed by users

$enableBulkSelection : bool = false
$bulkSelection : array<string|int, mixed> = []

Bulk selection accessibility label configuration

$bulkActions : array<string|int, mixed> = []
$bulkSelectionDataFields : array<string|int, mixed> = []
$bulkSelectionDisabledField : string|null = null
$bulkSelectionHideDisabledControl : bool = false
$includeViewMetadata : bool = true
$includeAllColumns : bool = true
Return values
array<string|int, mixed>

Complete grid state

buildExportDataFromEntities()

Build export data from pre-processed entities (Data Mode)

protected buildExportDataFromEntities(iterable<string|int, mixed> $data, array<string|int, mixed> $visibleColumns, array<string|int, mixed> $columnsMetadata) : array<string|int, mixed>

Extracts values from entities using column metadata configuration. Supports virtual properties, nested relations via renderField, and custom exportValue callbacks.

Parameters
$data : iterable<string|int, mixed>

Pre-processed entities or arrays

$visibleColumns : array<string|int, mixed>

List of visible column keys

$columnsMetadata : array<string|int, mixed>

Column configuration metadata

Return values
array<string|int, mixed>

Transformed data ready for CSV export

buildExportDataFromQuery()

Build export data from database query (Query Mode)

protected buildExportDataFromQuery(Query $query, array<string|int, mixed> $visibleColumns, array<string|int, mixed> $columnsMetadata, string $tableName) : array<string|int, mixed>

Builds SQL SELECT statements and executes query for simple database fields. Best for exports that don't require computed fields.

Parameters
$query : Query

Database query to execute

$visibleColumns : array<string|int, mixed>

List of visible column keys

$columnsMetadata : array<string|int, mixed>

Column configuration metadata

$tableName : string

Full table name for model alias extraction

Return values
array<string|int, mixed>

Transformed data ready for CSV export

buildGridDataUrlFromPageContext()

Build grid-data URL preserving query string from page context.

protected buildGridDataUrlFromPageContext(string|null $pageContextUrl, array<string, mixed> $gridDataRoute) : string
Parameters
$pageContextUrl : string|null
$gridDataRoute : array<string, mixed>

Cake URL array for gridData action

Return values
string

consumeFlashForStream()

Read flash from session and clear it for stream rendering.

protected consumeFlashForStream() : array<string, mixed>
Return values
array<string, mixed>

convertDateBoundaryToUtc()

Convert a date boundary string from kingdom timezone to UTC for SQL comparison.

protected convertDateBoundaryToUtc(string $dateValue, bool $isStart) : string

The database stores datetimes in UTC. Date-range filters use kingdom-timezone dates (e.g., "today" = 2026-04-09 in US/Eastern). Without conversion, a SQL comparison like start_on <= '2026-04-09 23:59:59' would miss records stored as '2026-04-10 03:00:00' UTC (which is still April 9 in Eastern).

Parameters
$dateValue : string

Date string (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)

$isStart : bool

True for start-of-day boundary (00:00:00), false for end-of-day (23:59:59)

Return values
string

UTC datetime string for SQL comparison

dispatchWorkflowEvent()

Fire a workflow event without fallback. Silently logs on failure.

protected dispatchWorkflowEvent(TriggerDispatcher $dispatcher, string $triggerEvent, array<string|int, mixed> $context) : void

Includes kingdom context from the authenticated user.

Parameters
$dispatcher : TriggerDispatcher

Workflow trigger dispatcher

$triggerEvent : string

Event name for the workflow engine

$context : array<string|int, mixed>

Event data / context for the workflow

dispatchWorkflowOrFail()

Dispatch to the workflow engine and fail when no active definition is available.

protected dispatchWorkflowOrFail(TriggerDispatcher $dispatcher, string $slug, string $triggerEvent, array<string|int, mixed> $context) : array<int, mixed>

Resolves the current kingdom from the authenticated user's branch hierarchy and includes it in the dispatch context.

Parameters
$dispatcher : TriggerDispatcher

Workflow trigger dispatcher

$slug : string

Workflow definition slug

$triggerEvent : string

Event name for the workflow engine

$context : array<string|int, mixed>

Event data / context for the workflow

Return values
array<int, mixed>

enablePluginViewCellsForFragment()

Include route-matched plugin cells in an AJAX or other fragment response.

protected enablePluginViewCellsForFragment() : void

extractContextValue()

Extract a matching value from the workflow context or its nested payload arrays.

protected extractContextValue(array<string, mixed> $context, array<int, string> $keys) : mixed
Parameters
$context : array<string, mixed>

Workflow trigger context.

$keys : array<int, string>

Keys to search for.

extractExportValue()

Extract export value from entity using column metadata

protected extractExportValue(mixed $entity, string $columnKey, array<string|int, mixed> $columnMeta) : string

Resolution order:

  1. exportValue callback if defined in column metadata
  2. renderField path for nested entity access (e.g., 'member.name_for_herald')
  3. Direct property access using column key
Parameters
$entity : mixed

Entity or array to extract value from

$columnKey : string

Column key identifier

$columnMeta : array<string|int, mixed>

Column metadata configuration

Return values
string

Extracted and formatted value

extractFilterFromExpression()

Recursively extract a filter value from an expression tree

protected extractFilterFromExpression(array<string|int, mixed> $expression, string $columnKey) : mixed
Parameters
$expression : array<string|int, mixed>

The expression node to search

$columnKey : string

The column key to find

Return values
mixed

The filter value or null if not found

extractFilterFromSystemView()

Extract a specific filter value from a system view configuration

protected extractFilterFromSystemView(array<string|int, mixed> $systemView, string $columnKey) : mixed
Parameters
$systemView : array<string|int, mixed>

The system view configuration

$columnKey : string

The column key to find

Return values
mixed

The filter value or null if not found

extractFilterFromViewConfig()

Extract a specific filter value from a saved user view's config

protected extractFilterFromViewConfig(mixed $view, string $columnKey) : mixed
Parameters
$view : mixed

The GridView entity

$columnKey : string

The column key to find

Return values
mixed

The filter value or null if not found

extractFilterGrouping()

Extract filter grouping information from expression tree

protected extractFilterGrouping(array<string|int, mixed>|null $selectedSystemView, array<string|int, mixed> $skipFilterColumns) : array<string|int, mixed>

Analyzes the expression tree to determine OR relationships between filters. Returns metadata that the frontend can use to display visual OR indicators.

Parameters
$selectedSystemView : array<string|int, mixed>|null

Currently active system view

$skipFilterColumns : array<string|int, mixed>

Columns that show as pills but don't query

Return values
array<string|int, mixed>

Grouping metadata with 'orGroups' array

extractLockedDateRangeDefaults()

Extract canonical bounds for active date-range filters whose fields are locked.

protected extractLockedDateRangeDefaults(array<string, mixed> $viewConfig, array<int, string> $lockedFilters, array<string, array<string, mixed>> $columnsMetadata) : array<string, array{value: string|null, operator: string}>
Parameters
$viewConfig : array<string, mixed>

Active system or saved-view config.

$lockedFilters : array<int, string>

Locked filter keys.

$columnsMetadata : array<string, array<string, mixed>>

Grid column metadata.

Return values
array<string, array{value: string|null, operator: string}>

Date parameter bounds.

extractNumericContextValue()

Extract a numeric value from top-level or nested workflow context arrays.

protected extractNumericContextValue(array<string, mixed> $context, array<int, string> $keys) : int|null
Parameters
$context : array<string, mixed>

Workflow trigger context.

$keys : array<int, string>

Keys to search for.

Return values
int|null

extractStringContextValue()

Extract a string value from top-level or nested workflow context arrays.

protected extractStringContextValue(array<string, mixed> $context, array<int, string> $keys) : string|null
Parameters
$context : array<string, mixed>

Workflow trigger context.

$keys : array<int, string>

Keys to search for.

Return values
string|null

extractSystemViewDefaults()

Extract default filters/search metadata for a system view configuration

protected extractSystemViewDefaults(array<string, mixed> $systemViewConfig) : array{filters: array, dateRange: array, dateRangeOperators: array, search: ?string, skipFilterColumns: array}
Parameters
$systemViewConfig : array<string, mixed>

Raw system view config

Return values
array{filters: array, dateRange: array, dateRangeOperators: array, search: ?string, skipFilterColumns: array}

formatExportValue()

Format value for CSV export

protected formatExportValue(mixed $value) : string

Handles various data types and converts to string representation.

Parameters
$value : mixed

Value to format

Return values
string

Formatted string value

getPageContextUrl()

Posted page context URL (path + query), validated.

protected getPageContextUrl() : string|null
Return values
string|null

getVerifyQueueSystemViewCounts()

Get record counts for each verify queue system view.

protected getVerifyQueueSystemViewCounts() : array<string, int>
Return values
array<string, int>

handleCsvExport()

Handle CSV export from grid result

protected handleCsvExport(array<string|int, mixed> $result, CsvExportService $csvExportService, string $entityName[, string|null $tableName = null ][, iterable<string|int, mixed>|null $data = null ]) : Response

Generates a CSV export response from the grid processing result. Supports two modes:

  1. Query Mode (default): Uses the query from result to build SQL SELECT statements. Best for simple fields that map directly to database columns.

  2. Data Mode: Pass pre-processed data with computed/virtual fields already populated. Best for exports that include calculated fields, virtual properties, or complex transformations that can't be done in SQL.

Column Value Resolution (in order of precedence):

  1. exportValue callback in column metadata - custom formatting function
  2. renderField path (e.g., 'member.name_for_herald') - for nested entity access
  3. queryField for relation columns in query mode
  4. Direct column key access on entity/array
Parameters
$result : array<string|int, mixed>

Result from processDataverseGrid() with isCsvExport flag

$csvExportService : CsvExportService

CSV export service instance

$entityName : string

Base name for the export file (e.g., 'members', 'warrants')

$tableName : string|null = null

Optional table name for fetchTable (e.g., 'Awards.Recommendations' for plugin tables) If not provided, uses ucfirst($entityName)

$data : iterable<string|int, mixed>|null = null

Optional pre-processed data. If provided, uses data mode instead of query mode. Data should be an iterable of entities or arrays with all computed fields populated.

Tags
throws
ForbiddenException

If user lacks export permission

Return values
Response

CSV download response

isCsvExportRequest()

Check if the current request is for CSV export

protected isCsvExportRequest() : bool
Return values
bool

True if CSV export is requested

isDataverseTableFrameRequest()

protected isDataverseTableFrameRequest() : bool
Return values
bool

Whether request is for inner table frame.

isGridOriginRequest()

Whether POST originated from a grid index (stay on list).

protected isGridOriginRequest(string|null $pageContextUrl) : bool
Parameters
$pageContextUrl : string|null
Return values
bool

loadAvailableViews()

Load and cache available views for the current request.

protected loadAvailableViews(string $gridKey, int $memberId) : array<int, mixed>
Parameters
$gridKey : string

Grid identifier

$memberId : int

Authenticated member id

Return values
array<int, mixed>

loadFilterOptions()

Load filter options from a data source

protected loadFilterOptions(array<string|int, mixed>|string $source) : array<string|int, mixed>

Supports multiple formats for filterOptionsSource:

  1. Simple string (table name): Uses 'id' for value, 'name' for label

    'filterOptionsSource' => 'Branches'
    
  2. Array with table: Database table with full control

    'filterOptionsSource' => [
        'table' => 'Waivers.WaiverTypes',  // Required: table name for fetchTable()
        'valueField' => 'id',              // Optional: field for option value (default: 'id')
        'labelField' => 'name',            // Optional: field for option label (default: 'name')
        'conditions' => ['is_active' => true],  // Optional: filter conditions
        'order' => ['name' => 'ASC'],      // Optional: sort order (default: labelField ASC)
    ]
    
  3. Array with appSetting: Load from app settings (YAML array)

    'filterOptionsSource' => [
        'appSetting' => 'Branches.Types',  // Required: app setting key
    ]
    

    The app setting should contain a YAML array like: ['Kingdom', 'Principality', 'Barony'] Both value and label will be set to the array item value.

  4. Array with method: Call a static method on a class to get options

    'filterOptionsSource' => [
        'method' => 'getGatheringsFilterOptions',  // Required: static method name
        'class' => 'Awards\\KMP\\GridColumns\\RecommendationsGridColumns',  // Required: fully qualified class name
    ]
    

    The method should return array of ['value' => string, 'label' => string].

Parameters
$source : array<string|int, mixed>|string

Source identifier string (table name) or configuration array

Return values
array<string|int, mixed>

Filter options as array of ['value' => string, 'label' => string]

loadFilterOptionsCached()

Load filter options with per-request cache.

protected loadFilterOptionsCached(array<string|int, mixed>|string $source) : array<int, array{value: string, label: string}>
Parameters
$source : array<string|int, mixed>|string

filterOptionsSource configuration

Return values
array<int, array{value: string, label: string}>

matchesGridIndexPath()

Whether page context path matches a grid index route pattern.

protected matchesGridIndexPath(string|null $pageContextUrl, string $pathRegex) : bool
Parameters
$pageContextUrl : string|null
$pathRegex : string
Return values
bool

mobileQueuePagination()

Build shared pagination values for mobile actionable queues.

protected mobileQueuePagination(int $total) : array<string, int|bool>
Parameters
$total : int

Total actionable records

Return values
array<string, int|bool>

mobileQueuePaginationPayload()

Remove internal pagination values before sending the mobile JSON payload.

protected mobileQueuePaginationPayload(array<string, int|bool> $pagination) : array<string, int|bool>
Parameters
$pagination : array<string, int|bool>

Pagination data

Return values
array<string, int|bool>

organizeViewCells()

Organize view cells by type and display order.

protected organizeViewCells(array<string|int, mixed> $viewCells) : array<string|int, mixed>

Unused - view cells organized in ViewCellRegistry

Parameters
$viewCells : array<string|int, mixed>

Flat array of view cell configurations

Return values
array<string|int, mixed>

Organized array grouped by type and sorted by order

processDataverseGrid()

Process dataverse grid request with unified logic

protected processDataverseGrid(array<string|int, mixed> $config) : array<string|int, mixed>

This method handles all aspects of grid processing including view management, filtering, searching, sorting, and pagination. It supports both saved user views and system-defined views.

Parameters
$config : array<string|int, mixed>

Grid configuration with the following keys:

  • gridKey (string): Unique identifier for the grid
  • gridColumnsClass (string): Fully qualified class name for grid columns metadata
  • baseQuery (Query): Base query object to start with
  • tableName (string): Primary table name for field qualification
  • defaultSort (array): Default sort configuration ['field' => 'direction']
  • defaultPageSize (int): Default number of records per page (default: 25)
  • systemViews (array|null): Optional array of system views (for Warrants-style grids)
  • defaultSystemView (string|null): Default system view key (required if systemViews provided)
  • queryCallback (callable|null): Optional callback to modify query per system view
  • showAllTab (bool): Whether to show "All" tab (default: true for saved views, false for system views)
  • canAddViews (bool): Whether users can create custom views (default: true)
  • canFilter (bool): Whether user filtering is enabled (default: true). When false, users cannot add/remove filters via the UI or query parameters. However, filters defined by system views are ALWAYS applied regardless of this setting.
  • canExportCsv (bool): Whether CSV export button is shown (default: true)
  • showFilterPills (bool): Whether active filter pills/badges are displayed (default: true)
  • showViewTabs (bool): Whether view tabs are displayed (default: true)
  • enableColumnPicker (bool): Whether column picker is available (default: true)
  • lockedFilters (array): Array of filter column keys that cannot be removed by users. Locked filters will not show remove (×) buttons and their values cannot be cleared via query string parameters. Useful for embedded grids where context filters (e.g., member_id) must always be applied.
  • enableBulkSelection (bool): Whether row selection checkboxes are shown (default: false)
  • bulkSelection (array): Bulk selection accessibility label configuration. Keys: selectAllLabel, rowLabelTemplate, disabledLabel. rowLabelTemplate supports {field_key} placeholders resolved from each row, including dotted paths and column renderField aliases.
  • bulkActions (array): Array of bulk action button configurations when enableBulkSelection is true. Each action is an array with keys: label, icon, modalTarget, permission.
  • disablePagination (bool): When true, bypasses the paginator and returns all matching records. Use for views (e.g. calendar) that are already filtered to a bounded date range and must show every result without an arbitrary row cap. Caller responsibility*: the baseQuery MUST include WHERE clauses that bound the result set (e.g. a date range) to avoid fetching unbounded data. (default: false)

NOTE: Authorization scope must be applied to baseQuery BEFORE calling this method. Use $baseQuery = $this->Authorization->applyScope($baseQuery, 'index'); in your controller before passing the query to processDataverseGrid().

Return values
array<string|int, mixed>

Result array with keys: data, gridState, columnsMetadata, etc.

queueMail()

Returns a mailer instance.

protected queueMail(string $name, mixed $action, mixed $to, mixed $vars) : Mailer
Parameters
$name : string

Mailer's name.

$action : mixed
$to : mixed
$vars : mixed
Tags
throws
MissingMailerException

if undefined mailer class.

Return values
Mailer

queueMailJob()

Queues a mail job to be processed later.

protected queueMailJob(array<string|int, mixed> $data) : void
Parameters
$data : array<string|int, mixed>

Data to be passed to the mailer.

renderDataverseGridResponse()

Render consistent dataverse grid responses for outer/table turbo frames.

protected renderDataverseGridResponse(array<string, mixed> $result, string $frameId[, string|null $collectionVar = null ][, array<string, mixed> $extraViewVars = [] ]) : void
Parameters
$result : array<string, mixed>

processDataverseGrid() result

$frameId : string

Outer frame id (e.g. members-grid)

$collectionVar : string|null = null

Optional collection variable name to set (e.g. members)

$extraViewVars : array<string, mixed> = []

Additional vars to expose to template

renderDataverseTableRowElement()

Render a single Dataverse grid row element (Turbo Stream replace target HTML).

protected renderDataverseTableRowElement(array<string, mixed> $vars) : string
Parameters
$vars : array<string, mixed>

Element variables

Return values
string

renderTurboCloseModal()

Render turbo-stream: flash + replace table frame with lazy reload src.

protected renderTurboCloseModal(string $refreshFrame, array<string, mixed> $gridDataRoute[, string|null $pageContextUrl = null ][, array<string|int, mixed>|null $flashMessages = null ]) : Response
Parameters
$refreshFrame : string
$gridDataRoute : array<string, mixed>
$pageContextUrl : string|null = null
$flashMessages : array<string|int, mixed>|null = null
Return values
Response

renderTurboFlashOnly()

Render turbo-stream flash messages without forcing a grid or frame reload.

protected renderTurboFlashOnly([array<string|int, mixed>|null $flashMessages = null ]) : Response
Parameters
$flashMessages : array<string|int, mixed>|null = null
Return values
Response

renderTurboReloadFrame()

Stream that reloads an edit turbo-frame (validation errors).

protected renderTurboReloadFrame(string $frameId, string $frameSrc[, array<string|int, mixed>|null $flashMessages = null ]) : Response
Parameters
$frameId : string
$frameSrc : string
$flashMessages : array<string|int, mixed>|null = null
Return values
Response

renderTurboRemoveGridRow()

Render turbo-stream: flash + remove a grid row (no longer matches current filters).

protected renderTurboRemoveGridRow(string $rowDomId[, array<string|int, mixed>|null $flashMessages = null ]) : Response
Parameters
$rowDomId : string
$flashMessages : array<string|int, mixed>|null = null
Return values
Response

renderTurboReplaceGridRow()

Render turbo-stream: flash + replace a single grid row by DOM id.

protected renderTurboReplaceGridRow(string $rowDomId, string $rowHtml[, array<string|int, mixed>|null $flashMessages = null ]) : Response
Parameters
$rowDomId : string
$rowHtml : string
$flashMessages : array<string|int, mixed>|null = null
Return values
Response

resolveBranchIdFromContextMember()

Resolve a branch ID from member identifiers carried in workflow context.

protected resolveBranchIdFromContextMember(array<string, mixed> $context) : int|null

Supports both direct member IDs and member public IDs from public forms.

Parameters
$context : array<string, mixed>

Workflow trigger context.

Return values
int|null

resolveDataverseGridQueryContext()

Resolve Dataverse grid column context for early query construction.

protected resolveDataverseGridQueryContext(array<string, mixed> $config[, array<string, mixed>|null $selectedSystemView = null ][, mixed $currentView = null ][, bool $viewContextResolved = false ]) : DataverseGridQueryContext
Parameters
$config : array<string, mixed>

Grid configuration.

$selectedSystemView : array<string, mixed>|null = null

Already-resolved system view when called from processDataverseGrid().

$currentView : mixed = null

Already-resolved saved view when called from processDataverseGrid().

$viewContextResolved : bool = false

Whether null selected/current view values are already authoritative.

Return values
DataverseGridQueryContext

resolveKingdomId()

Resolve the kingdom ID from the authenticated member or workflow context.

protected resolveKingdomId([array<string, mixed> $context = [] ]) : int|null

Authenticated requests still prefer the actor's branch ancestry. Anonymous requests can derive kingdom from explicit branch or member identifiers in the workflow context so public forms can dispatch to kingdom-specific flows.

Parameters
$context : array<string, mixed> = []

Workflow trigger context.

Return values
int|null

Kingdom branch ID, or null if unavailable

resolveKingdomIdFromBranch()

Walk the branch parent chain to find the kingdom-type ancestor.

protected resolveKingdomIdFromBranch(int $branchId) : int|null
Parameters
$branchId : int

Starting branch ID

Return values
int|null

Kingdom branch ID, or null if no kingdom found

resolveNestedValue()

Resolve nested value from entity using dot notation path

protected resolveNestedValue(mixed $entity, string $path) : mixed
Parameters
$entity : mixed

Entity to traverse

$path : string

Dot-notation path (e.g., 'member.name_for_herald')

Return values
mixed

Resolved value or null if path doesn't exist

sendMailNow()

Returns a mailer instance.

protected sendMailNow(array<string|int, mixed> $data) : Mailer
Parameters
$data : array<string|int, mixed>
Tags
throws
MissingMailerException

if undefined mailer class.

Return values
Mailer

wantsTurboStreamRequest()

Whether the client expects a turbo-stream response.

protected wantsTurboStreamRequest() : bool
Return values
bool

withPageContextQuery()

Run a callback with query params from the posted page context URL.

protected withPageContextQuery(string|null $pageContextUrl, callable(): T $callback) : T
Parameters
$pageContextUrl : string|null
$callback : callable(): T
Tags
template
Return values
T

applyDataverseGridSort()

Apply a standard field sort or delegate to a column-specific sort handler.

private applyDataverseGridSort(SelectQuery $query, string $columnKey, string $direction, array<string, mixed> $columnMeta, string $tableName) : SelectQuery

Custom handlers are useful when a relation sort needs a correlated subquery or another expression that remains valid in paginator/eager-loader subqueries.

Parameters
$query : SelectQuery

Query being sorted.

$columnKey : string

Grid column key.

$direction : string

Requested sort direction.

$columnMeta : array<string, mixed>

Column metadata.

$tableName : string

Primary query alias.

Return values
SelectQuery

Sorted query.

attemptQuickPinLogin()

Attempt authentication using quick-login PIN credentials from the login form.

private attemptQuickPinLogin(QuickLoginDeviceService $quickLoginService) : Response|null
Parameters
$quickLoginService : QuickLoginDeviceService

Quick-login device service.

Return values
Response|null

Redirect response on successful login, otherwise null.

clearPendingQuickLoginSetup()

Clear any pending quick-login setup state from the current session.

private clearPendingQuickLoginSetup() : void

collectDataverseExpressionColumnKeys()

private collectDataverseExpressionColumnKeys(mixed $expression, array<int, string> &$columns) : void
Parameters
$expression : mixed
$columns : array<int, string>

columnKeyForDataverseField()

private columnKeyForDataverseField(string $field, array<string, array<string, mixed>> $columnsMetadata) : string
Parameters
$field : string
$columnsMetadata : array<string, array<string, mixed>>
Return values
string

defaultPostLoginRedirectTarget()

Determine the default post-login destination based on device type.

private defaultPostLoginRedirectTarget() : array<string, string>
Return values
array<string, string>

enforcePublicLookupRateLimit()

Apply rate limits to anonymous member lookup helpers.

private enforcePublicLookupRateLimit(RequestRateLimiter $rateLimiter, string $bucket) : Response|null
Parameters
$rateLimiter : RequestRateLimiter

Rate limiter

$bucket : string

Rate-limit bucket

Return values
Response|null

429 response when limited, otherwise null

extractDataverseGridConfigColumnKeys()

private extractDataverseGridConfigColumnKeys(array<string, mixed> $config) : array<int, string>
Parameters
$config : array<string, mixed>
Return values
array<int, string>

extractWorkflowDispatchFailure()

Extract the first workflow dispatch failure from trigger results.

private extractWorkflowDispatchFailure(array<int, mixed> $results, string $defaultMessage) : string|null
Parameters
$results : array<int, mixed>

Workflow dispatch results.

$defaultMessage : string

Fallback error message.

Return values
string|null

flagQuickLoginOutOfSync()

Mark quick login as out of sync and prompt password re-authentication.

private flagQuickLoginOutOfSync(string $emailAddress) : void
Parameters
$emailAddress : string

Email used for the failed quick-login attempt.

getProxyHeaders()

Extract proxy headers relevant for geolocation from the current request.

private getProxyHeaders() : array<string, string>
Return values
array<string, string>

invalidateOfflineTrust()

Deliver local invalidation even when the browser follows a redirect immediately.

private invalidateOfflineTrust() : void

isDataverseGridNumericSearchColumn()

private isDataverseGridNumericSearchColumn(array<string, mixed>|null $columnMeta) : bool
Parameters
$columnMeta : array<string, mixed>|null

Column metadata.

Return values
bool

isQuickLoginAccountEligible()

Check whether a member is eligible for quick-login PIN authentication.

private isQuickLoginAccountEligible(Member $member) : bool
Parameters
$member : Member

Candidate member account.

Return values
bool

True when account status and lockout state permit quick login.

isSafeInternalRedirectPath()

Validate whether a redirect path is an internal URL safe for post-login navigation.

private isSafeInternalRedirectPath(string $page) : bool
Parameters
$page : string

Redirect path from query string.

Return values
bool

legacyIndex()

Legacy paginated member listing (deprecated, use index with Dataverse grid).

private legacyIndex() : mixed

Supports search with Þ/th character conversion for medieval names.

markQuickPinLoginSuccess()

Reset lockout counters and timestamps after successful quick PIN login.

private markQuickPinLoginSuccess(Member $member) : void
Parameters
$member : Member

Authenticated member entity.

maybeQueueQuickLoginPinSetup()

Queue quick-login PIN setup after successful password login when requested.

private maybeQueueQuickLoginPinSetup(Member $member, array<string|int, mixed>|string $redirectTarget) : Response|null
Parameters
$member : Member

Authenticated member.

$redirectTarget : array<string|int, mixed>|string

Destination after login or setup skip.

Return values
Response|null

Redirect to PIN setup or null when setup is not required.

membershipCardReference()

Build a stable opaque reference for stale membership-card form detection.

private membershipCardReference(Member $member) : string|null
Parameters
$member : Member

Member with a current card reference

Return values
string|null

normalizeDataverseGridColumnConfig()

private normalizeDataverseGridColumnConfig(mixed $columns) : array<int, string>
Parameters
$columns : mixed
Return values
array<int, string>

normalizeLockedDateBoundary()

Normalize a persisted date boundary while retaining an intentionally open bound.

private normalizeLockedDateBoundary(mixed $value) : string|null
Parameters
$value : mixed
Return values
string|null

redirectAfterSuccessfulLogin()

Redirect after successful login.

private redirectAfterSuccessfulLogin() : Response
Return values
Response

requestEtagMatches()

Check If-None-Match using weak comparison semantics.

private requestEtagMatches(string $etag) : bool
Parameters
$etag : string
Return values
bool

resolveDataverseGridActiveColumns()

Resolve hidden-but-active query dependency columns.

private resolveDataverseGridActiveColumns(array<string, mixed> $config, array<string, array<string, mixed>> $columnsMetadata, array<string, mixed>|null $selectedSystemView, mixed $currentView) : array<int, string>
Parameters
$config : array<string, mixed>

Grid configuration.

$columnsMetadata : array<string, array<string, mixed>>
$selectedSystemView : array<string, mixed>|null
$currentView : mixed
Return values
array<int, string>

resolveDataverseGridViewContext()

Resolve active saved/system view enough for pre-query column dependency planning.

private resolveDataverseGridViewContext(array<string, mixed> $config) : array{selectedSystemView: array|null, currentView: mixed}
Parameters
$config : array<string, mixed>

Grid configuration.

Return values
array{selectedSystemView: array|null, currentView: mixed}

resolveDataverseGridVisibleColumns()

Resolve UI-visible columns using the same precedence as processDataverseGrid().

private resolveDataverseGridVisibleColumns(class-string $gridColumnsClass, array<string, array<string, mixed>> $columnsMetadata, array<string, mixed>|null $selectedSystemView, mixed $currentView) : array<int, string>
Parameters
$gridColumnsClass : class-string
$columnsMetadata : array<string, array<string, mixed>>
$selectedSystemView : array<string, mixed>|null
$currentView : mixed
Return values
array<int, string>

resolvePostLoginRedirectTarget()

Resolve where the member should land after a successful sign-in.

private resolvePostLoginRedirectTarget() : array<string|int, mixed>|string
Return values
array<string|int, mixed>|string

setAddFormViewVars()

Populate shared view vars for the admin add-member form.

private setAddFormViewVars(Member $member) : void
Parameters
$member : Member

Current form entity

setRegisterFormViewVars()

Populate shared view vars for the public registration form.

private setRegisterFormViewVars(Member $member) : void
Parameters
$member : Member

Current form entity

withProfilePhotoCacheHeaders()

Apply private browser caching and content hardening headers.

private withProfilePhotoCacheHeaders(Response $response, string $etag) : Response
Parameters
$response : Response
$etag : string
Return values
Response
On this page

Search results