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
$Members
public
MembersTable
$Members
$csvExportService
protected
CsvExportService
$csvExportService
$isCsvRequest
protected
bool
$isCsvRequest
= false
Whether current request is for CSV export (.csv extension)
$mailer
protected
Mailer
$mailer
$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|voidautoComplete()
Auto complete.
public
autoComplete(MemberSearchService $searchService) : mixed
Parameters
- $searchService : MemberSearchService
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|voidchangePassword()
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
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
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
emailTaken()
Email taken.
public
emailTaken(MemberSearchService $searchService, RequestRateLimiter $rateLimiter) : mixed
Parameters
- $searchService : MemberSearchService
- $rateLimiter : RequestRateLimiter
forgotPassword()
Forgot password.
public
forgotPassword(MemberAuthenticationService $authService) : mixed
Parameters
- $authService : MemberAuthenticationService
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|voidgridData()
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|voidimpersonate()
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
Return values
Response|nullimportExpirationDates()
Import membership or background-check expiration dates from CSV.
public
importExpirationDates(MemberExpirationImportService $importService) : Response|null
Parameters
- $importService : MemberExpirationImportService
-
Import workflow
Return values
Response|nullindex()
Display member listing with Dataverse grid (saved views, filters, sorting).
public
index() : Response|null|void
Return values
Response|null|voidinitialize()
Load shared components: Authentication, Authorization, Flash.
public
initialize() : void
isCsvRequest()
Check if current request is for CSV export.
public
isCsvRequest() : bool
Return values
boollogin()
login logic
public
login(MemberAuthenticationService $authService, QuickLoginDeviceService $quickLoginService) : mixed
Parameters
- $authService : MemberAuthenticationService
- $quickLoginService : QuickLoginDeviceService
logout()
Logout.
public
logout() : mixed
membershipCard()
Stream a membership verification card after verifier authorization.
public
membershipCard(MemberRegistrationService $registrationService[, int|null $id = null ]) : Response
Parameters
- $registrationService : MemberRegistrationService
- $id : int|null = null
Return values
ResponsemobileCardPhoto()
Stream the authenticated member's mobile profile photo.
public
mobileCardPhoto(MemberProfileService $profileService) : Response
Parameters
- $profileService : MemberProfileService
Return values
Response —Inline file response
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
register()
Register.
public
register(MemberRegistrationService $regService, TriggerDispatcher $dispatcher) : mixed
Parameters
- $regService : MemberRegistrationService
- $dispatcher : TriggerDispatcher
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
ResponserequestMembershipCardReupload()
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|nullresetPassword()
Reset password.
public
resetPassword(MemberAuthenticationService $authService[, mixed $token = null ]) : mixed
Parameters
- $authService : MemberAuthenticationService
- $token : mixed = null
revokeSessions()
Revoke all sessions and PIN devices using the existing password-management permission.
public
revokeSessions(MemberAuthenticationService $authService[, mixed $id = null ]) : mixed
Parameters
- $authService : MemberAuthenticationService
- $id : mixed = 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|voidsearchMembers()
Search members.
public
searchMembers(MemberSearchService $searchService, RequestRateLimiter $rateLimiter) : mixed
Parameters
- $searchService : MemberSearchService
- $rateLimiter : RequestRateLimiter
security()
Render member-authorized security actions in the shared dialog.
public
security([mixed $id = null ]) : Response|null
Parameters
- $id : mixed = null
Return values
Response|nullsendMobileCardEmail()
Send mobile card email.
public
sendMobileCardEmail(MemberProfileService $profileService[, mixed $id = null ]) : mixed
Parameters
- $profileService : MemberProfileService
- $id : mixed = null
setupQuickLoginPin()
Collect and save a quick-login PIN after a successful password login.
public
setupQuickLoginPin(QuickLoginDeviceService $quickLoginService) : Response|null|void
Parameters
- $quickLoginService : QuickLoginDeviceService
Return values
Response|null|voidstopImpersonating()
Stop impersonating and restore original super user identity.
public
stopImpersonating(ImpersonationService $impersonationService) : Response|null
Parameters
- $impersonationService : ImpersonationService
-
Session helper
Return values
Response|nullsubmitScaMemberInfo()
Submit sca member info.
public
submitScaMemberInfo(MemberRegistrationService $regService) : mixed
Parameters
- $regService : MemberRegistrationService
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
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
uploadProfilePhoto()
Upload and assign a member profile photo.
public
uploadProfilePhoto(MemberProfileService $profileService) : Response
Parameters
- $profileService : MemberProfileService
Return values
Response —Redirect response
verifyMembership()
Verify membership.
public
verifyMembership(MemberRegistrationService $registrationService, TriggerDispatcher $dispatcher[, mixed $id = null ]) : mixed
Parameters
- $registrationService : MemberRegistrationService
- $dispatcher : TriggerDispatcher
- $id : mixed = null
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|voidverifyQueueGridData()
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|voidview()
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
Return values
Response|null|voidviewCard()
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:
- Canonical current filter state (query parameters plus enforced locked values)
- Saved user view configuration (when loading a saved view)
- 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|nullassertSafeContextUrl()
Ensure URL is same-origin relative path + query only.
protected
assertSafeContextUrl(string $url) : string
Parameters
- $url : string
Tags
Return values
stringauthorizeCurrentUrl()
Authorize the current URL/action via Authorization component.
protected
authorizeCurrentUrl() : void
Tags
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>|nullbuildDataverseGridState()
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
stringconsumeFlashForStream()
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:
- exportValue callback if defined in column metadata
- renderField path for nested entity access (e.g., 'member.name_for_herald')
- 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|nullextractStringContextValue()
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|nullextractSystemViewDefaults()
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|nullgetVerifyQueueSystemViewCounts()
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:
-
Query Mode (default): Uses the query from result to build SQL SELECT statements. Best for simple fields that map directly to database columns.
-
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):
exportValuecallback in column metadata - custom formatting functionrenderFieldpath (e.g., 'member.name_for_herald') - for nested entity accessqueryFieldfor relation columns in query mode- 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
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
boolloadAvailableViews()
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:
-
Simple string (table name): Uses 'id' for value, 'name' for label
'filterOptionsSource' => 'Branches' -
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) ] -
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.
-
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
boolmobileQueuePagination()
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
baseQueryMUST 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
Return values
MailerqueueMailJob()
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
stringrenderTurboCloseModal()
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
ResponserenderTurboFlashOnly()
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
ResponserenderTurboReloadFrame()
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
ResponserenderTurboRemoveGridRow()
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
ResponserenderTurboReplaceGridRow()
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
ResponseresolveBranchIdFromContextMember()
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|nullresolveDataverseGridQueryContext()
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
DataverseGridQueryContextresolveKingdomId()
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
Return values
MailerwantsTurboStreamRequest()
Whether the client expects a turbo-stream response.
protected
wantsTurboStreamRequest() : bool
Return values
boolwithPageContextQuery()
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
Return values
TapplyDataverseGridSort()
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.
cleanupMembershipCardUpload()
Remove a newly uploaded card after its owning workflow fails.
private
cleanupMembershipCardUpload(MemberRegistrationService $registrationService, int $documentId, string $context) : void
Parameters
- $registrationService : MemberRegistrationService
- $documentId : int
- $context : string
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
stringdefaultPostLoginRedirectTarget()
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|nullfindActiveDefinition()
Find an active workflow definition by slug.
private
findActiveDefinition(string $slug) : WorkflowDefinition|null
Parameters
- $slug : string
-
Workflow definition slug
Return values
WorkflowDefinition|nullflagQuickLoginOutOfSync()
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
boolisQuickLoginAccountEligible()
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
boollegacyIndex()
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|nullnormalizeDataverseGridColumnConfig()
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|nullredirectAfterSuccessfulLogin()
Redirect after successful login.
private
redirectAfterSuccessfulLogin() : Response
Return values
ResponserequestEtagMatches()
Check If-None-Match using weak comparison semantics.
private
requestEtagMatches(string $etag) : bool
Parameters
- $etag : string
Return values
boolresolveDataverseGridActiveColumns()
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: arrayresolveDataverseGridVisibleColumns()
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>|stringserveProfilePhoto()
Serve a cached profile-photo thumbnail after action-level authorization.
private
serveProfilePhoto(MemberProfileService $profileService, Member $member, string $filenamePrefix) : Response
Parameters
- $profileService : MemberProfileService
- $member : Member
- $filenamePrefix : string
Return values
ResponsesetAddFormViewVars()
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