For some reason my zend application is redirecting when it's not supposed to.
The index view just shows the form. The next view shows some information from a database based on the information supplied by the form. The user then clicks on a confirm button which sends them to anotherAction which constructs and sends an email. I've got a try/catch block where it tries to send the email. If successful, set one variable, otherwise set another.
Psudo-code:
public function indexAction()
{
$form = new Form();
if(!empty($_POST))
{
if($form->isValid($_POST))
{
$this->_helper->FlashMessenger($_POST); //store $_POST in temporary session
//show a different view
//do something else
}
}
$this->view->form = $form;
}
So I'm instantialising a form, if the user posts the form then validate it and store the session variables in a flash session and show a differnet view. In all cases show the form (if it has been sent then it will be auto-populated).
public function anotherAction()
{
$messages = $this->_helper->FlashMessenger->getMessages();
if (!empty($messages[0]))
{
$post = $messages[0];
$mail = new My_Mail();
//set up email
try
{
$mail->send();
$success = true;
}
catch (Zend_Exception $e)
{
$success=false;
//save $e to log
}
$this->view->success = $success;
}
else
{
//if not sent here by /page, then redirect to it.
$this->_helper->redirector->goToRouteAndExit(array(), 'page', true);
}
}
In this action, I'm checking for the session. If it's got the form data in it, then try to send an email and set variable; otherwise redirect back to the form. The view variable is used to show one message or the other (email sent / email failed to send).
Here's the problem: It redirects back to the form anyway. The form is submitted and confirmed, we go to the next page where it does something then it redirects back to the page with the form on it. Why is it doing this and how do I stop it?
[edit]
The plot thickens: If I open the confirm link in a new tab it will run and stop correctly. If I do it in the same tab/window it runs twice and redirects.
[another edit]
I have removed all the code in the second action.
The code is now:
public function anotherAction()
{
$messages = $this->_helper->FlashMessenger->getMessages();
if (!empty($messages[0]))
{
;
}
else
{
$this->_helper->redirector->goToRouteAndExit(array(), 'page', true);
}
}
and it is still redirecting.
For the confirm button I have
<button>Confirm</button>
Could the anchor and button both be calling the next-page?
[final edit]
Ok, this IS the problem. It looks like both the button and the anchor are calling the page! So the first time it runs it's ok then it runs again and redirects me :(
Well, there we go. Learn something new everyday.
Thanks for the help all.
I assume your form submits to /controller/another/ ...
What happens in the //do something block of code there in that action? Since we know that it's not really doing both the "if" and the "else" in the same pass ... it must be doing something in the "if" that you're not showing here that either triggers it to recall the function, _forward()'s, or somehow is getting to this point a 2nd time where it then evaluates the else part of your logic.
Can you post a more complete sample to review?
try replacing your redirect with a die() or $this->_forward( 'page' ) to see if any php warning messages are being hidden by the redirect.
Both the button and the anchor are calling the page! So the first time it runs it's ok then it runs again and redirects me.
Removed the button.
Try the following:
$this->redirect()->toRoute('routeName',array('controller'=>'controllerName','action'=>'actionName'));
$this->redirect()->toUrl('UrlLink')
Related
I'm probably going about this the complete wrong way, but here's where I am at.
I have a page called adminquery.php and on it is a form. When that form is submitted, it calls a file called adduser.php
This page attempts to add the user sent by POST to a database and sends back one of two messages (added or updated) which should display on the adminquery.php page.
if ($row[0] == 1)
{
//update
$_SESSION['errMsg'] = "user updated";
}
else
{
//add
$_SESSION['errMsg'] = "user added";
}
header("Location: adminquery.php");
die();
adminquery.php displays the message
if(isset($_SESSION['errMsg'])){
echo "<p>".$_SESSION['errMsg']."</p>";
}
So far, so good. However, when I reload adminquery.php or access it from another page, I want it to not display this _SESSION message which is no longer applicable.
So I thought I would check the originating page when loading adminquery.php and, if it's not been accessed from adduser.php I would empty the message
$referringSite = $_SERVER['HTTP_REFERER'];
if (strpos($referringSite, 'adduser') == false) {
//$_SESSION['errMsg'] = $referringSite;
$_SESSION['errMsg'] = "";
}
The commented line is used to check the referring page and it displays adminquery.php as the referring page rather than adduser.php (which has been called but not displayed). It seems like unless the page has been displayed or an element on it clicked to reopen adminquery.php that it's not recognised as the referring page.
Is there some simpler solution I'm not seeing?
Setting an empty string won't clear the session variable. You need to unset it like so:
unset($_SESSION['errMsg']);
Also, you don't need to check the referrer. Since the user script sets that variable, the admin query script can just check if it exists, and if so, remove it after displaying the appropriate message.
You must unset this session variable.
if(isset($_SESSION['errMsg'])){
echo "<p>".$_SESSION['errMsg']."</p>";
unset($_SESSION['errMsg']);
}
I'm pretty new to programming and gotta do a project for school. My task is to wrinte a ticketsystem with login etc. in PHP.
Since my groupmates aren't to helpful at all i decided to just code the loginsystem and create a .php which loads content dynamicly.
For normal links things went smooth so far but the loginsystem + the dynamic system gives me headache already.
Whenever i hit the login button (even when I don't enter any logindata at all) I endup in the frontpage(home.php) with the header tellin me that I'm on the "user.php".
I don't get any errors or anything, there seems to be just soem logical errors which i don't get :-(
can anybody help me with this?
http://pastebin.com/5XMSje07
Add exit() under all of your header() redirects
What's your directory structure looking like?
It seems like you don't have a check for empty fields when the post comes in. There should be something along the lines of the following in your login function when the post is read in:
if($_POST['Login'] == null || $_POST['Password'] == null)
{
return false;
}
else
{
//do the login check with the sql call to match username and pw
}
Redirects should be used more sparingly than you appear to have done
In your login script, you have:
if(!isset($usergroup))
{
login();
} else {
logout($usergroup);
}
This is all very well if you assigned $usergroup from a $SESSION value, which you haven't done. This page will therefore always show the login form.
$usergroup = $_SESSION['user'];
would be a start.
You also have multiple session_start calls, as it says in Highlander, "There can be only one".
Your code to detect whether someone has posted data to your script is inside the functions and probably should be inside the above test. Something like...
if (!isset($usergroup)) {
// have we recieved post data to login, if logged in set usergroup)
// if we have not logged in, show the login form
}
if (isset($usergroup) {
// show the logout form
}
i have a secure login form and at the moment, i have set it to just redirect to a home page link, but i want to add some validation so that IF a user comes from a perticular page then they should be redirected to that page after logging in, but not sure how to do it, my current way is not working, here is what i have tried so far:
print $_SERVER['HTTP_REFERER'];
$previousPage = $_SERVER['HTTP_REFERER'];
if ($errors == "") {
if (do_login($form_email_address,$form_password)) {
// success!
if ($previousPage == "http://hiddensite/path/video/"){
redirect($previousPage);
}else{
redirect("/index.php?page=home&loggedin=1");
}
} else {
$errors = "Could not login. Please check your e-mail address and/or password and try again.";
}
and if your wondering what redirect() is, its just my function:
function redirect($url) {
// this function redirects from one page to another
ob_clean();
header("Location: $url");
exit();
}
Do you want to know if a user comes from another page on your own site? If so, you could add a session var to that previous page and test it on your login page.
On your previous page:
session_start();
$_SESSION['foo'] = "bar";
And on your login page -
if(isset($_SESSION['foo'])) {...}
Not a great way to keep track of referrers, but if you only want to check one page as per your question, this should work.
We seem to be missing some information in answering your question. The code you have provided seems fine but in order for us to pinpoint the issue we would have to see the do_login function as you previously posted in the comments (which is now retracted). Since you are always redirected to the home page that would mean that the do_login function always returns false or anything else but true.
Before you retracted the comment I did noticed you also used the sqlslashes() function a few times. Is this a function that you have created? Be sure to include this in your question.
I'm having this strange problem with codeigniters flashdata in my login form. When I submit the form with an error in it (unrecognised email or bad email password combo) it takes two submits for the error message to display. Here's the relevant code:
//If an email address is matched
if($rowcount === 1) {
$row = $query->row();
if (hash('sha1', $row->salt . $_POST['password']) === $row->password) {
//there's a matching user...create a session here and redirect to homepage
} else {
$this->session->set_flashdata('credentials_error', '1');
// echo 'recognise email but not password';
}
} else {
//send message back to view here
$this->session->set_flashdata('email_error','1');
}
print_r($this->session);
$global_data['page_data'] = $this->load->view('login-template','',true);
$this->load->view('global', $global_data);
and the relevant bit from the view:
if($this->session->flashdata('email_error')) {
echo '<p class="error">We dont recognise this email address.</p>';
}
if($this->session->flashdata('credentials_error')) {
echo '<p class="error">We dont recognise these details. Please try again.</p>';
}
So if I submit the form with a bad email address that's unrecognised then I set the email_error flash data. The problem is that in the view I can see that the flashdata is set when I print out all the session data ([flash:new:emaili_error] => 1) but my error message does not show. However when I submit the form again (re-sending the same data) the error message shows.
Any ideas why this might be?
Yes; don't be fooled by the name they use, "sessions" in Codeigniter are cookies (they're not a fancy equivalent of the native php $_SESSION array, and they don't use it. Inf act, global arrays are usually destroyed in CI). As such, they're available only at the subsequent request; when you load the view the cookies has just been set: you need to make another request in order for the browser to catch it up and display it.
Usually flashdata are used, in fact, when you want to persist something between 2 http requests, not in the same request you set them and load a view.
It happens that you send a form, you make your checks, then you set the flashdata with the error and in the same process you load a view. The flashdata is "set" in codeigniter's class, only. When you re-submit the form, the cookie is now available, therefore you're shown the message. Hope it's clearer.
I always redirect instead of loading a view to get my flashdata working correctly. When you load a view, it's not submitting a new http request, but when you redirect, it is.
I'm a pretty new with the Code Igniter (as its my first framework I'm learning).
I got this in my controller:
if ($this->form_validation->run() === FALSE)
{
$this->load->view('account/register', $data);
}
else
{
$data['message'] = $this->lang->line('account_created');
$this->register->insert_account();
$this->load->view('account/register_success', $data);
}
If form is validated successfully , it does just change the view, but it is still possible to hit the refresh button, and re-send the form data - its not a big problem for me since I'm checking if fields are unique, but would be better for me to prevent from re-sending the form data.
Normally in clean PHP I would use header("Location: ..."); but I'm loading a view here, so it won't be possible to access it after redirection - isnt it?
Have you any suggestion for that?
You can redirect to the same page but also use codeigniters flashdata in the session library.
On a form submit set the flashdata with a success message.
Redirect to the same page with the form and display the flashdata success message.
By redirecting the page is reloaded and prevents a refresh.
controller
Do this on form success
$this->session->set_flashdata("success", $strMessage);
redirect("account/register");
view
This will show a success message on the form page
if($this->session->flashdata("success") !== FALSE)
{
echo "<div class=\"formSuccess\">" . $this->session->flashdata("success") . "</div>\n";
}
Ajax the view you need into a div. See what I mean? change the contents of the page but not the page itself.