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.
Related
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();
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.
I am trying to validate 2 fields here, the "title" and the "HTML" field.
I have this code:
$this->form_validation->set_rules('title', $this->input->post('title'), 'required|min_length[5]|max_length[255]');
$this->form_validation->set_rules('html', $data['html'], 'required');
if ($this->form_validation->run() == FALSE){
echo 'Fail';
}else{
echo 'Success';
}
die();
I can confirm that both variables are valid strings.
The function always returns false, even if both fields are valid. If I only set one rule for one field, then the function will return true if it is a success.
Could somebody please advise?
Many thanks indeed,
Peter
The second parameter of your validation rules should be the human readable name of the field, not the actual data. Consider the following code.
$this->form_validation->set_rules('title', 'Title', 'required|min_length[5]|max_length[255]');
$this->form_validation->set_rules('html', 'HTML', 'required');
The first rule will check the POST variable $_POST['title'] to ensure that it is set and is between 5 and 255 characters. If it fails these rules the name Title is used in the error message. The second rule will check the variable $_POST['html'] to ensure that it is set and if it is not set will use the name HTML in the error message.
Take a look at the CodeIgniter Documentation for more specific implementation details.
Based on your code, it looks like you want to run some variables that are not part of the $_POST array through form validation. To do this you have two choices. First you can put all of the data you want to validate into an array and use $this->form_validation->set_data($array) to use that array instead of $_POST. Alternatively you can just add the fields you want to validate to $_POST.
set_data() example:
$formData = array('title' => $this->input->post('title'), 'html' => $data['html']);
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('title', 'Title', 'required|min_length[5]|max_length[255]');
$this->form_validation->set_rules('html', 'HTML', 'required');
if ($this->form_validation->run() == FALSE){
echo 'Fail';
}else{
echo 'Success';
}
$_POST example:
$_POST['html'] = $data['html'];
$this->form_validation->set_rules('title', 'Title', 'required|min_length[5]|max_length[255]');
$this->form_validation->set_rules('html', 'HTML', 'required');
if ($this->form_validation->run() == FALSE){
echo 'Fail';
}else{
echo 'Success';
}
Personally I recommend the $_POST method.
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
}
I am pretty sure that I have just missed something very obvious but to my eyes I cannot work out what. The empty form validation is working correctly but its when I enter any random values into the input boxes and click login it shows 'This is working fine'; so I have a feeling that it is something to do with my callback function.
I am trying to make is so the person can login with their username or password
Validation:
'loginUser' => array(
array(
'field' => 'userLoginUsername',
'label' => 'Username',
'rules' => 'trim|required|xss_clean'
),
array(
'field' => 'userLoginPassword',
'label' => 'Password',
'rules' => 'trim|required|callback__check_login|xss_clean|sha1'
)
)// End of login user array
Callback:
function _check_login($username, $password)
{
if($this->users_model->login_check($username,$password))
{
$this->form_validation->set_message('_check_login', 'Sorry you have entered an incorrect %s ');
return FALSE;
}else{
return TRUE;
}
}
Controller:
function login()
{
if($this->form_validation->run('loginUser') == FALSE)
{
$data['success'] = '';
}else{
echo 'This is working fine';
}
$data['companyName'] = $this->core_model->companyDetails()->coreCompanyName;
$data['pageTitle'] = "User Login";
$this->load->view('frontend/assets/header', $data);
$this->load->view('frontend/user_login', $data);
$this->load->view('frontend/assets/footer');
}
}
Model:
function login_check($username, $password)
{
$this->db->select('userName,userEmail,userPassword');
$this->db->from('users');
$this->db->where('userName', $username, 'userEmail', $username, 'userPassword' , $password, 'userActive', 1);
$query = $this->db->get();
if($query->num_rows() == 1)
{
return TRUE;
}else{
return FALSE;
}
}
View:
<h1><?php echo $companyName; echo nbs(1);?> - <?php echo $pageTitle; ?></h1>
<div class="formComments">
<p class="error"><?php echo validation_errors();?></p>
<p class="success"><?php echo $this->session->flashdata('success'); ?></p>
</div>
<div class="user_login">
<form class="form-inline" method="POST" action="login" >
<input type="text" name="userLoginUsername" id="userLoginUsername" class="input-small" placeholder="Username">
<input type="password" name="userLoginPassword" id="userLoginPassword" class="input-small" placeholder="Password">
<button type="submit" class"btn">Login</button>
</form>
</div>
in your code
if data is verified by model ie TRUE returned callback _check_login will return FALSE to login() because of
if($this->users_model->login_check($username,$password))
{
$this->form_validation->set_message('_check_login', 'Sorry you have entered an incorrect %s ');
return FALSE;
}
hence condition
if($this->form_validation->run('loginUser') == FALSE)
will be succeeded and it will set $data['success'] = '';
for wrong input or empty validation model returns FALSE so
if($this->users_model->login_check($username,$password))
{
$this->form_validation->set_message('_check_login', 'Sorry you have entered an incorrect %s ');
return FALSE;
}else{
return TRUE; /* login check failed control comes here*/
}
hence
if($this->form_validation->run('loginUser') == FALSE)
{
$data['success'] = '';
}else{
echo 'This is working fine'; /*control comes here now*/
}
change
if($this->users_model->login_check($username,$password))
to
if(!$this->users_model->login_check($username,$password))
and it should work
hope this helps
EDIT__
well, just figured out something you are missing might be creating the issue. the callback you are setting in the rule array
array(
'field' => 'userLoginPassword',
'label' => 'Password',
'rules' => 'trim|required|callback__check_login['.$_POST['userLoginUsername'].']|xss_clean|sha1'
)
must be
array(
'field' => 'userLoginPassword',
'label' => 'Password',
'rules' => 'trim|callback__check_login['.$_POST['userLoginUsername'].']|xss_clean|sha1'
)
because the callback function is expecting 2 values and the way you are using it only send password field to it. also with this rearrange the callback argument to
function _check_login($password, $username)
so the first value be password and second be username. for checking 'userActive' remove it from the where clause and check its value if query returned some record
if($query->num_rows() == 1){
/* check its value if 1 do something as you asked in comment*/
Ok, that's a lot of code but I spotted this:
In your controller you use a validation rule to check for the right user data; besides that I wouldn't do like that, since properly speaking it isn't a "form validation" rule, what I see is that if your user exists and his credentials are correct you return TRUE.
That's fine, but in your validation rule you have:
if($this->users_model->login_check($username,$password))
{
$this->form_validation->set_message('_check_login', 'Sorry you have entered an incorrect %s ');
return FALSE;
which measn that when the model returns TRUE (user is ok), your validation returns FALSE! and that means when the user is right your validation doesn't succeed, and when your user is "wrong" (see your "random input") the rule returns TRUE, making it a success.
I don't have time to look further now, but skimming the code everything looks ok apart from this. SO, just change that line to
if(!$this->users_model->login_check($username,$password))
{
i.e. "if the model returns FALSE, make the rule return FALSE too". Hope it is clear.
It looks like this line here:
if($this->form_validation->run('loginUser') == FALSE)
You should either remove 'loginUser' or pop in a variable, like $loginUser, something feels funny about your array.