Posting data twice into the database - CodeIgniter - php

So i started my first CodeIgniter project, and I'm still learning a lot of things. Right now I've made this user sign-up page.
When the user fills in the sign-up form and presses submit it will trigger the following function:
/**
* Signup validation
*/
public function signup_validation(){
$this->load->library('form_validation');
$this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email|is_unique[users.email]');
$this->form_validation->set_rules('password', 'Password', 'required|trim');
$this->form_validation->set_rules('cpassword', 'Confirm Password', 'required|trim|matches[password]');
$this->form_validation->set_message('is_unique', "That email address is already is use");
if($this->form_validation->run()){
$this->load->model('model_users');
if ($this->model_users->add_user()){
echo "user has been added";
} else {
echo "Something went wrong";
}
$this->model_users->add_user();
} else {
$this->load->view('view_signup');
}
}
This function then makes a call to "model_users" and runs the function "add_user":
public function add_user(){
$data = array(
'email' => $this->input->post('email'),
'password' => $this->input->post('password')
);
$query = $this->db->insert('users', $data);
if ($query){
return true;
} else {
return false;
}
}
So this codes adds the data in the database fine. The validation works great. But for some reason it adds every user twice. I've tried to figure out what causes this problem, but I cannot seem to find out why.
I've also created another small piece of code where you can add page-categories into the database, the code is very similar, but it does not post twice.

You call
$this->model_users->add_user()
twice.
Once in the if statement as a condition and again after the else. Remove the second call.

$this->model_users->add_user() is called twice once inside if() and once after if else.
if ($this->model_users->add_user()){
echo "user has been added";
} else {
echo "Something went wrong";
}
$this->model_users->add_user();
I think you want to remove the below one.

Related

What prevents data from being inserted in CI?

