Is there any way that I can reset some value from the Input on the server side. Let's say, I am getting the value in foo i.e. Input::get('foo') on the server side, but I don't want that in Input. How may I reset that?
Now all I can think of is getting $formData = Input::except('foo') to get all the input values except foo and the processing this $formData instead. But I don't want to change my whole implementation for that, so is there any otherway provided by Laravel?
Was as simple, as the following:
Input::merge(array('foo' => null));
Related
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.
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')).
I have cookie date stored in a serialized array which I would like to access via the Blade template.
If a cookie value is set matching the current field name, then I want to show it. I am currently using the following code, but I'm not sure how to access the array value.
{{{ Cookie::has('myBookingDetails') ? Cookie::get('myBookingDetails') : old('name') }}}
The value of the myBookingDetails cookie looks like this:
a:4:{s:4:"name";s:13:"Joe Bloggs";s:5:"email";s:29:"joe#domain.co.uk";s:5:"phone";s:11:"0777777777";s:3:"reg";s:6:"123456";}
How can I access the "name" value via Blade?
The data is serialized. You need to use unserialize() function to get the data.
$data = unserialize(Cookie::get('myBookingDetails'));
$name = $data['name']
Check for existence before use.
Don't know if previous answer solved your enigma, but I could give some help.
I fought with a similar case. Seems that in template - in laravel 5.1 - I couldn't access directly to cookies:
Cookie::get('cookiename') simply returns null
cookie('cookiename') returns a Symfony\Component\HttpFoundation\Cookie, but $cookie->getValue() returns (again) null.
The good old $_COOKIE['cookiename'] returns the right cookie, so you could simply go with unserialize( $_COOKIE['myBookingDetails'] )['name']; !
PS: It should be better to handle with cookies in controller and pass a normal variable to the view!
On my web page I have Zend_Form with CSRF hash. It submits to the same page and it is used to update user's data (name, surname, birthdate and so on...). I would like to reinitialize CSRF hash after every valid post submission. How I could do it?
Now when I first time submit 'user data' form I get proper behavior (user data gets updated). But if I submit again (right after first, proper submit) to change another form field I get error saying:
The two given tokens do not match
Is there anyway to reinitialize hash properly?
Your problem comes from this function in Zend_Form_Element_Hash the $session->setExpirationHops is set to 1 hop, so if you try to resubmit the same form it will always fail. This is by design and is the root of the security you're seeking.
However you can change this behavior, simply extend Zend_Form_Element_Hash and override this method to set the expirationHops to a value you prefer (you can also set the session options manually at any time if you prefer).
public function initCsrfToken()
{
$session = $this->getSession();
$session->setExpirationHops(1, null, true);
$session->setExpirationSeconds($this->getTimeout());
$session->hash = $this->getHash();
}
It goes without saying that it would be in the interest of security to perform a full refresh and repopulate the form to perform any edits. This should reset the hash.
My problem came from tampering with Zend_Form_Element_Hash init methods, I had this:
$_csrf = new Zend_Form_Element_Hash($this->_csrfName);
$_csrf->setSalt(md5($name));
$_csrf->setAttrib('id', '');
$_csrf->initCsrfToken();
The last line should never be there. When I removed it, everything started to act correctly.
#RockyFord: The initCsrfToken() function was place I was looking at the beginning, but
for me (I mean my intuition) it just couldn't be that. So I just debugged, debugged, debugged,
and at last commenting out 4th line was proper solution. Sorry for holding off reply, I totally forgot.
I would like to do something roughly analogous (but not exactly identical) to the following: I want to create a Person content type, which has an SSN field. I would like to store the SSN field as an integer, but allow the user to input the number as 123-45-6789. This means that before validation triggers, stating that "123-45-6789" is invalid input, I would like to remove the dashes and treat this as an integer.
I've tried to use both a #value_callback function, as well as a non-default validation function. The problem then is that although I can force the value to be validated, the unchanged value is what is passed to the db for insertion, which fails. In example, this means that although I can force "123-45-6789" to be recognized by Drupal as "123456789", the database is still being passed "123-45-6789", which of course fails.
The one obvious solution would be altering this via client side javascript, before the value is even submitted to the webserver. I would strongly prefer to avoid this route.
Apologies if I've misunderstood but you should just be able to do something like this:
function my_validation_handler(&$form, &$form_state) {
if (passes_ssn_validation($form_state['values']['SSN'])) {
// Changing the value in $form_state here will carry on over to the submission function
$form_state['values']['SSN'] = convert_to_db_format($form_state['values']['SSN']);
}
else {
form_set_error('SSN', 'The SSN was invalid');
}
}
Then you'd attach that validation function using $form['#validate'][] = 'my_validation_handler' in either your form build or form_alter function.
Hope that helps
you should use hook_node_presave(). It allows you to change the values of different fields before they are inserted to the database. Here's the official documentation:
http://api.drupal.org/api/drupal/modules--node--node.api.php/function/hook_node_presave/7
Hope this can help :)
I have a page "bottom1.php" it has 16 select menus, labled rating1-rating16.
When the user submits this form, the next page has a script that looks like this:
//pulling data from post into array.
import_request_variables("p", "form_");
$scores= array($form_rating1,$form_rating2,$form_rating3,$form_rating4,$form_rating5,$form_rating6,$form_rating7,$form_rating8,$form_rating9,$form_rating10,$form_rating11,$form_rating12,$form_rating13,$form_rating14,$form_rating15,$form_rating16);
//putting array into session
$_SESSION['scores']=$scores;
the user is then directed to another page where an additional 16 selections are made, then the same script is ran, only this time the array is stored into the session as "scores2".
The user is shown the output from each array, and then when the user confirms that the values are correct, each member of the scores, and scores2 array is parsed out, put into another variable, and then inserted into a database.
I know this is a primitive way of accomplishing this, but its the only way I know how.
This method worked with php configuration of 5.2.13, but I switched to a server with a configuration of 5.1.6 and now this script wont work. This script is critical to my site. Thanks for your help!
The parsing script looks like this:
$fpage=$_SESSION['scores'];
$spage=$_SESSION['scores2'];
$score1 = $fpage['0'];
$score2 = $fpage['1'];
$score3 = $fpage['2'];
$score4 = $fpage['3'];
$score5 = $fpage['4'];
...
$score31 =$spage['13'];
$score32 =$spage['14'];
$score33 =$spage['15'];
And then I insert $score1 - $score33 into my db..
The way you are doing it isn't exactly safe, for the same reason register_globals() is/was a bad idea. If you happen to prefix one of your internal variables with 'form_', the user could overwrite that value and potentially inject harmful code (depending on how that variable is used).
A better way to do this would be to filter the array directly into a new array using array_filter() or preg_grep().
Oliver A.'s solution only works in the scenario that all of the array keys will be in the form of 'form_rating', but your original script assumed a prefix of 'form_'.
preg_grep could be used as follows:
$keys = preg_grep('/^form_/', array_keys($_POST));
$scores = array();
foreach ($keys as $key) {
$scores[$key] = $_POST[$key];
}
I do not have a php enviroment to test this right now but this should work:
$scores = array();
for($i=1;array_key_exists("form_rating{$i}",$_POST);$i++){
$scores[] = $_POST["form_rating{$i}"];
}
EDIT: I tested and working
If the script does not work when PHP changes version then:
Check the logs to see the errors
Check the PHP Changelog for any function or control structure change that my halt your script.
Just an issue that it happen to me a lot when switching between 5.1 and 5.2 is the Elvis operator ?: which is not recognized in php 5.1.
This is why is important to develop on the same kind of configuration that the server has, or to implement unit-testing and automatic deployments which can detect this problems before reaching production.