In codeigniter we can define the url that should be displayed in the browser. I have a login page which goes well when the credentials are given right. I need to show an error message in the same page itself if the credentials are wrong. For that i have did the followings.
<div style="<?php echo ($status==='err')?'display:block':''?>" class="form-login-error">
<h3>Invalid login</h3>
<p>Please enter correct email and password!</p>
</div>
and
$data['status'] = (isset($_GET['status']))?$_GET['status']:true;
in controllers's index function
if($userdata['status'] == 'success')
{
if(!empty($userdata['userdet']))
{
$this->session->set_userdata($userdata['userdet']);
redirect('dashboard');
}
}else{
redirect('login?status=err');
}
The code works well. but my doubt is can i change the url pattern? It is now showing loclhost/myproject/login?status=err.Can i change this to localhost/myproject/loginerror? I tried to define in routes, but it is showing page not found error. Thanks in advance.
You are making a simple thing much complex by using URL's param's here.
I would suggest using CI session Flashdata. The benefit of using Flashdata is that the session variable is maintained only for the next page and then the session variable is cleared automatically so it is very useful in cases where we need to display some messages to users.
Change your code to something like this :
<div style="<?php echo ($this->session->flashdata('error') )?'display:block':''?>" class="form-login-error">
<h3>Invalid login</h3>
<p>Please enter correct email and password!</p>
</div>
and in your controller :
if($userdata['status'] == 'success')
{
if(!empty($userdata['userdet']))
{
$this->session->set_userdata($userdata['userdet']);
redirect('dashboard');
}
}else{
$this->session->set_flashdata('error', 1);
redirect('login');
}
use the codeigniter application/config/routes.php
$route['myproject/login/(:any)']="myproject/login/$1";
youcan hold the value of parameter in action of controller.
Related
I'm using codeigniter 3, and flashdata to show an error message to the user when inserting an invalid username or password.
The problem is that the message is always showing even when the page was just opened and no password or username was inserted.
EDIT:
The comparison and the authentication are right but when i open the page it still appear even when no action was taken.
this is the form
<?php echo $this->session->flashdata('msg');?>
and this is the controller
public function authentication(){
//post user unput
$empNum=$this->input->post('employeeNum');
$pwd=$this->input->post('password');
$user=$this->empNumAuth($empNum, $pwd);
if($user) {
if($user['PrivilegeLevel']==='1'){
$this->session->set_userdata($user);
redirect('AdminDashboard/view');
}
else if($user['PrivilegeLevel']=='2') {
$this->session->set_userdata($user);
redirect('UserDashboard/view');
}
}
else {
$this->session->set_flashdata('msg','الرقم الوظيفي او رمز الدخول خاطئ');
redirect('Login/LoginPage');
}
From your code, the flashdata is set whenever the authentication fails( $this->empNumAuth() returns false). So if the path /authentication gets called, and no password or username is entered, it passes blank values to the empNumAuth() function, which will definitely return a false value(since blank values were passed, so the authentication will fail). Otherwise, if you feel the flashdata should not be shown, and you are sure valid credentials were submitted, then the problem lies within the empNumAuth() function, start checking from there.
BONUS:
If you are echoing the flashdata message within an error/success div, it will always display, with no text on it. That is, suppose you have an error div formatted with a red background, when you echo the flashdata directly as you did, the error div will be displayed but with blank text. The best way is to check if the flashdata is set before echoing it. See the example below. (I have used default Bootstrap error alert div)
<?php if($this->session->flashdata('msg'){?>
<div class="alert alert-danger"><?php echo $this->session->flashdata('msg');?>
</div>
<?php } ?>
The above code checks if the flashdata is set which will prevent the flashdata div from being displayed always.
Use the above code in view file...
<?php
if($this->session->flashdata('msg')
{
?>
<div class="alert alert-danger"><?php echo $this->session->flashdata('msg');?>
</div>
<?php
}
?>
I am making a website in CodeIgniter and for one of these pages I need to insert information into a database, however every time I enter information into my form and submit it, the page refreshes like it had been submitted but nothing enters the database.
Controller:
public function insertjob()
{
$this->load->helper('form');
$data['title']="Add a new job";
$this->load->view("insertjob", $data);
}
public function addingjob()
{
$jobtype=$this->input->post('jobtype');
$jobinfo=$this->input->post('jobinfo');
$this->load->model("cmodel");
if($this->cmodel->addjob($jobtype, $jobinfo)){
$data['msg']="New job addition successful";
}else{
$data['msg']="There was an error please try again";
}
$this->load->view("confirmation",$data);
Model:
function addjob($jobtype,$jobinfo)
{
$newjob=array("jobtype"=>$jobtype,"jobinfo"=>$jobinfo);
return $this->db->insert('clientjobs', $newjob); exit;
View:
</p>
<?php
echo form_open('client/insertjob');
echo form_label('Job:', 'Job');
echo form_input('jobtype');
echo form_label('Job information:', 'Job information');
echo form_input('jobinfo');
echo form_submit('Add job', 'Submit Post!');
echo form_close();
?>
Try removing the exit from your model:
function addjob($jobtype,$jobinfo)
{
$newjob=array("jobtype"=>$jobtype,"jobinfo"=>$jobinfo);
return $this->db->insert('clientjobs', $newjob);
}
It's not neccessary and could be breaking the database class, as well as halting any execution for the application.
Here's your problem:
echo form_open('client/insertjob');
If you look at your HTML code in your browser, you'll see something like this:
<form action="client/insertjob">
There will probably be a whole bunch of other attributes in your form tag - they're not important for this answer.
That action attribute is telling the browser where to go after you click submit. Where is it going? Back to the insertjob method. But it needs to go to your addingjob method - that's where the database update is actually being done. So change the form_open call to:
echo form_open('client/addingjob');
As I see your are using 2 controller functions for posting, page 1 to page 2. You have error on form open you should post your data to addingjob not insertjob.
echo form_open('client/addingjob');
will fix your issue but I highly recommend you to use, one controller for form submit. Below code will send post to same url. And you could add some attributes on it.
<?php
$attributes = array('class' => 'form-horizontal');
echo form_open($this->uri->uri_string(),$attributes); ?>
Basically I'v got a HTML Form that links to a php file in a different location for it's action, Currently I'm using the form to update the users profiles and then send them back to the editprofile.php. Basically at the top of editprofile.php if they've submitted the query I want to display the result of either "Profile Updated" or "Failed to Update", issue is I can't workout how to display query results when the query is in a different file.
I tried to do this;
<?php
if(!$query)
{
echo '<div class="editfail">Profile failed to update!</div>';
}
else
{
echo '<div class="editsuccess">Profile successfully updated!</div>';
}
?>
Except the issue with this is that the query hasn't been run on this page, it was run from another page and then redirected back to the editprofile page using a header, so how can I display the same results as above when the query is being executed from another location?
You can send parameter when you are redirecting back the file.
example
if(mysql_query($update_query))
{
header('location:editprofile.php?msg="success to save"');
}
else
{
header('location:editprofile.php?msg="failed to save"');
}
Or even you can send flag also
if(mysql_query($update_query))
{
header('location:editprofile.php?flag=0');
}else
{
header('location:editprofile.php?flag=1');
}
And check the value of flag in your editprofile.php file to display proper message.
You shouldn't mess around with the headers fxn unless you need to - depending on output_buffer settings etc they can be a pain:
You can do what you want - all in 1 single page:
So something like this -As a matter of common convention, and to a degree security, you should post the form to itself - you can integrate whatever else from the other page into the pass/fail profile logic block:
<?php
$query = htmlentities($_POST['profiletext']); #sanitize avec tu code du jour
if(!$query || $query != 'someacceptablevalue))
{
#If it's not posted, or its not a good value, tell them it failed
# and redisplay the form to try again
$query_msg = '<div class="editfail">Profile failed to update!</div>';
$profile_form = "<div_class='profile_rest_of_page stuff'>
<form action='#' method='post'>
<input type='text' id='profiletext' name='profiletext/>
</form>
</div>";
}
else
{
# They did it - Success, and link to next step
$query_msg = '<div class="editsuccess">Profile successfully updated!</div>';
$profile_form = 'No form needed - you did it';
}
#One block below handles all in 1 page with above logic:
echo "<body>
<div class='profile_message_container'>
$query_msg
</div>
<div_class='profile_rest_of_page stuff'>
$profile_redo<br/> You did it <a href='next'>next</a>
</div>
</body>
";
?>
You can do this in two ways:
Send the query results in the link like a GET which could be tampered with
Process the form in the same page that has your form as follows
if(isset($_POST['some_name'])) {
// Process form
} else {
// Display form
}
My developer built our registration page to display a div when logins failed based on a string in the URL.
When logins fail this is added to the URL /login?msg=invalid
The PHP in my login.phtml which displays the error messages based on the msg= parameter is
<?php
$msg = "";
$msg = $_GET['msg'];
if($msg==""){ $showMsg = ""; }
elseif($msg=="invalid"){ $showMsg = ' <div class="alert alert-error">
<a class="close" data-dismiss="alert">×</a>
<strong>Error!</strong> Login or password is incorrect!
</div>'; }
elseif($msg=="disabled"){ $showMsg = "Your account has been disabled."; }
elseif($msg==2){ $showMsg = "Your account is not activated. Please check your email."; }
?>
In the controller the redirect to that URL is
else //email id does not exist in our database
{
//redirecting back with invalid email(invalid) msg=invalid.
$this->_redirect($url."?msg=invalid");
}
I know there are a few other validation types for disabled accounts etc. I'm in the process of redesigning the entire interface and would like to get rid of this kind of validation so that the div tags display when logins fail but not show the URL strings.
If it matters the new div I want to display is
<div class="alert alert-error alert-login">
Email or password incorrect
</div>
I'd like to replace the php my self in my login.phtml and controller but not a good programmer. What can I replace $this->_redirect($url."?msg=invalid"); with so that no strings are added to the URL and display the appropriate div tags?
Thanks
Passing a msg through a GET parameter is a bit weird to me.
See this thread discussing other ways to send a message to the page, using sessions, cookies or database, here.
I'm not familiar with the zend framework, but there has to be a way to set a "flash" message through the session.
change this in loginAction of your contorller
$this->_redirect($url."?msg=invalid");
to
$this->view->message = $msg;
then add to your code to login.phtml
<?php if ($this->message) :?>
<div class="alert alert-error alert-login">
Email or password incorrect
</div>
<? endif; ?>
... your form code there
I've been searching about deleting db entries in Codeigniter and I finally created a solution that I think is secure. I would really appreciate any feedback! I'm not sure if I'm doing this right..
Advantages:
Uses POST request
ID of entry to be deleted is
validated
Uses CSRF protection (automatically
generated by Codeigniter)
In my example I'm deleting user submitted links (a DB table row contains a link title, link URL, an link description).
HTML: Database entires are contained within a form. Each entry has a form button with the respective link id in the id attribute.
<?php echo form_open('profile/remove_link'); ?>
<?php echo form_hidden('link_id', ''); //value will be populated via jquery ?>
<ul id="user_links">
<?php foreach($query as $row): ?>
<li><?php echo $row->link_title; ?></li>
<li><?php echo auto_link($row->link_url, 'url', TRUE); ?></li>
<li><?php echo $row->link_description; ?></li>
<button type="submit" class="remove" id="<?php echo $row->link_id ?>" value="remove">Remove Link</button>
<?php endforeach; ?>
</ul>
</form>
JQUERY: When user clicks on the remove button, the respective link id is added to the the hidden text input named link_id.
$(document).ready(function(){
$('.remove').click(function() {
var link_to_remove = $(this).attr("id");
$("input[name=link_id]").val(link_to_remove);
});
});
Upon clicking a remove button, it sends the id of link to be removed to controller profile and function remove_link
function remove_link()
{
$this->load->model('Profile_model');
$links_data['query'] = $this->Profile_model->links_read(); //get links from db to add in view
//Validation
$this->form_validation->set_rules('link_id', 'Link ID', 'trim|required|xss_clean|max_length[11]|numeric'); //validate link id
if ($this->form_validation->run() == FALSE) //if validation rules fail
{
$this->load->view('profile/edit_links_view', $links_data);
}
else //success
{
$link_id = $this->input->post('link_id'); //get id of link to be deleted
$seg = 'user_links'; //used to redirect back to user links page
$this->Profile_model->links_delete($link_id, $seg); //send link id to model function
}
}
MODEL
function links_delete($link_id, $seg)
{
$this->db->where('user_id', $this->tank_auth->get_user_id());
$this->db->where('link_id', $link_id);
$this->db->delete('user_links');
redirect("/profile/$seg/");
}
If the ids are unique integers in your database, you could remove these rules:
trim|xss_clean|numeric
And add this one:
is_natural_no_zero
Returns FALSE if the form element contains anything other than a natural number, but not zero: 1, 2, 3, etc.
The numeric rule allows some characters you probably don't want, like decimals and negative. Here's the source (one line):
return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
If for some reason you are echo'ing the input back in your HTML output before validating, or are just paranoid, then by all means: xss_clean it up. Otherwise it's not really needed, as I don't think there's any possible method of XSS attacks that only use a number.
Reference:
https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29
http://ha.ckers.org/xss.html
Also, you might want to add a LIMIT 1 clause to your query, and definitely make sure to return a value (probably TRUE/FALSE) from your model so you know whether or not the query was successful, so you can give feedback to the user instead of assuming everything went well.
The only thing that I see wrong is that you don't validate who can and can't delete records. That's the only issue you should focus on. Permissions to check if the person sending the request of deletion is allowed to perform such operations. Other than that it's just a matter of preference.
I would suggest rewriting controller and model a bit to make the flow more logical and provide better performance:
controller:
function remove_link()
{
if ($this->input->post('link_id'))
{
//Validation
$this->form_validation->set_rules('link_id', 'Link ID', 'is_natural_no_zero');
if ($this->form_validation->run())
{
$seg = 'user_links'; //do you really need to assign it to variable ??
$this->load->model('Profile_model');
if ($this->Profile_model->links_delete($this->input->post('link_id')) //send link id to model function
{
redirect('/profile/user_links'); // redirect user in controller and only when model returns true
}else{
// inform user about error somehow, eg. by setting session flashdata and redirecting back to /profile/user_links
}
}
} // else statement here was a mistake as in case of form_validation failure nothing happened
$this->load->model('Profile_model');
$links_data['query'] = $this->Profile_model->links_read(); //get links from db to add in view
$this->load->view('profile/edit_links_view', $links_data);
}
model:
function links_delete($link_id)
{
$this->db->where('user_id', $this->tank_auth->get_user_id())
->where('link_id', $link_id)
->delete('user_links'); // you can chain methods without writing always $this->db->
return $this->db->affected_rows(); // returns 1 ( == true) if successfuly deleted
}
And as a side note in your jQuery code I suggest using $('#some_id') instead of $('input[name=XXXX]') - it saves some javascript code execution thus is faster