Forms
In CakePHP a form is built by the Form helper. It receives an entity and chooses the field type by the column type, fills in current values, shows validation errors and adds a protection token.
The form template
Create the file templates/Articles/add.php:
<h1>New article</h1>
<?= $this->Form->create($article) ?>
<?= $this->Form->control('title') ?>
<?= $this->Form->button('Save') ?>
<?= $this->Form->end() ?>create() opens the form tag, control() outputs a label, a field and a place for an error, and end() closes the form.
The action
// src/Controller/ArticlesController.php
public function add()
{
$article = $this->Articles->newEmptyEntity();
if ($this->request->is('post')) {
$article = $this->Articles->patchEntity($article, $this->request->getData());
if ($this->Articles->save($article)) {
return $this->redirect(['action' => 'index']);
}
}
$this->set(compact('article'));
}One action both shows the form and handles it. Open /articles/add, enter a title and press the button: you land on the list with the new article. If an empty form is submitted, saving fails, the entity with errors returns to the template and "Enter a title." appears under the field.
More fields
<fieldset>
<?= $this->Form->control('title', ['label' => 'Title']) ?>
<?= $this->Form->control('body', ['label' => 'Text', 'rows' => 8]) ?>
<?= $this->Form->control('published', ['label' => 'Publish']) ?>
</fieldset>A text column gives a textarea and a boolean column gives a checkbox. The second argument sets the label and field attributes.
Field options
| Option | What it does |
|---|---|
'label' => 'Title' | The label text |
'type' => 'email' | The field type: email, password, number, date |
'options' => ['a' => 'A', 'b' => 'B'] | A drop-down list |
'empty' => 'Choose…' | An empty list item |
'required' => false | Removes the required attribute |
Editing a record
public function edit(int $id)
{
$article = $this->Articles->get($id);
if ($this->request->is(['patch', 'post', 'put'])) {
$this->Articles->patchEntity($article, $this->request->getData());
if ($this->Articles->save($article)) {
return $this->redirect(['action' => 'index']);
}
}
$this->set(compact('article'));
}The templates/Articles/edit.php template contains the same form. Given an existing entity, Form->create() fills the fields with its values. The address /articles/edit/1 opens the form of the first article.
The delete button
Deleting must be sent with the POST method. The helper creates a hidden form for a link:
<p>
<?= $this->Form->postLink(
'Delete',
['action' => 'delete', $article->id],
['confirm' => 'Delete the article?'],
) ?>
</p>The browser asks for confirmation before sending. The delete() action gets the record with get($id), calls $this->Articles->delete($article) and redirects to the list.
CSRF protection
CSRF is an attack in which another site submits a form on behalf of a visitor. In a new project the protection is already enabled in src/Application.php: Form->create() adds a hidden field with a token to the form, and a request without it is rejected.
Common mistake
A form written with plain <form> and <input> tags is rejected by CakePHP with a CSRF token error: it has no hidden field. Use the Form helper and do not forget Form->end().