I have set the CI framework with database connection, put it on autoload and created a form, yet still, nothing is inserted into the Database!
I've tried using objects(classes) and different ways to pass information in an array
if (isset($_POST['register-submit'])) {
$this->load->model('Registermodel');
$this->load->library('form_validation');
$this->form_validation->set_rules('register-username', 'Username', 'required');
$this->form_validation->set_rules('register-password', 'Password', 'required|min_length[6]');
$this->form_validation->set_rules('register-password-repeat', 'confirm passphrase', 'required|min_length[6]|matches[register-password]');
$this->form_validation->set_rules('register-pin', 'pin', 'required|regex_match[/^[0-9]{6}$/]');
//If form validation was successful
if ($this->form_validation->run() == TRUE) {
echo 'successfully registered!';
//Add user to database
$data = array(
'ci_useruniqid'=> $_POST['register-uniqid'],
'ci_userdate'=> $_POST['register-date'],
'ci_useruid'=> $_POST['register-username'],
'ci_userpwd'=> password_hash($_POST['register-password'], PASSWORD_DEFAULT),
'ci_usermnemonic'=> $_POST['register-mnemonic'],
'ci_usercurrentaddress'=> $_POST['register-address'],
'ci_useraccount'=> $_POST['register-account'],
'ci_useraccountbalance'=> $_POST['register-account-balance'],
'ci_userpin'=> $_POST['register-pin'],
'ci_userstatus'=> $_POST['register-status'],
'ci_usertype'=> $_POST['register-type'],
'ci_userinfo'=> $_POST['register-info'],
'ci_userpgp'=> $_POST['register-pgp'],
'ci_usercurrency'=> $_POST['register-currency']
);
$this->RegisterModel->adduser($data);
redirect("AuthController/loginview", "refresh");
}
What I expect to happen is for the data(as seen above) to be inserted into the DB. My actual result is no response even something as simple as echoing something out in an if statement.
My table structure:
ci_userid int(11)
ci_useruniqid
ci_userdate date
ci_useruid
ci_userpwd
ci_usermnemonic
ci_usercurrentaddress
ci_useraccount
ci_useraccountbalance decimal(12,8)
ci_userpin
ci_userstatus
ci_usertype
ci_userinfo
ci_userpgp
ci_usercurrency
The rest are text, here is my adduser model:
public function adduser($data) {
$insert = $this->db->insert('users', $data);
}
As this was too long for a comment, I present to you my quasi answer that will help you debug.
echo 'hello world <br><pre>';
print_r($_POST);
if (isset($_POST['register-submit'])) {
$this->load->model('Registermodel');
$this->load->library('form_validation');
$this->form_validation->set_rules('register-username', 'Username', 'required');
$this->form_validation->set_rules('register-password', 'Password', 'required|min_length[6]');
$this->form_validation->set_rules('register-password-repeat', 'confirm passphrase', 'required|min_length[6]|matches[register-password]');
$this->form_validation->set_rules('register-pin', 'pin', 'required|regex_match[/^[0-9]{6}$/]');
//If form validation was successful
if ($this->form_validation->run() == TRUE) {
echo 'successfully registered!';
//Add user to database
$data = array(
'ci_useruniqid' => $_POST['register-uniqid'],
'ci_userdate' => $_POST['register-date'],
'ci_useruid' => $_POST['register-username'],
'ci_userpwd' => password_hash($_POST['register-password'], PASSWORD_DEFAULT),
'ci_usermnemonic' => $_POST['register-mnemonic'],
'ci_usercurrentaddress' => $_POST['register-address'],
'ci_useraccount' => $_POST['register-account'],
'ci_useraccountbalance' => $_POST['register-account-balance'],
'ci_userpin' => $_POST['register-pin'],
'ci_userstatus' => $_POST['register-status'],
'ci_usertype' => $_POST['register-type'],
'ci_userinfo' => $_POST['register-info'],
'ci_userpgp' => $_POST['register-pgp'],
'ci_usercurrency' => $_POST['register-currency']
);
$this->RegisterModel->adduser($data);
echo 'success';
//redirect("AuthController/loginview", "refresh");
} else {
echo validation_errors();
}
} else {
echo 'register-submit... well... does not exist';
}
Please note, use $this->input->post('somename'); for all your $_POST stuff. e.g. assume that register-uniqid doesn't exist (form validation won't catch it because it isn't required) you'll get an undefined index error; thus you'd have to do isset($_POST['register-uniqid']) ? $_POST['register-uniqid'] : null whereas $this->input->post() does that logic for you.
Now, even if you make this fix, if register-uniqid is absolutely critical (cannot be null) then make sure form validation covers it with a required. Even though you may have some hidden fields, it doesn't mean the user can't delete them if they want and post a null to that db column. I would suggest forgoing hidden fields entirely and coding any non-user-related input in to this controller or model.

CodeIgniter - username and email existence check doesn't work

I'm trying to check whether or not an email or username exists in the database before inserting data into the database. For a reason I do not understand, despite using the email_exists and username_exists functions, when inserting the data, the database throws a field not unique error for username and email fields.
The username_exists and email_exists functions gets any usernames or emails where they match the username or email submitted by the form. The functions then return true if there is a username or email that exists, or false if the opposite. When both functions return false (i.e. username and email don't exist in the database) it inserts the form data into the database.
Any help would be great!
Controller Function
public function register(){
if($this->session->userdata('loggedIn') == TRUE){
$this->session->set_flashdata('error_msg', 'please log out to access this page ');
echo 'Please log out to access this page!...';
sleep(2);
redirect('index.php/user/dashboard');
}
$data['session_data'] = array(
'userID' => $this->session->userdata('userID'),
'loggedIn' => $this->session->userdata('loggedID')
);
$this->load->view('navigation');
$this->load->view('register', $data);
echo 'registration page - ';
if($this->input->post('register')){
$this->form_validation->set_rules('username', 'username', 'required');
$this->form_validation->set_rules('email', 'email', 'required|valid_email');
$this->form_validation->set_rules('password', 'password', 'required');
$user_details = array(
'username' => strip_tags($this->input->post('username')),
'email' => strip_tags($this->input->post('email')),
'password' => strip_tags($this->input->post('password'))
);
if($this->form_validation->run() == true){
$username_exists = $this->user_model->username_exists($user_details[0]);
$email_exists = $this->user_model->email_exists($user_details[1]);
if($username_exists == false && $email_exists == false) {
$this->user_model->add_user_account($user_details);
echo 'user added successfully: '. $user_details[0];
$this->session->set_flashdata('success_msg', 'SUCCESSFULLY ADDED USER, username and email do not already exist!... ');
sleep(2);
redirect('index.php/user/login');
} else {
echo 'username or email already exists! try again!...';
$this->session->set_flashdata('error_msg', 'ERROR OCCURRED - username or email exists!...');
sleep(2);
redirect('index.php/user/register');
}
} else {
echo 'error occured, try again!...';
$this->session->set_flashdata('error_msg', 'ERROR OCCURRED- something didn\'t work');
sleep(2);
redirect('index.php/user/register');
}
}
}
Model Functions
public function add_user_account($user_details){
$this->db->insert('user_account', $user_details);
}
public function username_exists($username){
$this->db->select('username');
$this->db->from('user_account');
$this->db->where('username', $username);
$query = $this->db->get();
if($query->num_rows() > 0){
return true;
} else {
return false;
}
}
public function email_exists($email){
$this->db->select('email');
$this->db->from('user_account');
$this->db->where('email', $email);
$query = $this->db->get();
if($query->num_rows() > 0){
return true;
} else {
return false;
}
}
$user_details[0] doesn't reference anything as you have non-numerical keys for the user_details array. I assume you mean to access the key username thus you should do $user_details['username'].
Like so:
$username_exists = $this->user_model->username_exists($user_details['username']);
$email_exists = $this->user_model->email_exists($user_details['email']);
To be honest I'm surprised this isn't giving you notice errors.
Further, you could easily make your username/email exists functions into a callback or simply use the is_unique feature of the form_validation library.
Also I'm pretty sure that you can apply strip_tags as a form_validation rule and it will remove the tags in the post variables.
Well to address your question via a means of simplification, you can use is_unique[table.field] as a validation rule.
That way you do not need to write any model methods for checking that your username or email is unique.
So in your form validation rules you can alter your username and email rules to include the is_unique rule.
$this->form_validation->set_rules('username', 'Username', 'required|is_unique[user_account.username]');
$this->form_validation->set_rules('email', 'Email', 'required|valid_email|is_unique[user_account.email]');
Note: The 2nd Field is the Form Label and can be anything. In this case I uppercased it. The 1st field IS case sensitive.
As to why your existing code isn't working...
Try getting friendly using var_dump(); or print_r();
i.e.
$username_exists = $this->user_model->username_exists($user_details[0]);
$email_exists = $this->user_model->email_exists($user_details[1]);
// Debug these two and see what they are...
var_dump($username_exists);
var_dump($email_exists);
Now seeing you are using an associative array in setting up
$user_details = array(
'username' => strip_tags($this->input->post('username')),
'email' => strip_tags($this->input->post('email')),
'password' => strip_tags($this->input->post('password'))
);
And then referencing them like
$username_exists = $this->user_model->username_exists($user_details[0]);
Using the above var_dump's should give you an "Aha!!!" moment.
When in doubt var_dump();

Codeigniter Form Validation in Model

Hello all, this is my first CI project.
I have a simple form validation function in my model.
function verify_login()
{
//This method will have the credentials validation
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'trim|required|xss_clean');
$this->form_validation->set_rules('password', 'Password', 'trim|required|xss_clean|callback_check_database');
var_dump($this->form_validation->run());
die;
if ($this->form_validation->run() == FALSE) {
//Field validation failed. User redirected to login page
$this->load->view('login_view');
} else {
//Go to private area
redirect('home', 'refresh');
}
}
This only works when it's in a controller but not in a model. When I try passing the variables from the controller to the function in the model, the variables get received but won't process.
Can someone enlighten me? Thank you.
its fine to do your form validation in a model. But you want to have the validation return True or False to your controller. Not call a view. So like
// in your Model lets call it Users
function verify_login()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'trim|required|xss_clean');
$this->form_validation->set_rules('password', 'Password', 'trim|required|xss_clean|callback_check_database');
if ($this->form_validation->run() == FALSE) {
return FALSE ;
} else {
return TRUE;
}
}
// Your callback function
// in Controller
function verify(){
if( $this->users->verify_login() == FALSE ){
// $this->errormessage will be available in any view that is called from this controller
$this-errormessage = "There was an error with your Log In. Please try again." ;
$this->showLogin() ; }
else {
// set a session so you can confirm they are logged in on other pages
$this->setLoginSession($this->input->post('username', TRUE)) ;
$this->showUserHome(); }
}
Another thing to think about -- often people know their user name but mess up their password. So if you check for them separately you can adjust the error message accordingly. And if you check for user name and there are no results -- you don't need to check for password and in the error message you can tell them there is no user by that name.
My biggest recommendation to you is to not do validations like this in your model. If you're validating in your model it needs to be against a database value directly and not a form.
Please let me know if that solves your problem, if not please comment and I'll edit my answer.
UPDATE: Please ignore some of the above, as I was going off theory and not fact :)
I'll have to dig deeper into the CI core to get a good idea of what's wrong with this. Your code itself looks ok. Only thing I can see is that your callback may not exist in your model and only in your controller. Echoing the below I do not consider this a good use of the model.
The docs on validations
class Data_model extends CI_Model
{
public function rules()
{
return [
['field' => 'pertanyaan',
'label' => 'pertanyaan',
'rules' => 'required|is_unique[data.pertanyaan]'],
['field' => 'jawaban',
'label' => 'jawaban',
'rules' => 'required']
];
}
}
class Datas extends CI_Controller
{
public function add()
{
$data = $this->data_model;
$validation = $this->form_validation;
$validation->set_rules($data->rules());
if ($validation->run()) {
$data->save();
$this->session->set_flashdata('success', 'Berhasil disimpan');
}
$this->load->view("admin/data/new_form");
}
}

