Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

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

OptionWhat 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' => falseRemoves 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().

Thanks for reading!

Donate to the site — we work hard for you.