This is my validation for updating the email..
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email|callback__unique_email[email]');
The call back function is
public function _unique_email($email) {
if ($this->crud_model->fetch_user_by_email_user_id($email,$this->session->userdata('user_id'))) {
return true;
} else {
$this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email|is_unique[users.email]');
return true;
return false;
}
}
the email should be updated if the user changes the email in profile settings but if the user not makes any changes the email should be the old one and if he changes the email then it should be update by checking weather the email is unique in the database or not??
function index()
{
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('email', 'Email', 'required|callback_email_check');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('form');
}
else
{
if($this->update($email)){
$this->load->view('formsuccess');
}
}
}
I haven't used codeIgniter for years, So I don't exactly know how things are there. But I'll try to answer your question on a general context and try to express that using the same code in your question with minor changes.
When You want to check if the user changed his email or not you need to have his old email from database first or in a hidden field of the form, then compare the email field value with the old one will make you know if he changed it.
Second you need to check if the email have duplicates on the database, remember you need to do this only if the user changed his email address, so just run a query with the database. if there are no existing email update the user email in database else display an error and quit.
public function is_unique_email($email) {
$old_email = $this->crud_model->fetch_user_email($this->session->userdata('user_id'));
if ($old_email == $email) {
return true;
} else {
$duplicates = $this->crud_model->fetch_user_by_email($email);
if(count($duplicates) > 0)
{
return false;
}
else
{
return true;
}
}
}
The end code should something similar to this, I'm sorry I can't give you the exact code, But I think you can run with this approach.
I suggest you to move to some good frameworks like symfony, laravel or
zend. Codeigniter is not improved much from those early days where PHP
did a lot.
Related
I have a Yii form accept first name, last name and email from user. Using an add more link, users can add multiple rows of those three elements.
For email validation, unique and required are set in model rules and everything works fine. I am using JavaScript to create addition row on clicking add more link.
Problem
On the first row my values are John, Newman, johnnewman#gmail.com and the second row, i'm entering Mathew, Heyden, johnnewman#gmail.com. In this case email address is duplicated. None of the validation rules (require and unique) is capable of validating this. Can some one suggest a better method to validate this ?
Update:
I created a custom validation function and i guess this is enough to solve my problem. Can someone tell me how to access the whole form data / post data in a custom validation function ?
public function uniqueOnForm($attribute){
// This post data is not working
error_log($_REQUEST, true);
$this->addError($attribute, 'Sorry, email address shouldn\'t be repeated');
}
You can try this:
<?php
public function rules()
{
return array(
array('first_name', 'checkUser')
);
}
public function checkUser($attribute)
{
if($this->first_name == $this->other_first_name){
$this->addError($attribute, 'Please select another first name');
}
}
?>
You can also look into this extension
You can write custom validator:
//protected/extensions/validators
class UniqueMailValidator extends CValidator
{
/**
* #inheritdoc
*/
protected function validateAttribute($object, $attribute)
{
$record = YourModel::model()->findAllByAttributes(array('email' => $object->$attribute));
if ($record) {
$object->addError($attribute, 'Email are exists in db.');
}
}
}
// in your model
public function rules()
{
return array(
array('email', 'ext.validators.UniqueMailValidator'),
...
Or better try to use THIS
public function rules(){
return array(
//other rules
array('email', 'validEmail'),
)
}
public function validEmail($attribute, $params){
if(!empty($this->email) && is_array($this->email)){
$isduplicate = $this->isDuplicate($this->email);
if($isduplicate){
$this->addError('email', 'Email address must be unique!');
}
}
}
private function isDuplicate($arr){
if(count(array_unique($arr)) < count($arr)){
return true;
}
else {
return false;
}
}
because you are using tabular input (multiple row) , so make sure input field as an array. might be like this :
<?php echo $form->textField($model, 'email[]'); ?>
how to validation email only use domain #gm.ac.id. i try but validation its not working.
this is code
public function email_check($email)
{
if (valid_email('email#mail.ugm.ac.id'))
{
return TRUE;
}
else
{
$this->form_validation->set_message('email_check', '%s gunakan email ugm');
return FALSE;
}
}
$this->form_validation->set_rules('email', 'email', 'required|callback_email_check');
please help me what to do.
thank you.
Valid_email has no way of knowing what domains it should allow or not.
An easier way would be:
$this->form_validation->set_rules('email', 'email', 'required|valid_email|callback_email_check');
This way you pass to email_check() only those emails which are validly constructed. Now you are just left to check the domain. Something like:
public function email_check($email)
{
return strpos($email, '#gm.ac.id') !== false;
}
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");
}
}
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 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
}