CI - show database error or fail

I've developed a simple login system which works ok but fails, and I need to know why
QUESTION: How to show what is causing the fail. This is not a validation error but an error either with the data being passed to MySQL or the query somehow failing
here's the db function:
function login($email,$password)
{
$this->db->where("email",$email);
$this->db->where("password",$password);
$query=$this->db->get("users");
if($query->num_rows()>0)
{
foreach($query->result() as $rows)
{
//add all data to session
$newdata = array(
'user_id' => $rows->id,
'user_name' => $rows->username,
'user_email' => $rows->email,
'logged_in' => TRUE,
);
}
$this->session->set_userdata($newdata);
return true;
}
return false;
}
And here's the logic:
public function login()
{
$this->load->library('form_validation');
// field name, error message, validation rules
$this->form_validation->set_rules('email', 'Your Email', 'trim|required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'trim|required|min_length[4]|max_length[32]');
if($this->form_validation->run() == FALSE)
{
$this->signin();
}
else
{
$email=$this->input->post('email');
$password=md5($this->input->post('pass'));
$result=$this->user_model->login($email,$password);
if($result)
{
$this->dash();
}
else
{
$data['title']= 'Login Error';
$this->load->view('nav/header', $data);
$this->load->view('login', $data);
$this->load->view('nav/footer', $data);
}
}
}
I know the error is happening as I redirect back to login page if fail and change title text to show me (only in testing mode for right now) - but how can I find out what is going wrong with the query?
You can use log_message and check the logs if the y behave as expected:
http://ellislab.com/codeigniter/user-guide/general/errors.html
I usually just use echo '<pre>'; print_r($query->result());die; just after the $query is formed.
It's faster.
$this->db->where("email",$email);
$this->db->where("password",$password);
$query=$this->db->get("users");
echo $this->db->last_query();
die();
you can echo the query you just did by using $this->db->last_query() this will show the query that your made with the values, and check if the query is valid.
read more at http://ellislab.com/codeigniter/user-guide/database/helpers.html

How do I echo a form error in a else statement in my controller in code-igniter?

I have all of the different combinations of submitting a incorrect form for my login form in code-igniter working as they should.
**EDIT - This seems like the most logical formation as the other suggestions were loading double views and or not cohesive with my structure. All of the errors work properly except one.
When you hit submit with CORRECT email and gibberish password, no error appears and the page reloads with the entered email auto filled and the password field set back to the defaulted "PASSWORD" text.
I have been stuck on this far too and long and any help would be greatly appreciated.
function validate_credentials_login()
{
$this->load->library('session');
$this->load->helper(array('form','url'));
$this->load->model('user_model', 'um');
$this->load->library('encrypt');
$this->load->library('form_validation');
$this->form_validation->set_rules('email_login', 'Email', 'trim|required|valid_email');
$this->form_validation->set_rules('password_login', 'Password', 'trim|required');
if ( $this->form_validation->run() === TRUE )
{
$user = $this->um->validate_home_login(array('email' => $this->input->post('email_login')));
if ( $user )
{
if ( $user->password == $this->encrypt->sha1( $user->salt . $this->encrypt->sha1($this->input->post('password_login'))) && $user->email == $this->input->post('email_login') )
{
$this->session->set_userdata(array('email' => $this->input->post('email_login')));
redirect('account/edit');
}
else
{
$this->form_validation->run() == FALSE;
}
}
else
{
$this->form_validation->run() == FALSE;
}
}
$data['main_content'] = 'home/home_page';
$this->load->view('includes/templates/home_page_template', $data);
}
As #Brendan says, you don't need the last 2 else statement, but you even not need to pass the errors to the view! you can put this code:
In the controller:
$this->form_validation->set_rules('email_login', 'Email', 'trim|required|valid_email');
$this->form_validation->set_rules('password_login', 'Password', 'trim|required');
if ( $this->form_validation->run() === TRUE )
{
$user = $this->um->validate_home_login(array('email' => $this->input->post('email_login')));
if ( $user )
{
if ( $user->password == $this->encrypt->sha1( $user->salt . $this->encrypt->sha1($this->input->post('password_login'))) && $user->email == $this->input->post('email_login') )
{
$this->session->set_userdata(array('email' => $this->input->post('email_login')));
redirect('account/edit');
}
$data['main_content'] = 'home/home_page';
$this->load->view('includes/templates/home_page_template', $data);
}
And in the view:
<?php echo validation_errors('<div class="error">', '</div>'); ?>
The <div class="error" only is showed if there are errors validating the form, in other case nothing is showed.
What I would do (and have done) is just use validation_errors() on the login view page. You can do that by doing this:
if ($user)
if ($success)
{
redirect(...);
}
}
$this->load->view('login_page_template', $data); // Not sure what your login view is named
and in the login view:
...
<?php echo validation_errors('<div class="errors_login">', '</div>'); ?>
...
If you change your logic slightly, you could get rid of the else's and just load the login view after the if statements run. If the user successfully logs in, they will be redirected before the login view gets loaded anyway. This way, you don't have to else every if statement and duplicate the same code over and over. Let me know if that doesn't make sense.
Edit: like #m4t1t0 said, you don't have to pass the errors to the view, you can just echo validation_errors('<div class="errors_login">', '</div>'); wherever you want the errors to show up. I've updated my example to reflect this.
If you want to show errors individually, above each form item (i.e. email does not exist, password incorrect, etc) then you can use echo form_error('field_name'); in each respective location.
Edit 2: I also just noticed you're using sha1 encryption for your passwords. This is fine for a low-security setup, but I would recommend using PHP's crypt() function, which by default uses the Blowfish algorithm (if available). Here's a basic implementation:
// to make password hash
$password = crypt($this->input->post('password'));
// to check password hash
if (crypt($this->input->post('password'), $password_from_db) == $password_from_db)
{
// success
}

Categories