Andy
Andy

Reputation: 5395

CakePHP 3 correct way to modify request data in a controller

There are numerous posts about this on SO but all seem out-of-date.

Using CakePHP 3.7 in 2019 and following a tutorial on implementing a "password reset" email: http://web.archive.org/web/20171001155555/http://www.naidim.org/cakephp-3-tutorial-9-reset-password

The application has a users table which has 2 fields called passkey and timeout. In the sample code linked above they have used the following to "unset" these 2 fields when the user is resetting their password:

$this->request->data['passkey'] = null;
$this->request->data['timeout'] = null;

It seems that this is deprecated and you cannot set request data in a controller like this anymore.

My plan was to attempt to use array_merge() to merge the request data and anything we want to modify like this:

$save_data = array_merge($this->request->getData(), ['passkey' => null, 'timeout' => null]);

// Note $user is the result of a find query done earlier.
$this->Users->patchEntity($user, $save_data);

Doing this seems to have no effect on the data saved in the DB - it will update the password field (which comes from a form on the linked post). But it will not modify either the passkey or timeout fields in the DB.

If I debug($save_data) is it indeed giving me an array of:

[
    'password' => 'foo',
    'confirm_password' => 'foo',
    'passkey' => null,
    'timeout' = null
];

Is this the wrong way to do it? I believe the reason this has been changed is to do with request objects being immutable, although it was easier programatically to be able to set data through $this->request as previously.

Upvotes: 0

Views: 2076

Answers (1)

Zenzs
Zenzs

Reputation: 138

I'm not 100% sure I've understood your needs but ensuring the passkey and timeout are reset in the reset function could be done by refactoring the linked code to the below. This may be one way...

// AS IS

// Clear passkey and timeout
$this->request->data['passkey'] = null;
$this->request->data['timeout'] = null;
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
…

// TO THIS

$user = $this->Users->patchEntity($user, $this->request->getData());

// Clear passkey and timeout
$user->passkey = null;
$user->timeout = null;

if ($this->Users->save($user)) {
…

Upvotes: 2

Related Questions