Skip to content

Commit 7f67b24

Browse files
committed
Document the lifecycle of forms/pages
Closes #562
1 parent 50c4116 commit 7f67b24

1 file changed

Lines changed: 220 additions & 0 deletions

File tree

docs/php/pages.md

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,34 @@
44

55
The default implementation for pages to present any sort of content, but are designed to handle `GET` requests only. They usually follow a fixed method chain that will be invoked one after another, adding logical sections to the request flow.
66

7+
### Lifecycle
8+
9+
The following diagram shows the exact order in which methods are called and events are fired when a page is requested.
10+
11+
```
12+
__run()
13+
14+
├─ readParameters()
15+
│ └─ Event: readParameters
16+
17+
└─ show()
18+
├─ checkModules()
19+
│ └─ Event: checkModules
20+
21+
├─ checkPermissions()
22+
│ └─ Event: checkPermissions
23+
24+
├─ readData()
25+
│ └─ Event: readData
26+
27+
├─ assignVariables()
28+
│ └─ Event: assignVariables
29+
30+
├─ Event: show
31+
32+
└─ [Template rendering]
33+
```
34+
735
### Method Chain
836

937
#### \__run()
@@ -70,6 +98,84 @@ public function assignVariables() {
7098

7199
Extends the AbstractPage implementation with additional methods designed to handle form submissions properly.
72100

101+
### Lifecycle
102+
103+
`AbstractForm` overrides `readData()` to inject the form submission handling. The submission methods (`submit()` through `save()`) are only called when `$_POST` or `$_FILES` are not empty, i.e. the form was actually submitted.
104+
105+
#### Initial Page Load (GET)
106+
107+
When the form is loaded for the first time (no submission), the lifecycle is identical to `AbstractPage`:
108+
109+
```
110+
__run()
111+
112+
├─ readParameters()
113+
│ └─ Event: readParameters
114+
115+
└─ show()
116+
├─ checkModules()
117+
│ └─ Event: checkModules
118+
119+
├─ checkPermissions()
120+
│ └─ Event: checkPermissions
121+
122+
├─ readData()
123+
│ │ (no POST/FILES data, submission is skipped)
124+
│ └─ Event: readData
125+
126+
├─ assignVariables()
127+
│ └─ Event: assignVariables
128+
129+
├─ Event: show
130+
131+
└─ [Template rendering]
132+
```
133+
134+
#### Form Submission (POST)
135+
136+
When the form is submitted, the submission methods are called within `readData()` before the inherited `readData()` logic:
137+
138+
```
139+
__run()
140+
141+
├─ readParameters()
142+
│ └─ Event: readParameters
143+
144+
└─ show()
145+
├─ checkModules()
146+
│ └─ Event: checkModules
147+
148+
├─ checkPermissions()
149+
│ └─ Event: checkPermissions
150+
151+
├─ readData()
152+
│ ├─ submit() ← only if $_POST or $_FILES are not empty
153+
│ │ ├─ Event: submit
154+
│ │ │
155+
│ │ ├─ readFormParameters()
156+
│ │ │ └─ Event: readFormParameters
157+
│ │ │
158+
│ │ ├─ validate()
159+
│ │ │ ├─ Event: validate
160+
│ │ │ └─ validateSecurityToken()
161+
│ │ │
162+
│ │ └─ save() ← only if validate() did not throw
163+
│ │ ├─ Event: save
164+
│ │ └─ saved() ← must be called manually
165+
│ │ └─ Event: saved
166+
│ │
167+
│ └─ Event: readData
168+
169+
├─ assignVariables()
170+
│ └─ Event: assignVariables
171+
172+
├─ Event: show
173+
174+
└─ [Template rendering]
175+
```
176+
177+
!!! info "If `validate()` throws a `UserInputException`, `save()` is skipped and the form is re-displayed with error messages. The exception is caught internally by `submit()`."
178+
73179
### Method Chain
74180

75181
#### \__run()
@@ -125,3 +231,117 @@ The only purpose of this method is to fire the event `saved` that signals that t
125231
#### assignVariables()
126232

127233
*Inherited from AbstractPage.*
234+
235+
## AbstractFormBuilderForm
236+
237+
Extends `AbstractForm` with the [Form Builder](api/form_builder/overview.md) API, which automates form creation, validation, and data handling. The key difference from `AbstractForm` is that `buildForm()` is called during `checkPermissions()`, and form field processing is handled automatically by the form document.
238+
239+
### Lifecycle
240+
241+
#### Initial Page Load (GET)
242+
243+
```
244+
__run()
245+
246+
├─ readParameters()
247+
│ └─ Event: readParameters
248+
249+
└─ show()
250+
├─ checkModules()
251+
│ └─ Event: checkModules
252+
253+
├─ checkPermissions()
254+
│ ├─ Event: checkPermissions
255+
│ │
256+
│ └─ buildForm()
257+
│ ├─ createForm()
258+
│ ├─ Event: createForm
259+
│ ├─ form->build()
260+
│ ├─ finalizeForm()
261+
│ └─ Event: buildForm
262+
263+
├─ readData()
264+
│ ├─ setFormObjectData() ← only if $formObject is set (edit mode)
265+
│ │ └─ form->updatedObject()
266+
│ │ (no POST/FILES data, submission is skipped)
267+
│ ├─ Event: readData
268+
│ └─ setFormAction()
269+
270+
├─ assignVariables()
271+
│ └─ Event: assignVariables
272+
273+
├─ Event: show
274+
275+
└─ [Template rendering]
276+
```
277+
278+
#### Form Submission (POST)
279+
280+
```
281+
__run()
282+
283+
├─ readParameters()
284+
│ └─ Event: readParameters
285+
286+
└─ show()
287+
├─ checkModules()
288+
│ └─ Event: checkModules
289+
290+
├─ checkPermissions()
291+
│ ├─ Event: checkPermissions
292+
│ │
293+
│ └─ buildForm()
294+
│ ├─ createForm()
295+
│ ├─ Event: createForm
296+
│ ├─ form->build()
297+
│ ├─ finalizeForm()
298+
│ └─ Event: buildForm
299+
300+
├─ readData()
301+
│ ├─ setFormObjectData() ← only if $formObject is set (edit mode)
302+
│ │ └─ form->updatedObject()
303+
│ │
304+
│ ├─ submit() ← only if $_POST or $_FILES are not empty
305+
│ │ ├─ Event: submit
306+
│ │ │
307+
│ │ ├─ readFormParameters()
308+
│ │ │ ├─ Event: readFormParameters
309+
│ │ │ └─ form->readValues()
310+
│ │ │
311+
│ │ ├─ validate()
312+
│ │ │ ├─ Event: validate
313+
│ │ │ └─ form->validate()
314+
│ │ │
315+
│ │ └─ save() ← only if validate() did not throw
316+
│ │ ├─ Event: save
317+
│ │ ├─ [objectAction: create/update]
318+
│ │ └─ saved() ← called automatically
319+
│ │ ├─ Event: saved
320+
│ │ ├─ form->cleanup() ← only for create action
321+
│ │ ├─ buildForm() ← only for create action (rebuilds the form)
322+
│ │ └─ form->showSuccessMessage()
323+
│ │
324+
│ ├─ Event: readData
325+
│ └─ setFormAction()
326+
327+
├─ assignVariables()
328+
│ └─ Event: assignVariables
329+
330+
├─ Event: show
331+
332+
└─ [Template rendering]
333+
```
334+
335+
### Key Differences from AbstractForm
336+
337+
| Aspect | `AbstractForm` | `AbstractFormBuilderForm` |
338+
|--------|---------------|--------------------------|
339+
| Form structure | Manual HTML templates | Defined in `createForm()` using PHP |
340+
| Form building | N/A | `buildForm()` called during `checkPermissions()` |
341+
| Reading POST data | Manual in `readFormParameters()` | Automatic via `form->readValues()` |
342+
| Validation | Manual in `validate()` | Automatic via `form->validate()` |
343+
| Saving | Manual in `save()` | Automatic via `$objectActionClass` |
344+
| `saved()` | Must be called manually | Called automatically |
345+
| Security token | `validateSecurityToken()` | Handled by the form document |
346+
347+
For more details on form builder components, see the [Form Builder documentation](api/form_builder/overview.md).

0 commit comments

Comments
 (0)