I am using codeigniter and the tutorial from here. I have made a basic blog tool which works fine. However as it stands to add a new post you have to go to a separate page 'create.php' to get to the form. I would like to try and put the form on the same page as the page that will be updated i.e. 'index.php'. If I try to do this at the moment the form simply refreshes and does submit the data.
model
function insert_post($data){
$this->db->insert('posts', $data);
return;
}
Current View (admin/create.php)
<?php echo validation_errors(); ?>
<h4>Create A New Post Below</h4>
<form action="" method="post" >
<p>Title:</p>
<input type="text" name="title" size="50"/><br/>
<p>Summary:</p>
<textarea name="summary" rows="2" cols="50"></textarea><br/>
<p>Post Content:</p>
<textarea name="content" rows="6" cols="50"></textarea><br/>
<input type="submit" value="Save" />
<?php echo anchor('admin','Cancel'); ?>
</form>
View I would like the form to be on (index.php)
<?php
echo '<p>Welcome '.$username.'! All posts available for edit or deletion is listed below.</p><br/>';
echo anchor('admin/create','Create New Post');
$count = count($post['id']);
for ($i=0;$i<$count;$i++)
{
echo '<div class="postDiv">';
echo '<h4>'.$post['title'][$i];
echo '<p>'.$post['summary'][$i].'</p>';
echo '<p>'.$post['content'][$i].'</p>';
//echo anchor('blog/view/'.$post['id'][$i],' [view]');
echo anchor('admin/edit/'.$post['id'][$i],' [edit]');
echo anchor('admin/delete/'.$post['id'][$i],' [delete]</h4>');
echo '</div>';
}
?>
Controller
function create(){
$data['userId'] = $this->tank_auth->get_user_id();
$data['username'] = $this->tank_auth->get_username();
$this->form_validation->set_rules('title','title','required');
$this->form_validation->set_rules('summary','summary','required');
$this->form_validation->set_rules('content','content','required');
if($this->form_validation->run()==FALSE)
{
$this->load->view('template/admin_html_head',$data);
$this->load->view('admin/create',$data);
$this->load->view('template/html_tail',$data);
} else {
$data = $_POST;
$this->posts->insert_post($data);
redirect('admin');
}
}
This was straight forward when I used normal php but with codeigniter I am getting lost with the MVC stuff. I know this is probably a fairly basic question so please either explain your answer or give me a link to something which will explain what I need to do as I want to learn from this. I have read the codeigniter docs on validation but I dont think thats my problem?
What you are trying to do is called embedding a view. I will try to explain how but you should also check some links which might prove to be more in depth:
http://net.tutsplus.com/tutorials/php/an-introduction-to-views-templating-in-codeigniter/
Codeigniter: Best way to structure partial views
The crux of what you need to do is change the link on index.php from:
echo anchor('admin/create','Create New Post');
to
$this->load->view('admin/create');
Now this should work, but to help you on the MVC front, it helps to explain why doing it this way is wrong. The idea of MVC is to seperate the functions in your application into their distinct roles. Most people will frown at putting business logic into views unless it is very minimal. The way that we could improve upon your code is to load the view in the controller, and set it to variable.
At the bottom of the codeigniter docs for views it shows how to load into a variable:
http://ellislab.com/codeigniter/user-guide/general/views.html
if the third parameter of load->view is set to true then the function will return your view as a string instead of outputting it to the browser
$data['input_form'] = $this->load->view('admin/create', $data, true);
then in the view that you want to load that form all you need to do is echo input_form
<?php echo $input_form;?>
So that should solve your problem but there are also a few more things you can do in your view file that will improve the readability of your code.
Instead of using a count() and for loop you can use foreach which makes everything much easier
<?php foreach ($post as $post_item):?>
<div>
<h4><?php echo $post_item['title'];?></h4>
</div>
<?php endforeach;?>
It also helps to break your view files up and have more tags. It might seems like it is extra bloat, but when you have larger view files it will be very cumbersome to continue using as many echo's as you have
just add one method uri_string() in your form action, uri_string will take same url of page put in action you can submit form to same page
<?php echo validation_errors(); ?>
<h4>Create A New Post Below</h4>
<form action="<?=uri_string()?>" method="post" >
<p>Title:</p>
<input type="text" name="title" size="50"/><br/>
<p>Summary:</p>
<textarea name="summary" rows="2" cols="50"></textarea><br/>
<p>Post Content:</p>
<textarea name="content" rows="6" cols="50"></textarea><br/>
<input type="submit" value="Save" />
<?php echo anchor('admin','Cancel'); ?>
</form>
in controller little chagnes
function create(){
$data['userId'] = $this->tank_auth->get_user_id();
$data['username'] = $this->tank_auth->get_username();
$this->form_validation->set_rules('title','title','required');
$this->form_validation->set_rules('summary','summary','required');
$this->form_validation->set_rules('content','content','required');
if($this->form_validation->run()==FALSE)
{
$this->load->view('template/admin_html_head',$data);
$this->load->view('admin/create',$data);
$this->load->view('template/html_tail',$data);
} else {
$data = $this->input->post();
$this->posts->insert_post($data);
redirect('admin');
}
}
Use session library
check this another stackoverflow thread to know how to use session
In order to use session library, u need to configure encryption_key in config.php
To do that, check this out
Related
$_POST won't recognize the value mailuid from the login form on this page or others (profile page).
$_Get methods do not work because of how the login system is built and unsecured.I need mailuid value to bring them to their own profiles page after login.
Login Form since its's post method I should be able to grab the value on other pages and this one
<div class="modal">
<div class = "modal-content">
<section class="section-default">
<h1>Login</h1>
<?php
if (!isset($_SESSION['Id'])) {
echo'<form action="includes/login.inc.php" method="post">
<input type="text" name="mailuid" placeholder="Username/E-mail...">
<input type="password" name="pwd" placeholder="Password...">
<button type="submit" name="login-submit">Login</button>
</form>';
} else if (isset($_SESSION['Id'])) {
echo '<div class="signup12">
You Do not have an account? Sign Up
</div>
<div class="forgotpwd">
Forgot your password?
</div>';
}
?>
</section>
</div>
</div>
Temporary check for the mailuid value. Supposed to grab the value form the login form a spit it back out, to check to see if it is recognized
<?php
$user = $_POST["mailuid"];
if (isset($_POST["mailuid"]))
{
$user = $_POST["mailuid"];
echo $user;
echo " is your username";
}
else
{
$user = null;
echo "no username supplied";
}
?>
First I would clean this up:
$user = $_POST["mailuid"];
if (isset($_POST["mailuid"]))
{
$user = $_POST["mailuid"];
echo $user;
echo " is your username";
}
else
{
$user = null;
echo "no username supplied";
}
Instead it can be written more concise:
$user = isset($_POST["mailuid"]) ? $_POST["mailuid"] : false;
if( $user ){
echo "{$user} is your username";
} else {
echo "no username supplied";
}
I prefer Boolean false over NULL, null just means it doesn't exist. Boolean false lets you know you checked it and it didn't exist. Generally should should access $_POST as few times as you can. This is because you should never trust $_POST.
$_Get methods do not work because of how the login system is built and unsecured.
Post is no more secure than get, it's quite easy to post anything to the page even without visiting the site by using something like PostMan etc. Once you assign it to a local variable you know you have at least normalized the data, even if you haven't sanitized it yet.
Also don't forget to call session_start before trying to access $_SESSION. Because of the vagueness of the question, it could be that the form works fine, just the session data isn't being maintained because you haven't started the session yet.. etc....
Hope it helps.
Personally I would clean up the HTML part that makes the form as well, so instead of this:
<div class="modal">
<div class = "modal-content">
<section class="section-default">
<h1>Login</h1>
<?php
if (!isset($_SESSION['Id'])) {
echo'<form action="includes/login.inc.php" method="post">
<input type="text" name="mailuid" placeholder="Username/E-mail...">
<input type="password" name="pwd" placeholder="Password...">
<button type="submit" name="login-submit">Login</button>
</form>';
} else if (isset($_SESSION['Id'])) {
echo '<div class="signup12">
You Do not have an account? Sign Up
</div>
<div class="forgotpwd">
Forgot your password?
</div>';
}
?>
</section>
</div>
</div>
I would do something like this:
<div class="modal">
<div class = "modal-content">
<section class="section-default">
<h1>Login</h1>
<?php if (!isset($_SESSION['Id'])){ ?>
<form action="includes/login.inc.php" method="post">
<input type="text" name="mailuid" placeholder="Username/E-mail...">
<input type="password" name="pwd" placeholder="Password...">
<button type="submit" name="login-submit">Login</button>
</form>
<?php }else{ ?>
<div class="signup12">
You Do not have an account? Sign Up
</div>
<div class="forgotpwd">
Forgot your password?
</div>';
<?php } ?>
</section>
</div>
</div>
See how much cleaner that is. Most of this is just readability issues. For example there is no need to check if isset($_SESSION['Id']) in the else if condition, because it's either set or not. This is one less place to maintain the session variable key, and it makes the code less convoluted.
As for the actual problem, as long as you are reaching the above code after submission of the form, it should work. So that leads me to believe that you have something wrong in the action.
You should get a clean page after going to includes/login.inc.php meaning there shouldn't be much in the way of HTML. One thing you can do that is real simple is just add at the top:
die(__LINE__.' of '.__FILE__);
$user = isset($_POST["mailuid"]) ? $_POST["mailuid"] : false;
//... other code
What this will do is die which kills PHP execution, but outputs the argument you passed in. In this case I'm just putting the line and file that the die is on, that way it's easier to find later. But the point is to see if you are even hitting the correct ending script or the forms action/endpoint.
I only suggest this because you are really vague in what it's current behaviour is
$_POST won't recognize the value mailuid from the login form on this page or others (profile page).
For example, this doesn't tell me if you are even hitting the right page. Now had you said something like "all it does is output no username supplied". Then I would at lest know that. As I said above it could be just an omission of sesion_start() which must be called before attempting to access any $_SESSION stuff. You should call it only once, at the top of each page that uses sessions.
Although it's not a solution, it was too much to post in a comment. I would really like to help you more, but there just isn't enough information to go on.
My base_url() is adding more bits into the url than it should be. What is wrong with my setup? I have the helper set up in config.php:
$autoload['helper'] = array('url');
My base_url() is set to: index.php/
So the problem is that when I activate this form:
<h1>sometimes haikus don't make sense refrigerator</h1>
<form action="<?php echo base_url(); ?>welcome/login_submit" method="post">
<label>
email:
<input id="email" name="email" />
</label>
<label>
password:
<input type="password" id="password" name="password" />
</label>
<input type="submit" value="Log me in!" />
</form>
The first time I access it, I'll type in: localhost/CIintranet/ and the the base_url() gets added next so it becomes: localhost/CIintranet/index.php/
I'm trying to program a login logout system though. So if the user login is incorrect, I want it to redirect back to the login page. Here's the code from the controller for that part:
public function login_submit() {
$this->load->model('LoginChecker', 'users');
//$this->load->view('login_submit');
$match = $this->users->authenticate_user( $_POST['email'], $_POST['password'] );
if( $match )
{
$this->load->view('login_submit');
echo "User exists in database!";
}
else
{
$this->load->view('login_form');
echo "<h1>Email or password is wrong, bretheren!</h1>";
}
}
But when it reloads the login_form, it adds another part into the url and the url fails. So the progression is like this:
Page loads to this url:
localhost/CIintranet/
First failed attempt (page still loads properly):
localhost/CIintranet/index.php/welcome/login_submit
Second failed attempt (page fails to load):
localhost/CIintranet/index.php/welcome/index.php/welcome/login_submit
I've been doing some research on this for a bit now and I'm noting a lot of people talking about the htaccess file in relation to this problem but nobody seems to mention specifically what fixes it or how to configure the base_url() so that it just takes care of this properly. I tried looking at the documentation but perhaps I missed something. I didn't find what I was looking for.
Any ideas?
Can you try setting the base_url to /index.php/? So it has the forward slash at the front too?
Failing that, please try: http://localhost/CIintranet/index.php/
It's usually the simple things!
if you use ... ?
<?php echo form_open('welcome/login_submit') ?>
...
<?php echo form_close(); ?>
activate helper: form
I am new to code igniter. I've created a form but it is not display properly.
When I put
<?php echo form_open('sms'); ?> instead of <form action="">tag
here in my form and controller, I can't understand why it is not displayed.
<?php echo form_open('sms'); ?>
<p>
<label><strong>Username</strong>
<input type="text" name="textfield" class="inputText" id="textfield" />
</label>
</p>
<p>
<label><strong>Password</strong>
<input type="password" name="textfield2" class="inputText" id="textfield2" />
</label>
</p>
<input type="submit" value="Authentification" name="auth" />
<label>
<input type="checkbox" name="checkbox" id="checkbox" />
Remember me</label>
</form>
and my controller is
<?php
class sms extends CI_Controller{
function school(){
$this->load->view('school/index.php');
if($this->input->post('auth',TRUE)){
$this->load->view('school/dashboard.php');
}
else{
$this->load->view('school/index.php');
}
}
}
?>
If this is your entire script for the most part, it looks like you need to load the helper first from the CodeIgniter Form Helper Page.
If you don't have this line, try adding it before the form_open() function:
<?php $this->load->helper('form'); ?>
While I have used CodeIgniter, it's been a while. Let me know if that changes the result.
Edit: Since you've chosen my answer I'll include this one, credits go out to devo:
You could change </form> to: <?php echo form_close(); ?>. There are pros and cons for this method though, and without using arguments you might be better off sticking with </form>.
I'll explain further:
<div class="registration">
<div class="form-box">
<?php $this->load->helper( 'form' ); ?>
<?php $end = '</div></div>'; ?>
<?php echo form_open( 'register' ); ?>
<!-- Form Inputs Here -->
<?php echo form_close( $end ); ?>
<!-- Echos '</form></div></div>' -->
So for closing the form without arguments, the </form> tag works best, both by performance and simplicity. The example used above is a rather simplistic view of what you can do with it, since what I wrote is not very efficient either.
However, this is still php we're talking about, so perhaps the craftier among us could put it to better use.
End Edit
Have you loaded the form helper? You can use $this->load->helper('form'); in your controller action, her inside function school(). You can then use form helper in the view pages.
Load form helper,
$this->load->helper('form');
And use,
echo form_close()
Instead of,
</form>
First in your Controller put in:
$this->load->helper('form');
And Change </form> to :
<?php echo form_close(); ?>
I think that this problem occurs often on a web application development. But I'll try to explain in details my problem.
I'd like to know how to correct this behavior, for example, when I have a block of code like this :
<?
if (isset($_POST['name'])) {
... operation on database, like to insert $_POST['name'] in a table ...
echo "Operation Done";
die();
}
?>
<form action='page.php' method='post' name="myForm">
<input type="text" maxlength="50" name="name" class="input400" />
<input type="submit" name="Submit" />
</form>
When the form gets submitted, the data get inserted into the database, and the message Operation Done is produced. Then, if I refreshed the page, the data would get inserted into the database again.
How this problem can be avoided? Any suggestion will be appreciated :)
Don't show the response after your create action; redirect to another page after the action completes instead. If someone refreshes, they're refreshing the GET requested page you redirected to.
// submit
// set success flash message (you are using a framework, right?)
header('Location: /path/to/record');
exit;
Set a random number in a session when the form is displayed, and also put that number in a hidden field. If the posted number and the session number match, delete the session, run the query; if they don't, redisplay the form, and generate a new session number. This is the basic idea of XSRF tokens, you can read more about them, and their uses for security here: http://en.wikipedia.org/wiki/Cross-site_request_forgery
Here is an example:
<?php
session_start();
if (isset($_POST['formid']) && isset($_SESSION['formid']) && $_POST["formid"] == $_SESSION["formid"])
{
$_SESSION["formid"] = '';
echo 'Process form';
}
else
{
$_SESSION["formid"] = md5(rand(0,10000000));
?>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
<input type="hidden" name="formid" value="<?php echo htmlspecialchars($_SESSION["formid"]); ?>" />
<input type="submit" name="submit" />
</form>
<?php } ?>
I ran into a similar problem. I need to show the user the result of the POST. I don't want to use sessions and I don't want to redirect with the result in the URL (it's kinda secure, I don't want it accidentally bookmarked). I found a pretty simple solution that should work for the cases mentioned in other answers.
On successfully submitting the form, include this bit of Javascript on the page:
<script>history.pushState({}, "", "")</script>
It pushes the current URL onto the history stack. Since this is a new item in history, refreshing won't re-POST.
UPDATE: This doesn't work in Safari. It's a known bug. But since it was originally reported in 2017, it may not be fixed soon. I've tried a few things (replaceState, etc), but haven't found a workaround in Safari. Here are some pertinent links regarding the issue:
Safari send POST request when refresh after pushState/replaceState
https://bugs.webkit.org/show_bug.cgi?id=202963
https://github.com/aurelia/history-browser/issues/34
Like this:
<?php
if(isset($_POST['uniqid']) AND $_POST['uniqid'] == $_SESSION['uniqid']){
// can't submit again
}
else{
// submit!
$_SESSION['uniqid'] = $_POST['uniqid'];
}
?>
<form action="page.php" method="post" name="myForm">
<input type="hidden" name="uniqid" value="<?php echo uniqid();?>" />
<!-- the rest of the fields here -->
</form>
I think it is simpler,
page.php
<?php
session_start();
if (isset($_POST['name'])) {
... operation on database, like to insert $_POST['name'] in a table ...
$_SESSION["message"]="Operation Done";
header("Location:page.php");
exit;
}
?>
<html>
<body>
<div style='some styles'>
<?php
//message here
echo $_SESSION["message"];
?>
</div>
<form action='page.php' method='post'>
<!--elements-->
</form>
</body>
</html>
So, for what I needed this is what works.
Based on all of the above solutions this allows me to go from a form to another form, and to the n^ form , all the while preventing the same exact data from being "saved" over and over when a page is refreshed (and the post data from before lingers onto the new page).
Thanks to those who posted their solution which quickly led me to my own.
<?php
//Check if there was a post
if ($_POST) {
//Assuming there was a post, was it identical as the last time?
if (isset($_SESSION['pastData']) AND $_SESSION['pastData'] != $_POST) {
//No, Save
} else {
//Yes, Don't save
}
} else {
//Save
}
//Set the session to the most current post.
$_session['pastData'] = $_POST;
?>
We work on web apps where we design number of php forms. It is heck to write another page to get the data and submit it for each and every form. To avoid re-submission, in every table we created a 'random_check' field which is marked as 'Unique'.
On page loading generate a random value and store it in a text field (which is obviously hidden).
On SUBMIT save this random text value in 'random_check' field in your table. In case of re-submission query will through error because it can't insert the duplicate value.
After that you can display the error like
if ( !$result ) {
die( '<script>alertify.alert("Error while saving data OR you are resubmitting the form.");</script>' );
}
No need to redirect...
replace die(); with
isset(! $_POST['name']);
, setting the isset to isset not equal to $_POST['name'], so when you refresh it, it would not add anymore to your database, unless you click the submit button again.
<?
if (isset($_POST['name'])) {
... operation on database, like to insert $_POST['name'] in a table ...
echo "Operation Done";
isset(! $_POST['name']);
}
?>
<form action='page.php' method='post' name="myForm">
<input type="text" maxlength="50" name="name" class="input400" />
<input type="submit" name="Submit" />
</form>
This happen because of simply on refresh it will submit your request again.
So the idea to solve this issue by cure its root of cause.
I mean we can set up one session variable inside the form and check it when update.
if($_SESSION["csrf_token"] == $_POST['csrf_token'] )
{
// submit data
}
//inside from
$_SESSION["csrf_token"] = md5(rand(0,10000000)).time();
<input type="hidden" name="csrf_token" value="
htmlspecialchars($_SESSION["csrf_token"]);">
I think following is the better way to avoid resubmit or refresh the page.
$sample = $_POST['submit'];
if ($sample == "true")
{
//do it your code here
$sample = "false";
}
I'm having trouble getting the form validation library to send my form errors back to my form in this case.
I have a controller that handles uploading images called addImage.php. This controller only handles the do_upload processing. I have a view called uploadimage.php that contains the upload form and submits to /addImage/do_upload.
The upload form is loaded on the front page of my website using a template in code igniter using
<?php $this->load->view('uploadimage'); ?>
The front page controller is contained in home.php
Right now after validation fails, I'm just redirecting to the homepage which clearly doesn't load the errors back (in addImage.php)
if($this->_submit_validate() == FALSE)
{
redirect('/', 'location');
return;
}
How can I redirect to my template_front.php while keeping those errors. Can I somehow call my home.php controller from the uploadimage.php controller to do this? I've confused myself trying to explain it! If this is totally unclear, let me know and I'll try to clarify.
Per the Documentation, you are suppose to simply re-load the view file on failure.
if ($this->form_validation->run() == FALSE)
{
$this->load->view('myform');
}
else
{
$this->load->view('formsuccess');
}
a redirect generates a new server request which flushes the validation error information.
on validation failure you should reload the form. May be you want to add a button to concel uploading.
On the view, you should add some tag to show errors (there are lots of info about validation helpares) like in:
<?=form_open_multipart("/personas/savefoto", array('class' => "form3") )?>
<h3><?=$heading?></h3>
<div class="center">
<?php echo '<strong>'.mb_convert_case($record['nombre'].' '.$record['apellido1'].' '.$record['apellido2'], MB_CASE_TITLE).'</strong><br/>';
if( file_exists("fotos/e".MATRIZ."/b".$record['id'].".jpg")){
?>
<img class="foto" src="<?php echo base_url()."fotos/e".MATRIZ."/b".$record['id']?>.jpg"/>
<br/><br/>
<?php
} ?>
</div>
<div class="form-row">
<label for="imagen">Nueva imagen <br/>(jpg, gif o png)</label>
<input type="file" name="userfile" size="20" />
<br/>
<?php if(isset($error_image)) echo '<p class="error">'.$error_image.'</p>'; ?>
</div>
<div class="form-row center">
<input type="submit" value="Aceptar" />
<input type="button" value="Cancelar" onclick="location.href='/system.php/personas/admin';">
</div>
<?=form_close();?>
look for the if(isset($error_image))
You could utilize the validation_errors() function and set them to a session variable
$this->session->set_userdata(array('form_errors', validation_errors()));
then access them on your redirect page.
echo $this->session->userdata('form_errors');
$this->session->unset_userdata('form_errors'); // prevent them from being stored past use