ApprovalsController
extends AppController
in package
uses
DataverseGridTrait
Approvals Controller
Manages user approvals and admin approval management.
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'
- BESTOWAL_GATHERING_REQUIRED_KEY : mixed = 'requires_bestowal_gathering'
- BESTOWAL_GATHERING_WORKFLOW_SLUGS : mixed = ['awards-recommendation-submitted', 'awards-exi...
Properties
- $WorkflowApprovals : WorkflowApprovalsTable
- $defaultTable : string|null
- $isCsvRequest : bool
- $pluginViewCells : array<string|int, mixed>
- $pluginViewCellsEnabledForFragment : bool
- Whether an intentionally fragment-style response still needs plugin view cells.
- $approvalManager : WorkflowApprovalManagerInterface
- $awardApprovalFinalStepCache : array<string, bool|null>
- $awardsRecommendationIdsByWorkflowInstanceId : array<int, int|null>
- $bestowalGatheringOptions : array<string|int, mixed>|null
- $engine : WorkflowEngineInterface
- $recommendationApprovalProcessService : RecommendationApprovalProcessService|null
Methods
- __construct() : mixed
- Constructor.
- allApprovals() : Response|null|void
- Admin view: all approvals across the system.
- allApprovalsGridData() : Response|null|void
- Grid data endpoint for the admin All Approvals DataverseGrid.
- approvalByToken() : Response|null|void
- Token-based deep link for email-based approval access.
- approvalDetail() : Response|null|void
- API: Get approval detail context for the expandable panel.
- approvals() : Response|null|void
- Approval dashboard entry point.
- approvalsGridData() : Response|null|void
- Grid data endpoint for the My Approvals DataverseGrid.
- approvalsKanbanLaneData() : Response|null|void
- Lane frame endpoint for the approval triage Kanban board.
- beforeFilter() : Response|null|void
- Pre-action filter for application-wide processing.
- beforeRender() : Response|null|void
- Finalize view-only data after the action has run.
- bestowalGatheringsAutoComplete() : void
- Return future gathering autocomplete options for approval-created bestowals.
- eligibleApprovers() : Response|null|void
- API: Return eligible approvers for a serial-pick-next workflow approval.
- initialize() : void
- Initialize controller authorization.
- isCsvRequest() : bool
- Check if current request is for CSV export.
- mobileApprovals() : Response|null|void
- Mobile-optimized approval dashboard.
- mobileApprovalsData() : Response|null|void
- JSON API: Pending approvals with rich context for mobile UI.
- reassignApproval() : Response|null|void
- Admin API: Reassign a pending approval to a different eligible member.
- recordApproval() : Response|null|void
- API: Record an approval response and optionally resume workflow.
- switchView() : Response
- Switch between mobile and desktop view modes.
- updateTriage() : Response|null|void
- API: create or update the current member's private approval triage state.
- applyCustomFilterHandlers() : SelectQuery
- Apply custom filter handlers for columns with complex filtering logic
- 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.
- enablePluginViewCellsForFragment() : void
- Include route-matched plugin cells in an AJAX or other fragment response.
- 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.
- 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.
- 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
- 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.
- resolveDataverseGridQueryContext() : DataverseGridQueryContext
- Resolve Dataverse grid column context for early query construction.
- resolveNestedValue() : mixed
- Resolve nested value from entity using dot notation path
- 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.
- applyWorkflowFilterOptionsToGridResult() : array<string, mixed>
- Add request-scoped Workflow dropdown options to a My Approvals grid result.
- approvalRequiresBestowalGatheringSelection() : bool
- Determine whether this approval creates an award bestowal that must be scheduled to a gathering.
- approvalResponseFailure() : Response|null|void
- Return a consistent failure response for single and bulk approval modal posts.
- augmentApproverConfigForResponse() : array<string, mixed>
- awardApprovalFinalStepState() : bool|null
- buildApprovalKanbanLane() : array<string, mixed>
- buildApprovalKanbanLanes() : array<int, array<string, mixed>>
- collectDataverseExpressionColumnKeys() : void
- columnKeyForDataverseField() : string
- defaultTriagePayload() : array<string, mixed>
- extractDataverseGridConfigColumnKeys() : array<int, string>
- formatTriagePayload() : array<string, mixed>
- formatValidationErrors() : string
- getApprovalKanbanCardActions() : array<string, array<string, mixed>>
- getApprovalManager() : WorkflowApprovalManagerInterface
- Get the injected approval manager.
- getApprovalResponseModalPayload() : array<string, mixed>
- Return a JSON-safe payload the bulk modal can reuse from the first selected approval.
- getApprovalResponseTypeKey() : string
- Hash the modal-affecting approval configuration so bulk responses cannot mix types.
- getAwardsRecommendationIdForApproval() : int|null
- Resolve the Awards recommendation context for approval responses, when present.
- getBestowalGatheringOptions() : array<int, array{id: int, label: string}>
- getPostedBestowalGatheringId() : int|null
- Read the optional approval-selected bestowal gathering ID from the posted form data.
- getTriagePayload() : array<string, mixed>
- getTriagePayloads() : array<int, array<string, mixed>>
- getWorkflowEngine() : WorkflowEngineInterface
- Get the injected workflow engine.
- handleApprovalResponseSideEffects() : void
- Apply workflow side effects after a successful approval response.
- isApprovalKanbanView() : bool
- isApprovalPendingForMember() : bool
- isDataverseGridNumericSearchColumn() : bool
- isEscapedAmpersandQueryKey() : bool
- Detect keys like amp;page or amp%3Btriage_state created by repeated HTML entity encoding.
- isSelectableBestowalGathering() : bool
- Check that a selected bestowal gathering is still available for scheduling.
- isSelectableBestowalGatheringForApproval() : bool
- Check award/activity eligibility when the approval belongs to a recommendation workflow.
- jsonResponse() : Response
- normalizeDataverseGridColumnConfig() : array<int, string>
- normalizeLockedDateBoundary() : string|null
- Normalize a persisted date boundary while retaining an intentionally open bound.
- parseBulkApprovalIds() : array<string|int, int>
- prepareApprovalsForGrid() : void
- Add computed approval grid fields only when their columns are visible.
- prepareApprovalsForKanbanCards() : void
- Add lightweight card fields for approval Kanban lanes.
- recordBulkApprovalResponses() : Response|null|void
- Apply one modal response to multiple same-type approvals.
- recordSingleApprovalResponse() : ServiceResult
- Record one approval response without applying controller response handling.
- requiresBestowalGatheringSelection() : bool
- resolveApprovalsGridSyncContext() : array{tableFrameId: string, gridKey: string}|null
- 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().
- resolveEntityContext() : array<string|int, mixed>
- Resolve entity details from workflow instance for display.
- sanitizeApprovalKanbanQueryParams() : array<string, mixed>
- Remove query keys produced by escaped ampersands being reused as literal URL params.
- tryApprovalsGridTurboResponse() : Response|null
- Render a Turbo Stream refresh for the current approvals grid table.
- validateBestowalGatheringSelection() : string|null
- Validate the gathering selection for approval types that create scheduled bestowals.
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
BESTOWAL_GATHERING_REQUIRED_KEY
private
mixed
BESTOWAL_GATHERING_REQUIRED_KEY
= 'requires_bestowal_gathering'
BESTOWAL_GATHERING_WORKFLOW_SLUGS
private
mixed
BESTOWAL_GATHERING_WORKFLOW_SLUGS
= ['awards-recommendation-submitted', 'awards-existing-recommendation-approval']
Properties
$WorkflowApprovals
public
WorkflowApprovalsTable
$WorkflowApprovals
$defaultTable
protected
string|null
$defaultTable
= 'WorkflowApprovals'
$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
$approvalManager
private
WorkflowApprovalManagerInterface
$approvalManager
$awardApprovalFinalStepCache
private
array<string, bool|null>
$awardApprovalFinalStepCache
= []
$awardsRecommendationIdsByWorkflowInstanceId
private
array<int, int|null>
$awardsRecommendationIdsByWorkflowInstanceId
= []
$bestowalGatheringOptions
private
array<string|int, mixed>|null
$bestowalGatheringOptions
= null
$engine
private
WorkflowEngineInterface
$engine
$recommendationApprovalProcessService
private
RecommendationApprovalProcessService|null
$recommendationApprovalProcessService
= null
Methods
__construct()
Constructor.
public
__construct(ServerRequest $request, WorkflowEngineInterface $engine, WorkflowApprovalManagerInterface $approvalManager[, ComponentRegistry|null $components = null ]) : mixed
Parameters
- $request : ServerRequest
-
Request
- $engine : WorkflowEngineInterface
-
Workflow engine
- $approvalManager : WorkflowApprovalManagerInterface
-
Approval manager
- $components : ComponentRegistry|null = null
-
Component registry
allApprovals()
Admin view: all approvals across the system.
public
allApprovals() : Response|null|void
Return values
Response|null|voidallApprovalsGridData()
Grid data endpoint for the admin All Approvals DataverseGrid.
public
allApprovalsGridData() : Response|null|void
Return values
Response|null|voidapprovalByToken()
Token-based deep link for email-based approval access.
public
approvalByToken(string $token) : Response|null|void
Parameters
- $token : string
-
Approval token from email
Return values
Response|null|voidapprovalDetail()
API: Get approval detail context for the expandable panel.
public
approvalDetail(int $approvalId) : Response|null|void
Parameters
- $approvalId : int
-
Workflow approval ID
Return values
Response|null|voidapprovals()
Approval dashboard entry point.
public
approvals() : Response|null|void
Return values
Response|null|voidapprovalsGridData()
Grid data endpoint for the My Approvals DataverseGrid.
public
approvalsGridData() : Response|null|void
Return values
Response|null|voidapprovalsKanbanLaneData()
Lane frame endpoint for the approval triage Kanban board.
public
approvalsKanbanLaneData() : Response|null|void
Return values
Response|null|voidbeforeFilter()
Pre-action filter for application-wide processing.
public
beforeFilter(EventInterface $event) : Response|null|void
Handles: plugin validation, navigation history, view cell loading, and Turbo Frame detection.
Parameters
- $event : EventInterface
-
The beforeFilter event
Return values
Response|null|voidbeforeRender()
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|voidbestowalGatheringsAutoComplete()
Return future gathering autocomplete options for approval-created bestowals.
public
bestowalGatheringsAutoComplete(BestowalGatheringLookupService $lookupService) : void
Parameters
- $lookupService : BestowalGatheringLookupService
-
Gathering lookup service.
eligibleApprovers()
API: Return eligible approvers for a serial-pick-next workflow approval.
public
eligibleApprovers(int $approvalId) : Response|null|void
Parameters
- $approvalId : int
-
Workflow approval ID
Return values
Response|null|voidinitialize()
Initialize controller authorization.
public
initialize() : void
isCsvRequest()
Check if current request is for CSV export.
public
isCsvRequest() : bool
Return values
boolmobileApprovals()
Mobile-optimized approval dashboard.
public
mobileApprovals() : Response|null|void
Return values
Response|null|voidmobileApprovalsData()
JSON API: Pending approvals with rich context for mobile UI.
public
mobileApprovalsData() : Response|null|void
Return values
Response|null|voidreassignApproval()
Admin API: Reassign a pending approval to a different eligible member.
public
reassignApproval() : Response|null|void
Return values
Response|null|voidrecordApproval()
API: Record an approval response and optionally resume workflow.
public
recordApproval(RecommendationFeedbackService $feedbackService) : Response|null|void
Parameters
- $feedbackService : RecommendationFeedbackService
Return values
Response|null|voidswitchView()
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
updateTriage()
API: create or update the current member's private approval triage state.
public
updateTriage() : Response|null|void
Return values
Response|null|voidapplyCustomFilterHandlers()
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
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
enablePluginViewCellsForFragment()
Include route-matched plugin cells in an AJAX or other fragment response.
protected
enablePluginViewCellsForFragment() : void
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.
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|nullhandleCsvExport()
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.
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
ResponseresolveDataverseGridQueryContext()
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
DataverseGridQueryContextresolveNestedValue()
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
wantsTurboStreamRequest()
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.
applyWorkflowFilterOptionsToGridResult()
Add request-scoped Workflow dropdown options to a My Approvals grid result.
private
applyWorkflowFilterOptionsToGridResult(array<string, mixed> $result, array<int, string> $workflowNames) : array<string, mixed>
Parameters
- $result : array<string, mixed>
-
Dataverse grid result.
- $workflowNames : array<int, string>
-
Workflow names available to the member.
Return values
array<string, mixed>approvalRequiresBestowalGatheringSelection()
Determine whether this approval creates an award bestowal that must be scheduled to a gathering.
private
approvalRequiresBestowalGatheringSelection(WorkflowApproval|null $approval, array<string, mixed> $approverConfig) : bool
Older pending approvals may have been created before the workflow node included requires_bestowal_gathering, so the workflow slug is the compatibility fallback.
Parameters
- $approval : WorkflowApproval|null
-
Approval.
- $approverConfig : array<string, mixed>
-
Approval config.
Return values
boolapprovalResponseFailure()
Return a consistent failure response for single and bulk approval modal posts.
private
approvalResponseFailure(string $error) : Response|null|void
Parameters
- $error : string
Return values
Response|null|voidaugmentApproverConfigForResponse()
private
augmentApproverConfigForResponse(array<string, mixed> $approverConfig[, WorkflowApproval|null $approval = null ]) : array<string, mixed>
Parameters
- $approverConfig : array<string, mixed>
-
Approval config.
- $approval : WorkflowApproval|null = null
Return values
array<string, mixed>awardApprovalFinalStepState()
private
awardApprovalFinalStepState(WorkflowApproval $approval, array<string, mixed> $approverConfig) : bool|null
Parameters
- $approval : WorkflowApproval
-
Approval.
- $approverConfig : array<string, mixed>
-
Approval config.
Return values
bool|nullbuildApprovalKanbanLane()
private
buildApprovalKanbanLane(string $state) : array<string, mixed>
Parameters
- $state : string
-
Triage state.
Return values
array<string, mixed>buildApprovalKanbanLanes()
private
buildApprovalKanbanLanes() : array<int, array<string, mixed>>
Return values
array<int, array<string, mixed>>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
stringdefaultTriagePayload()
private
defaultTriagePayload() : array<string, mixed>
Return values
array<string, mixed>extractDataverseGridConfigColumnKeys()
private
extractDataverseGridConfigColumnKeys(array<string, mixed> $config) : array<int, string>
Parameters
- $config : array<string, mixed>
Return values
array<int, string>formatTriagePayload()
private
formatTriagePayload(EntityInterface $triage) : array<string, mixed>
Parameters
- $triage : EntityInterface
-
Triage entity
Return values
array<string, mixed>formatValidationErrors()
private
formatValidationErrors(array<string, mixed> $errors) : string
Parameters
- $errors : array<string, mixed>
-
Entity validation/rule errors
Return values
stringgetApprovalKanbanCardActions()
private
getApprovalKanbanCardActions() : array<string, array<string, mixed>>
Return values
array<string, array<string, mixed>>getApprovalManager()
Get the injected approval manager.
private
getApprovalManager() : WorkflowApprovalManagerInterface
Return values
WorkflowApprovalManagerInterfacegetApprovalResponseModalPayload()
Return a JSON-safe payload the bulk modal can reuse from the first selected approval.
private
getApprovalResponseModalPayload(WorkflowApproval $approval[, array<string|int, mixed>|null $approverConfig = null ]) : array<string, mixed>
Parameters
- $approval : WorkflowApproval
- $approverConfig : array<string|int, mixed>|null = null
Return values
array<string, mixed>getApprovalResponseTypeKey()
Hash the modal-affecting approval configuration so bulk responses cannot mix types.
private
getApprovalResponseTypeKey(WorkflowApproval $approval[, array<string|int, mixed>|null $approverConfig = null ]) : string
Parameters
- $approval : WorkflowApproval
- $approverConfig : array<string|int, mixed>|null = null
Return values
stringgetAwardsRecommendationIdForApproval()
Resolve the Awards recommendation context for approval responses, when present.
private
getAwardsRecommendationIdForApproval(WorkflowApproval|null $approval) : int|null
Parameters
- $approval : WorkflowApproval|null
-
Approval entity.
Return values
int|nullgetBestowalGatheringOptions()
private
getBestowalGatheringOptions() : array<int, array{id: int, label: string}>
Return values
array<int, array{id: int, label: string}>getPostedBestowalGatheringId()
Read the optional approval-selected bestowal gathering ID from the posted form data.
private
getPostedBestowalGatheringId() : int|null
Return values
int|nullgetTriagePayload()
private
getTriagePayload(int $approvalId, int $memberId) : array<string, mixed>
Parameters
- $approvalId : int
-
Workflow approval ID
- $memberId : int
-
Member ID
Return values
array<string, mixed>getTriagePayloads()
private
getTriagePayloads(array<string|int, int> $approvalIds, int $memberId) : array<int, array<string, mixed>>
Parameters
- $approvalIds : array<string|int, int>
-
Workflow approval IDs
- $memberId : int
-
Member ID
Return values
array<int, array<string, mixed>>getWorkflowEngine()
Get the injected workflow engine.
private
getWorkflowEngine() : WorkflowEngineInterface
Return values
WorkflowEngineInterfacehandleApprovalResponseSideEffects()
Apply workflow side effects after a successful approval response.
private
handleApprovalResponseSideEffects(ServiceResult $result, int $memberId, string $decision, mixed $comment[, int|null $bestowalGatheringId = null ]) : void
Parameters
- $result : ServiceResult
- $memberId : int
- $decision : string
- $comment : mixed
- $bestowalGatheringId : int|null = null
isApprovalKanbanView()
private
isApprovalKanbanView(array<string, mixed> $gridState) : bool
Parameters
- $gridState : array<string, mixed>
-
Grid state.
Return values
boolisApprovalPendingForMember()
private
isApprovalPendingForMember(int $approvalId, int $memberId) : bool
Parameters
- $approvalId : int
-
Workflow approval ID
- $memberId : int
-
Member ID
Return values
boolisDataverseGridNumericSearchColumn()
private
isDataverseGridNumericSearchColumn(array<string, mixed>|null $columnMeta) : bool
Parameters
- $columnMeta : array<string, mixed>|null
-
Column metadata.
Return values
boolisEscapedAmpersandQueryKey()
Detect keys like amp;page or amp%3Btriage_state created by repeated HTML entity encoding.
private
isEscapedAmpersandQueryKey(string $key) : bool
Parameters
- $key : string
-
Query parameter key.
Return values
boolisSelectableBestowalGathering()
Check that a selected bestowal gathering is still available for scheduling.
private
isSelectableBestowalGathering(int $gatheringId) : bool
Parameters
- $gatheringId : int
-
Gathering ID.
Return values
boolisSelectableBestowalGatheringForApproval()
Check award/activity eligibility when the approval belongs to a recommendation workflow.
private
isSelectableBestowalGatheringForApproval(WorkflowApproval $approval, int $gatheringId) : bool
Parameters
- $approval : WorkflowApproval
-
Approval being answered.
- $gatheringId : int
-
Gathering ID.
Return values
booljsonResponse()
private
jsonResponse(array<string, mixed> $payload[, int $status = 200 ]) : Response
Parameters
- $payload : array<string, mixed>
-
JSON payload
- $status : int = 200
-
HTTP status
Return values
ResponsenormalizeDataverseGridColumnConfig()
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|nullparseBulkApprovalIds()
private
parseBulkApprovalIds(mixed $rawApprovalIds) : array<string|int, int>
Parameters
- $rawApprovalIds : mixed
-
Posted approval ID list.
Return values
array<string|int, int>prepareApprovalsForGrid()
Add computed approval grid fields only when their columns are visible.
private
prepareApprovalsForGrid(iterable<string|int, WorkflowApproval> $approvals, array<int, string> $visibleColumns) : void
Parameters
- $approvals : iterable<string|int, WorkflowApproval>
- $visibleColumns : array<int, string>
prepareApprovalsForKanbanCards()
Add lightweight card fields for approval Kanban lanes.
private
prepareApprovalsForKanbanCards(iterable<string|int, WorkflowApproval> $approvals, int $memberId) : void
Parameters
- $approvals : iterable<string|int, WorkflowApproval>
-
Approvals.
- $memberId : int
-
Current member ID.
recordBulkApprovalResponses()
Apply one modal response to multiple same-type approvals.
private
recordBulkApprovalResponses(RecommendationFeedbackService $feedbackService, array<string|int, int> $approvalIds) : Response|null|void
Parameters
- $feedbackService : RecommendationFeedbackService
-
Feedback service.
- $approvalIds : array<string|int, int>
-
Selected approval IDs.
Return values
Response|null|voidrecordSingleApprovalResponse()
Record one approval response without applying controller response handling.
private
recordSingleApprovalResponse(WorkflowApproval|null $approval, int $memberId, string $decision, string|null $comment, int|null $nextApproverId, int|null $bestowalGatheringId, RecommendationFeedbackService $feedbackService) : ServiceResult
Parameters
- $approval : WorkflowApproval|null
- $memberId : int
- $decision : string
- $comment : string|null
- $nextApproverId : int|null
- $bestowalGatheringId : int|null
- $feedbackService : RecommendationFeedbackService
Return values
ServiceResultrequiresBestowalGatheringSelection()
private
requiresBestowalGatheringSelection(array<string, mixed> $approverConfig) : bool
Parameters
- $approverConfig : array<string, mixed>
-
Approval config.
Return values
boolresolveApprovalsGridSyncContext()
private
resolveApprovalsGridSyncContext(string|null $pageContextUrl) : array{tableFrameId: string, gridKey: string}|null
Parameters
- $pageContextUrl : string|null
Return values
array{tableFrameId: string, gridKey: string}|nullresolveDataverseGridActiveColumns()
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>resolveEntityContext()
Resolve entity details from workflow instance for display.
private
resolveEntityContext(WorkflowInstance $instance) : array<string|int, mixed>
Parameters
- $instance : WorkflowInstance
Return values
array<string|int, mixed>sanitizeApprovalKanbanQueryParams()
Remove query keys produced by escaped ampersands being reused as literal URL params.
private
sanitizeApprovalKanbanQueryParams(array<string, mixed> $query) : array<string, mixed>
Parameters
- $query : array<string, mixed>
-
Query parameters.
Return values
array<string, mixed>tryApprovalsGridTurboResponse()
Render a Turbo Stream refresh for the current approvals grid table.
private
tryApprovalsGridTurboResponse(string|null $pageContext) : Response|null
Parameters
- $pageContext : string|null
Return values
Response|nullvalidateBestowalGatheringSelection()
Validate the gathering selection for approval types that create scheduled bestowals.
private
validateBestowalGatheringSelection(WorkflowApproval|null $approval, string $decision, int|null $gatheringId) : string|null
Parameters
- $approval : WorkflowApproval|null
-
Approval being answered.
- $decision : string
-
Submitted decision.
- $gatheringId : int|null
-
Selected gathering ID.
Return values
string|null —Error message when invalid.