I have a page with several sections with forms that are submitted from the same page. The forms collapse to save space, but I want to conditionally keep them open if there is an error on submission.
In my controller, I set a specific "key" (see location_key below) for each form, which allows me to echo them in their respective locations:
In controller:
$this->Session->setFlash('You missed something...', 'element_name', array('class'=>'error'), 'location_key');
In view:
$this->Session->flash('location_key')
I'm trying to figure out how to check if $this->Session->flash('location_key') exists. If I do this it works but unsets the flash message:
if ( $this->Session->flash('location_key') ) // = TRUE
//Do something
$this->Session->flash('location_key') // = FALSE (because it just got called)
How can I test for the presence of this flash message without causing it to go away?
Figured it out! This works:
$this->Session->check('Message.location_key')
It returns true/false depending on whether there are any such flash messages set. ->read() does the same thing, but returns the flash data if there is (any and crucially, it leaves the session var so it can still be echoed later).
Flash messages are (surprise) stored in the session:
public function setFlash($message, $element = 'default', $params = array(), $key = 'flash') {
CakeSession::write('Message.' . $key, compact('message', 'element', 'params'));
}
To test for the presence of a flash message, test for the equivalent key in the session, e.g.:
if (CakeSession::check('Message.location_key')) {
...
}
Well, according to the api, the SessionHelper returns a string (with the flash message and element) when you do $this->Session->flash('location_key'), so why not store that string into a variable?
$myFlash = $this->Session->flash('location_key');
if ($myFlash)
/*etc*/
echo $myFlash;
Related
I have this line of code in my login method
Session::put('msg','Welcome user');
And with a simple route a get through AJAX the value of that message and then delete it ( in theory ) (It's like a flash message):
public function getMessage( ){
$msg = Session::pull('msg','');// tried this
Session::flush();// and/or this
return $msg;
}
Still the message from session is not removed. I want it behave like a flash message . Why the value still persists if I used Session::pull() and\or Session::flush()?
laravel have already a system of session flash,to set data in session flash
Session::flash('msg', 'Event Created');
and then when you show this session a single time,it will automatically remove,you don't need to think about it
Session::get('msg')
I'm attempting to validate a users login attempt and inform them that
Their username is wrong or
their password is wrong (because I personally hate with a blind fury when a website doesn't inform me WHICH it is but that's beside the point).
I've read a lot of SO posts on this issue but the ones I've found are years old and I'm dealing with CodeIgniter 3.0.1.
This is the code that I have in place. I'm using Eclipse PDT to as my IDE and I like it quite a bit (but that's getting off track) so I've been able to step through the execution and watch as it just fails completely.
IF (!$this->User->login( //Testing shows this works fine - the SWITCH statement gets executed as it should and the BADUSERNAME case is followed through.
addslashes(strtolower($this->input->post('username', TRUE))),
addslashes($this->input->post('password', TRUE)),
$this->getIP())){
SWITCH($this->User->ID){
CASE 'BADUSERNAME':
$this->session->set_flashdata('user_msg', 'Invalid Username');
BREAK;
CASE 'BADPASSWORD':
$this->session->set_flashdata('user_msg', 'Invalid Password');
BREAK;
CASE 'ALREADYLOGGEDIN':
$this->session->set_flashdata('user_msg', 'You are logged in elsewhere.');
BREAK;
DEFAULT:
$this->session->set_flashdata('user_msg', 'Something has gone terribly wrong. Please try logging in again.');
BREAK;
}
redirect(base_url());
}
Then a bit further down I load the header, body, and footer views - The body is where the error message should be displayed but it's not..
<div id="contentarea">
<div class="container">
<?PHP
ECHO $this->session->flashdata('show_validation') ? validation_errors() : '';
$error = $this->session->flashdata('user_msg'); //This is where it's supposed to get it...
IF ($error) //And this is where it's supposed to show it...
ECHO "<div class='error'>$error</div>";
?> //But the value is wiped so it only ever grabs NULL.
I've followed the path of execution after calling the redirect after setting the flash data and I've noticed that after the redirect finishes it's chain of execution, it calls exit;.
Then everything loads again from the index.php file, and when Session finally pops up... the value 'user_msg' is nowhere to be found.
So clearly I'm doing something wrong here - what am I doing wrong here? Will the flash_data only persist until that redirect is called? Even the session_data values (calling $this->session->value = 'some arbitrary user message' fails to persist).
How can I persist the message for the next time the body element is loaded so that it can tell the user "Hey, didn't find you" or "Hey, your password wasn't right"?
EDIT 1
So it turns out I do not need to redirect for what I am doing as POSTing (submitting the user name and password) handles that for me.
I'm going to leave the question here for anyone else who may need it answered though - perhaps the answer is simply that Flash data just doesn't survive a redirect?
Flashed data is only available for the next http request, if you reload the page a second time, data is gone.
To persist data in the session, you want to set the variable in the session.
Codeigniter
Adding Session Data
Let’s say a particular user logs into your site. Once authenticated, you could add their username and e-mail address to the session, making that data globally available to you without having to run a database query when you need it.
You can simply assign data to the $_SESSION array, as with any other variable. Or as a property of $this->session.
Alternatively, the old method of assigning it as “userdata” is also available. That however passing an array containing your new data to the set_userdata() method:
$this->session->set_userdata($array);
$this->session->set_userdata('username', 'username is wrong');
in the view
$this -> session ->userdata('username');
or
$this ->session -> username;
Reference Session Library Codeigniter.
hope this help.
All you have to do is use $this->session->keep_flashdata('user_msg') with $this->session->unset_userdata('user_msg')
here is the solution (view file)
<?php
$error = $this->session->flashdata('user_msg');
if (isset($error)) {
echo '<div class="error">' . $error . '</div>';
$this->session->unset_userdata('user_msg');
}
?>
After that in your controller construct function (In that controller where you redirecting)
public function __construct() {
parent::__construct();
//.....
$this->session->keep_flashdata('user_msg');
}
I had same problem and this works. do not forget to clear cache when try or try in different browser
You can use codeigniter's flashdata to display errors separately.
This is what I usually use.
Controller:
$errors = array();
foreach ($this->input->post() as $key => $value){
$errors[$key] = form_error($key);
};
$response['errors'] = array_filter($errors);
$this->session->set_flashdata($response['errors']);
redirect('your-page', 'refresh');
And the to display the errors use
<?php echo $this->session->flashdata('field_name'); ?>
Hello CodeIgniter users.
I have a problem with flash data and I would like some help. My CI version is 2.1.4.
I am using CI flash data to store data temporarily for a form that consists of multiple pages. Data entered on each page is stored so it can be accessed on the next pages and finally all data is entered int the database.
Now to keep data stored through multiple pages, instead of only one, I extended the Session class with the following function:
function keep_all_flashdata($prefix = '')
{
$userdata = $this->all_userdata();
foreach ($userdata as $key => $value)
{
if (strpos($key, ':old:' . $prefix))
{
$new_flashdata_key = str_replace(':old:', ':new:', $key);
$this->set_userdata($new_flashdata_key, $value);
}
}
}
This function preserves all flash data (or optionally only flash data that starts with a certain string) for another redirect. It is similar to the keep_flashdata function except for the fact that it works for multiple items without requiring their exact name.
After calling this function, both :old: and :new: keys are stored in the session data. Then after a redirect, old keys are removed and new keys are set to old. Then, if there's another page, I call keep_all_flashdata() again and so on until the last page.
This works fine when I'm working on my local WAMP server, but on my actual server, all flashdata just gets removed after a redirect, even if it has :new: in the key. I confirmed my keep_all_flashdata() function works by checking the contents of session->all_userdata() and everything looks as expected.
I am using some AJAX calls, but they should not erase flash data (a known issue) as I've prevented this with $this->CI->input->is_ajax_request() before flashdata is cleared (in the sess_update() and _flashdata_sweep() functions).
Is this a bug in CodeIgniter or am I doing something wrong? Any help is appreciated.
I think your if statement is causing the problem. I'm assuming that ":old:" or ":new:" is used as prefix for every key you store in a session?
strpos() returns the position of where the needle exists so that would be 0 when checking a key with the prefix ':old:'. That's intended as old flashdata needs to be removed. I tested the following piece of code:
$flashDataKey = ':new:myKey';
die(var_dump(strpos($flashDataKey, ':old:')));
Which returns false as expected since the needle was not found. Resulting in not storing the flashdata as ':old:' and keeping it for the next request.
I'm not sure why this is working on your localhost. You should change your if statement to:
if( strstr($key, ':new:') !== false)
Now only keys containing the string ':new:' will pass and everything else will return false. Hope this helped!
I have a website where the front page contains a search form with several fields.
When the user performs a search, I make an ajax call to a function in a controller.
Basically, when the user clicks on the submit button, I send an ajax call via post to:
Route::post('/search', 'SearchController#general');
Then, in the SearchController class, in the function general, I store the values received in a session variable which is an object:
Session::get("search")->language = Input::get("language");
Session::get("search")->category = Input::get("category");
//I'm using examples, not the real variables names
After updating the session variable, in fact, right after the code snippet shown above, I create (or override) a cookie storing the session values:
Cookie::queue("mysite_search", json_encode(Session::get("search")));
And after that operation, I perform the search query and send the results, etc.
All that work fine, but I'm not getting back the values in the cookie. Let me explain myself.
As soon as the front page of my website is opened, I perform an action like this:
if (!Session::has("search")) {
//check for a cookie
$search = Cookie::get('mysite_search');
if($search) Session::put("search", json_decode($search));
else {
$search = new stdClass();
$search->language = "any";
$search->category = "any";
Session::put("search", $search);
}
}
That seems to be always failing if($search) is always returning false, and as a result, my session variable search has always its properties language and category populated with the value any. (Again: I'm using examples, not the real variables names).
So, I would like to know what is happening here and how I could achieve what I'm intending to do.
I tried to put Session::put("search", json_decode($search)); right after $search = Cookie::get('mysite_search'); removing all the if else block, and that throws an error (the ajax call returns an error) so the whole thing is failling at some point, when storing the object in the cookie or when retieving it.
Or could also be something else. I don't know. That's why I'm here. Thanks for reading such a long question.
Ok. This is what was going on.
The problem was this:
Cookie::queue("mysite_search", json_encode(Session::get("search")));
Before having it that way I had this:
Cookie::forever("mysite_search", json_encode(Session::get("search")));
But for some reason, that approach with forever wasn't creating any cookie, so I swichted to queue (this is Laravel 4.2). But queue needs a third parameter with the expiration time. So, what was really going on is that the cookie was being deleted after closing the browser (I also have the session.php in app/config folder set to 'lifetime' => 0 and 'expire_on_close' => true which is exactly what I want).
In simple words, I set the expiration time to forever (5 years) this way:
Cookie::queue("mysite_search", json_encode(Session::get("search")), 2592000);
And now it seems to be working fine after testing it.
On my webpage, I have 2 options, to create a new list or to edit an existing list.
If the user wishes to create a new list, a new page with a textarea comes up.
If the user wishes to edit an existing list, the lists are displayed and the user can select a list. Upon selection of the list, the user is redirected to the new list page with the text area contents already filled in.
I have this if statement in the new list page to accept input from the edit-list page:
$items = $_GET['items'];
if ($items){
//get the stuff from the db and populate the text area
}
else {
//a new empty text area
}
The issue is that when I try reaching this page directly from the 'create new list' option, I get an error stating that items is an undefined variable.
This makes sense as the original page is not sending any data so there is nothing to get.
How can I work around this?
I can set the original page up to send a null value for items but I want to refrain from changing the original page.
Is there an option to check from where the request is coming from, or an option to activate a variable only if it can be received (usable by the GET feature)?
Use isset():
isset — Determine if a variable is set and is not NULL
if (isset($_GET['items'])){
//get the stuff from the db and populate the text area
$items = $_GET['items'];
}
#Eugen suggestion(check before assigning the variable:
$items = isset($_GET['items']) ? $_GET['items'] : null;
if($items) { // bla bla }
Firstly you must write/check
print_r($_GET)
if you want only check it you can use
if(isset($_GET["items"]){
//it have a value
}
Plus:If a variable has been unset with unset(), it will no longer be set. isset() will return FALSE if testing a variable that has been set to NULL. Also note that a NULL byte ("\0") is not equivalent to the PHP NULL constant.
You want this. You need to check if $_GET['items'] is set, and then you can set $items to the result.
if (isset($_GET['items']) && $items = $_GET['items']){
//get the stuff from the db and populate the text area
}
else {
//a new empty text area
}