Reputation: 5395
We have a CakePHP 3.x app which we've updated to the latest CakePHP 4.x. As part of this work we've also changed from PHP 7 to PHP 8.
Whilst testing the app we noticed a feature that had stopped working.
The app is a searchable database and is integrated with Redis for caching. One of the features means that the users search is retained between page reloads. This works by writing serialized form data to Redis, and then re-populating that back into the input
fields in the template. This means the user sees the search criteria they entered; they do not need to re-enter their search criteria when the page is refreshed.
The code in the CakePHP 3.x app which re-populated the input
form fields looked like this:
$form_fields = ['f1', 'f2', 'f3'];
The $form_fields
array contains the names of the form input
's in the template. As an example:
<input type="text" name="f1">
The next part of the code re-populates the form. In this case $user_search
is an array of data that has been obtained and unserialized from Redis. As an example we might have $user_search['f1']
and $user_search['f3']
containing Redis data; f2
is unpopulated because the user didn't search using that field.
foreach ($form_fields as $form_field) {
$this->request->getData()[$form_field] = (isset($user_search[$form_field])) ? $user_search[$form_field] : '';
}
In the Cake 3.x app the above works fine. When the page is reloaded the form fields are set due to setting the request data, e.g. in the loop above, it evalulates to:
$this->request->getData()['f1'] = 'foo';
$this->request->getData()['f3'] = 'bar';
This means the request data has "foo" as f1
and "bar" as f3
. There is nothing in f2
so it gets set to an empty string as per the : '';
condition.
In the CakePHP 4.x app this does not work; all form fields are unpopulated on page reload. I've confirmed that they are not being set to empty strings by modifying the : '';
condition mentioned above to : 'test';
and ensured the string "test" is not being shown in the fields.
The data exists in Redis and I've confirmed that $user_search
contains what's shown above - in other words the data is not missing so we've ruled that out.
When I read over https://book.cakephp.org/4/en/controllers/request-response.html I can't see an example of setting request data. There is a method getData()
which does what you'd expect - it reads the request data.
Is there a way to set the request data in Cake 4.x such that the above code would work?
In vanilla PHP what we're doing is equivalent to
$_POST['f1'] = 'foo';
$_POST['f2'] = ''; // empty string as no value set by user
$_POST['f3'] = 'bar';
AFAIK this was - and still is - valid in PHP; you can set/overwrite request data with anything in your code. If this is wrong please advise what I should be doing instead.
For clarity the reason we are setting request data in this manner is because the search for works via an ajax call. When the user enters their search criteria initially, the page has not been reloaded so the form fields appear to be populated correctly. This issue occurs on page reload. In that instance we want to repopulate the form with the values they entered prior to the page being reloaded.
Upvotes: 1
Views: 1494
Reputation: 5099
The function you're looking for is withData
. Remember that the request object is immutable, so you need to assign the result of that function call back into the request object, e.g. with $this->setRequest($this->getRequest()->withData('f1', 'foo')->withData('f3', 'bar'))
.
Upvotes: 4