FormHelper mixes POST and PUT requests


I’m not sure if the following is a bug or a feature; I recently updated CakePHP and noticed my edit forms were not working anymore.

I use the same form generating code for new items and editing items (after all, the fields are the same). Say, we have a form for a software release:

$this->Form->input('version', ['label' => 'Version']);
$this->Form->input('description', ['label' => Description']);

The $release variable is set to the string ‘Releases’ for new items and the ORM object when editing. When saving a new item the data sent as a HTTP POST request; there are some extra variables that deal with form security (e.g. _Token) but also a variable ‘_method’ with the value ‘POST’. However, when I edit a release (i.e. the $release variable has an object) the ‘_method’ variable contains ‘PUT’.

This caused my code in my edit() routine to skip because I am checking for a POST:

function edit ($id)
  if ($this->request->is('post'))
     // save data

The question is: do I need to change all my edit() routines to check for both POST and PUT methods now (or just PUT)? Or force a POST in all my forms? I understand the subtle differences between a POST and PUT but since 99.999% of all webforms just use POST it seems a bit overkill to me to make a distinction between the two cases (add vs. edit).

If CakePHP founds data with same model and key (Releases) posted by POST to page where edit form is located, it knows, you want to edit that data and it sets PUT method. PUT is REST standard for editing. Look at recommended edit method structure:

In 3.x the 1st param of FormHelper::create() needs to be a valid context. A string is not a valid context.

Okay, good point. In previous versions you could use a string and that has stuck with me.

Anyway, the real question hasn’t been answered yet: if I reuse the form for both adding and editing, do I need to check for both PUT and POST in my add/edit controller functions?

In case of add you should pass a new entity to Form::create() and controller method should only check for POST. For edit you would pass entity to edit to Form::create() and controller method should check for PUT.