Prevent form data re-send in Code Igniter - php

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.

Related

Preventing user access to submission page without having first completed the form

Say I have a form on example.com/contact that processes on example.com/submitted. In theory anyone can currently access example.com/submitted directly although this isn't ideal because of the message displayed. There's this question from 7 years ago but the answers in that don't work.
Theoretically the contents of the form page don't matter as long as it was posted. I don't want to have to echo out the contents of the submitted page as it is complete. I just need something simple like if the referrer wasn't example.com/form or POST method.
All I need is to only allow access to example.com/submitted if the user has actually submitted something. I've tried PHP and htaccess methods (PHP preferred) but nothing I've found has worked. Processing on the same page would remove this issue but the submitted page contains entirely different content.
Any advice would be appreciated as I can't find anywhere with a working answer.
Have the action of your form on example.com/contact point to example.org/submitted so that the form contents get posted to your submitted page.
Then, on your submitted page, check the method, and redirect to to contact on GET (or better, everything that isn't POST):
if ($_SERVER['REQUEST_METHOD'] !== 'POST')
header("Location: http://example.com/contact");
else if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST)) {
// validate input
// save to your CSV
// display `submitted` page
}
You can accomplish a check on both the refferer and the request method by doing so:
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_SERVER['HTTP_REFERER'] == "http://example.com/form") {
// Your code
}
Try this:
contact.php
session_start();
...
$_SESSION['form-submitted'] = 0;
if(isset($_POST['submit'])){//use your button value
//do your stuff
$_SESSION['form-submitted'] = 1;
//redirect to submitted file
}
submitted.php
if(isset($_SESSION['form-submitted']) && $_SESSION['form-submitted'] == 1){
//show content
} else {
//redirect to contact page
}
This will allow you to catch the get requests and check if the form was not submitted.
Have you tried this one yet ?
if (!isset($_POST)) {
header("Location: http://example.com/contact");
}

How to overpass "Confirm Form Resubmission" in PHP

I have 3 pages.
-page1.php sends data through a form with post action
-page2.php recieves data from page1.php. In page2.php there is a link to page3.php
-page3.php does some staff.
When i click to go back from page3 to page2 occures
Confirm Form Resubmission
ERR_CACHE_MISS
I understand the reason of this behaviour. When I take data from page1 to page2 I store some of them in session so i don't need always to use submit. How can i check if submit was done in order to continue normally if no submit was used?
Here is some code of page2:
<?php
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
global $dbcnx;
if (isset($_POST['submit']))//if i submit i store in session
{
$_SESSION['team_name'] = $_POST['teams'];
echo $_SESSION['team_name'];
}
else //do nothing
{}
//conitnue code normally
.
.
.
That was my last try. Any response will be helpfull. Thanks in advance!
The usual way to prevent that is to redirect to a page with no post data, click the link to see more info on How to make a redirect in PHP?
The answer is that you should redirect to a specific page using php.that is done with header().
this should be a help:
header("Location: http://www.something.com/any/thing.php") //the page can be anything
Of course, if you're using xampp or wamp or whatever server, use it this way:
header("Location: http://localhost/any/thing.php") //the page can be anything

form validation not working Codeigniter

I think I am doing everything all right, but why isnt my validation working. Every time the else statement gets executed, even if I enter the valid data.
public function login ()
{
// Redirect a user if he's already logged in
$dashboard = base_url().'dashboard';
$this->user_model->loggedin() == FALSE || redirect($dashboard);
// Set form
$this->form_validation->set_rules('email','Email','required');
$this->form_validation->set_rules('password','Password','required');
// Process form
if ($this->form_validation->run() == TRUE) {
echo "Validation Success";
}else{
$this->session->set_flashdata('validation_errors', validation_errors().'<p>Please enter valid email and password</p>' );
redirect(base_url().'login', 'refresh');
}
EDIT
I am using dreamhost VPS .
unless you are on another codeigniter project on another server, just use
redirect('name_of_controller/name_of_method') there is no need to put the base_url() because it already uses the base url as its condition.
and on your validation message set a message like $this->form_validation->set_message('rule','message')
read more at http://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#settingerrors
And you have not showed us the view, show us how you post the error message on your view.
1.) have a var_dump() of your session if the validation errors are really set
2.) have you loaded the session library?
3.) Are you sure you are accessing the proper session variables on the view?

flashdata error not displaying

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.

Zend Redirecting

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')

Categories