Welcome Guest, Not a member yet? Register   Sign In
Updating a unique field in database (example: account username or email)
#1

[eluser]Salvatore Formisano[/eluser]
Hi everyone,

I'll try to be short and straight to the point:

I am working on a codeigniter based website, and its users will have the possibility to edit their account (their name, username, email, password etc.)

When signing up, I used the following function to make sure that the username and the email were not already used for another account:

Code:
function unique($str, $field)
    {
        $CI =& get_instance();
        list($table, $column) = split("\.", $field, 2);
        $CI->form_validation->set_message('unique', 'The %s that you requested is unavailable.');
        $query = $CI->db->query("SELECT COUNT(*) dupe FROM $table WHERE $column = '$str'");
        $row = $query->row();
        return ($row->dupe > 0) ? FALSE : TRUE;
    }


now... my point is:

When a user wants to change his account's info, what kind of function could I use to make sure that unique fields (email,username) are not used by someone else already?


The "unique" function cannot be used for obvious reasons (if the user submits his "edit account" form with unique data unaltered, the function will return false because his data is already in the database)




I hope the question was clear enough, and that the solution can't be found in the user guide... because I really went through all of it (... well, almost!)



Thanks everyone,
Salvatore
#2

[eluser]aidehua[/eluser]
Assuming you have an ID column in your table, and you know your user's ID, maybe you could do something like this:

SELECT COUNT(*) dupe FROM $table WHERE $column = '$str' AND id != $id;
#3

[eluser]Salvatore Formisano[/eluser]
Thanks for the reply mate.

I don't know if my setup might work out with this solution, I currently have:

a config array here:

Code:
/application/config/form_validation.php

the array for the specific case I described is:

Code:
$config = array(
    'user_update_account_parser' => array(
        array(
            'field' => 'id',
            'label' => 'id',
            'rules' => 'required|integer'
            ),
        array(
            'field' => 'first_name',
            'label' => 'Nome',
            'rules' => 'required|min_length[4]|max_length[32]|alpha_dash'
            ),
        array(
            'field' => 'last_name',
            'label' => 'Cognome',
            'rules' => 'required|min_length[4]|max_length[32]|alpha_dash'
        ),
        array(
            'field' => 'username',
            'label' => 'Username',
            'rules' => 'required|min_length[6]|max_length[32]|alpha_dash|unique[accounts.username]'
        ),
        array(
            'field' => 'email',
            'label' => 'Email',
            'rules' => 'required|valid_email|unique[accounts.email]'
        ),
        array(
            'field' => 'new_password',
            'label' => 'Nuova Password',
            'rules' => 'matches[new_password_confirm]|min_length[6]|max_length[32]'
        ),
        array(
            'field' => 'new_password_confirm',
            'label' => 'Conferma Nuova Password',
            'rules' => 'matches[new_password]|min_length[6]|max_length[32]'
        )
    )
);

the unique rule (unique[table.column) uses an extension of the CI_Form_validation class. Here's the code

Code:
class MY_Form_validation extends CI_Form_validation {

    function My_Form_validation($rules = array())
    {
        parent::CI_Form_validation($rules);
    }
    
    // --------------------------------------------------------------------
    
    /**
     * Unique
     *
     * @access    public
     * @param    string
     * @param    field
     * @return    bool
     */
    
    // this function will make sure the value is not already in the database (you can specify table and column)
    function unique($str, $field)
    {
        $CI =& get_instance();
        list($table, $column) = split("\.", $field, 2);
        $CI->form_validation->set_message('unique', 'The %s that you requested is unavailable.');
        $query = $CI->db->query("SELECT COUNT(*) dupe FROM $table WHERE $column = '$str'");
        $row = $query->row();
        return ($row->dupe > 0) ? FALSE : TRUE;
    }
}


so basically... if I want to duplicate the same unique function calling it, let's say, unique_update... how would I manage to bring the id of the record to be excluded here safely?


I am not an expert in back-end, and I want to make sure what I do is not risky.

Thanks again,
Salvatore
#4

[eluser]Salvatore Formisano[/eluser]
bump....


am I using the wrong approach to the problem? :|
#5

[eluser]sophistry[/eluser]
why not just make an extra database update to wipe out the current user's data just before you run the ruleset validation?

so, let's say an existing, logged-in user modifies his username. just before submitting the data to validation, just do a db update with blank values (except for id).
#6

[eluser]Salvatore Formisano[/eluser]
Interesting approach indeed!

I will try this out and see how it goes
#7

[eluser]sophistry[/eluser]
oh, i just re-read the @aidehua reply. i wasn't really paying full attention.

that is a better approach.

to get the id from your form you need:
Code:
$this->input->post('fieldname_which_is_probably_id');
#8

[eluser]Salvatore Formisano[/eluser]
Ah,


well, I was aware of the syntax to get the input's value... but my issue is another

as you can read from my post above, the unique rule (unique[table.column]) uses an extension of the CI_Form_validation class. Here’s the code

the code is :

Code:
function unique($str, $field)
    {
        $CI =& get_instance();
        list($table, $column) = split("\.", $field, 2);
        $CI->form_validation->set_message('unique', 'The %s that you requested is unavailable.');
        $query = $CI->db->query("SELECT COUNT(*) dupe FROM $table WHERE $column = '$str'");
        $row = $query->row();
        return ($row->dupe > 0) ? FALSE : TRUE;
    }


so...assuming I want to use a similar rule as follows:

Code:
function unique_update($str,$field)
    {
        $CI =& get_instance();
        list($table, $column) = split("\.", $field, 2);
        $CI->form_validation->set_message('unique', 'The %s that you requested is unavailable.');
        $query = $CI->db->query("SELECT COUNT(*) dupe FROM $table WHERE $column = ‘$str’ AND id != $id;");
        $row = $query->row();
        return ($row->dupe > 0) ? FALSE : TRUE;
    }

this file extending the CI_Form_validation is NOT in my controller.

It's actually located under

Code:
/application/config/form_validation.php


Am I still able to refer to a value sitting in my controller (the posted id) while using a rule specified somewhere else?
#9

[eluser]sophistry[/eluser]
yes, sorry i didn't post the correct syntax. you have the CI superobject.

Code:
$CI->input->post('fieldname');
#10

[eluser]Salvatore Formisano[/eluser]
wow, so basically this would be the final result?

Code:
function unique_update($str,$field)
    {
        $CI =& get_instance();
        list($table, $column) = split("\.", $field, 2);
        $CI->form_validation->set_message('unique', 'The %s that you requested is unavailable.');
        $query = $CI->db->query("SELECT COUNT(*) dupe FROM $table WHERE $column = ‘$str’ AND id != $CI->input->post('fieldname');;");
        $row = $query->row();
        return ($row->dupe > 0) ? FALSE : TRUE;
    }




Theme © iAndrew 2016 - Forum software by © MyBB