Why CakePHP arrows _method equal to PUT instead of POST?

5

I recently updated my CakePHP project to version 2.4.5.

Since then, some of my forms have input hidden _method set to PUT automatically. The only way around this is to set 'type' => 'POST' .

But that was not necessary in the old days. I do not know if I'm doing something wrong, or if it's a BUG.

This is the form

  <?php echo $this->Form->create('User', array('url' => array('action' => 'new_password', $this->request->data['User']['forget_password'], 'admin' => false), 'autocomplete' => 'off')) ?>

    <?php echo $this->Form->hidden('User.id') ?>

    <fieldset>
      <label class="block clearfix">
        <span class="block input-icon input-icon-right">
          <?php echo $this->Form->password('User.password', array('label' => false, 'div' => false, 'class' => 'form-control', 'placeholder' => 'Digite a nova senha')) ?>
          <i class="icon-user"></i>
        </span>
      </label>

      <label class="block clearfix">
        <span class="block input-icon input-icon-right">
          <?php echo $this->Form->password('User.password_confirmation', array('label' => false, 'div' => false, 'class' => 'form-control', 'placeholder' => 'Digite novamente a nova senha')) ?>
          <i class="icon-user"></i>
        </span>
      </label>

      <div class="space"></div>

      <div class="clearfix">
        <?php echo $this->Form->button('<i class="icon-key"></i> '. __('Enviar'), array('class' => 'width-35 pull-right btn btn-sm btn-success', 'escape' => false)) ?>
      </div>

      <div class="space-4"></div>
    </fieldset>
  <?php echo $this->Form->end() ?>

And that's the action:

/**
 * new_password method
 *
 * @access public
 * @param String $forget_password
 * @return void
 * @since 1.0 
 * @version 1.0 
 * @author Patrick Maciel
 */
public function new_password($forget_password)
{

  $user = $this->User->findByForgetPassword($forget_password);

  if ($user == false) {
    $this->Session->setFlash(__('Link inválido'), 'flash/frontend/error');
    $this->redirect('/');
  }

  $this->layout = 'login';

  if ($this->request->is('post')) {
    $this->User->set = $this->request->data;
    if ($this->User->validates(array('fieldList' => array('id', 'forget_password', 'password', 'password_confirmation')))) {

     // ...

    } else {

     // ...

    }
  }

  $user['User']['password'] = null;
  $this->request->data = $user;

}

Note: I did not set the type type of the form above, just to test if it would occur, and it occurred.     

asked by anonymous 20.01.2014 / 17:08

4 answers

5

What I have seen is that if you have a selected record it considers the PUT method as default, if you do not have an active record it poses as POST.

We can see this here:

if ($model !== false && $key) {
      $recordExists = (
          isset($this->request->data[$model]) &&
          !empty($this->request->data[$model][$key]) &&
          !is_array($this->request->data[$model][$key])
       );

      if ($recordExists) {
          $created = true;
          $id = $this->request->data[$model][$key];
      }
}

Then we see this:

'type' => ($created && empty($options['action'])) ? 'put' : 'post',

So from what I understand if you use a form that is created and that you are not retrieving data from the model it will do a POST.

Source: link

    
20.01.2014 / 18:25
1

I still do not know what logic behind CakePHP to do this but it is this:

If the action is not add() , it considers PUT , unless the action is delete .

So, if it is a custom route, avoiding the REST pattern, you must manually set it:

'type' => 'POST'

And that's it.

Note: I tested both remove User.id , and remove parameters from url of Form, but nonetheless it kept as PUT

Reference: link

    
20.01.2014 / 18:17
0

CakePHP uses POST in the form and sets the _method attribute to PUT because the PUT method is not natively supported by browsers.

The Symfony2 framework does the same, and look at what they say in the documentation:

  

Unfortunately, life is not easy, since most browsers do not support sending PUT and DELETE requests. Fortunately Symfony2 provides you with a simple way of working around this limitation. By including a _method parameter in the query string or parameters of an HTTP request, Symfony2 will use this as the method when matching routes. Forms automatically include a hidden field for this parameter if their submission method is not GET or POST.

Source: link

    
26.02.2014 / 17:09
0

When using put or delete , the form will be post , but when submitted, the HTTP request method will be replaced with PUT or DELETE , respectively. This allows CakePHP to emulate REST support in web browsers.

link

    
26.02.2014 / 17:04