HelloWorldController
extends AppController
in package
HelloWorld Controller
This controller demonstrates a basic KMP plugin controller with:
- Standard CRUD operations
- Authorization integration
- View rendering with Bootstrap templates
- Flash messaging
- Proper error handling
The HelloWorld controller serves as a template for creating new controllers in KMP plugins. It shows the standard patterns and best practices.
Authorization
Access to controller actions is controlled by HelloWorldPolicy. The controller declares which actions require authorization checking:
- index: Requires view permission
- add: Requires create permission
- edit: Requires update permission
- delete: Requires delete permission
Usage Pattern
All controllers in KMP plugins should:
- Extend AppController for consistent behavior
- Use authorization for security
- Load necessary models in initialize()
- Follow CakePHP conventions
- Use Flash messages for user feedback
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'
Properties
- $HelloWorldItems : HelloWorldItemsTable
- $isCsvRequest : bool
- $pluginViewCells : array<string|int, mixed>
- $pluginViewCellsEnabledForFragment : bool
- Whether an intentionally fragment-style response still needs plugin view cells.
Methods
- add() : Response|null|void
- Add Action - Create New Item
- beforeFilter() : Response|null|void
- Pre-action filter for application-wide processing.
- beforeRender() : Response|null|void
- Finalize view-only data after the action has run.
- delete() : Response|null|void
- Delete Action - Remove Item
- edit() : Response|null|void
- Edit Action - Update Existing Item
- index() : Response|null|void
- Index Action - List View
- initialize() : void
- Initialize Controller
- isCsvRequest() : bool
- Check if current request is for CSV export.
- switchView() : Response
- Switch between mobile and desktop view modes.
- view() : Response|null|void
- View Action - Detail View
- 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.
- 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.
- enablePluginViewCellsForFragment() : void
- Include route-matched plugin cells in an AJAX or other fragment response.
- getPageContextUrl() : string|null
- Posted page context URL (path + query), validated.
- isGridOriginRequest() : bool
- Whether POST originated from a grid index (stay on list).
- 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.
- 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.
- wantsTurboStreamRequest() : bool
- Whether the client expects a turbo-stream response.
- withPageContextQuery() : T
- Run a callback with query params from the posted page context URL.
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
Properties
$HelloWorldItems
public
HelloWorldItemsTable
$HelloWorldItems
$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
Methods
add()
Add Action - Create New Item
public
add() : Response|null|void
Handles the creation of new hello world items.
Authorization
Requires 'add' permission via HelloWorldPolicy
Route
GET/POST /template/hello-world/add
Return values
Response|null|void —Redirects on successful add, renders view otherwise
beforeFilter()
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|voiddelete()
Delete Action - Remove Item
public
delete([string|null $id = null ]) : Response|null|void
Handles deletion of hello world items.
Authorization
Requires 'delete' permission via HelloWorldPolicy
Route
POST /template/hello-world/delete/{id}
Parameters
- $id : string|null = null
-
The item ID
Tags
Return values
Response|null|void —Redirects to index
edit()
Edit Action - Update Existing Item
public
edit([string|null $id = null ]) : Response|null|void
Handles updating existing hello world items.
Authorization
Requires 'edit' permission via HelloWorldPolicy
Route
GET/POST /template/hello-world/edit/{id}
Parameters
- $id : string|null = null
-
The item ID
Tags
Return values
Response|null|void —Redirects on successful edit, renders view otherwise
index()
Index Action - List View
public
index() : Response|null|void
Displays a list of hello world items. In a real controller, this would paginate records from a database table. This template version shows static data as an example.
Authorization
Requires 'index' permission via HelloWorldPolicy
Route
GET /template/hello-world
Return values
Response|null|void —Renders the view
initialize()
Initialize Controller
public
initialize() : void
This method is called before any action is executed. Use it to:
- Load additional models
- Configure components
- Set up authorization rules
- Initialize helpers
isCsvRequest()
Check if current request is for CSV export.
public
isCsvRequest() : bool
Return values
boolswitchView()
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
view()
View Action - Detail View
public
view([string|null $id = null ]) : Response|null|void
Displays details for a single hello world item.
Authorization
Requires 'view' permission via HelloWorldPolicy
Route
GET /template/hello-world/view/{id}
Parameters
- $id : string|null = null
-
The item ID
Tags
Return values
Response|null|void —Renders the view
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
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>enablePluginViewCellsForFragment()
Include route-matched plugin cells in an AJAX or other fragment response.
protected
enablePluginViewCellsForFragment() : void
getPageContextUrl()
Posted page context URL (path + query), validated.
protected
getPageContextUrl() : string|null
Return values
string|nullisGridOriginRequest()
Whether POST originated from a grid index (stay on list).
protected
isGridOriginRequest(string|null $pageContextUrl) : bool
Parameters
- $pageContextUrl : string|null
Return values
boolmatchesGridIndexPath()
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
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
ResponsewantsTurboStreamRequest()
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