Question

I have the following code shown below to allow the admin to add a particular user to multiple roles by selecting from the available roles (check-boxes). The code works fine to accomplish this but it also needs to remove the user from which ever role (check-box) was unselected. The checkboxes allow the admin to both add and remove the user from the selected roles. This is the part I cannot figure out.

If some one could walk me through this that would be really awesome. Thank you!

<?php
// declare variables
$msg = '';

// ------------------------------------------------------------------
// UPDATE USER INFO
// ------------------------------------------------------------------
if(isset($_POST['UpdateUser']))
{
    // get user id from query string sent
    $sent_id = mysqli_real_escape_string($conn, $_GET['uid']);
    if(isset($sent_id) && !empty($sent_id) && is_numeric($sent_id) && $sent_id > 0)
    {
        $user_id = $sent_id;

        // ------------------------------------------------------------------
        // ADD CURRENT USER TO SELECTED ROLES
        // ------------------------------------------------------------------
        if(isset($_POST['checked']))
        {
            // get selected role names
            $checked = $_POST['checked'];

            $i1=0;
            $i2=0;
            foreach($checked as $role_name)
            {
                // get role id
                $get_role_id = mysqli_query($conn, "SELECT RoleId FROM roles WHERE RoleName = '$role_name'")
                or die($dataaccess_error.mysqli_error($conn));

                $row = mysqli_fetch_array($get_role_id);
                $role_id = $row['RoleId'];

                // check if user already exist in role
                $check_if_exist = mysqli_query($conn, "SELECT UserId, RoleId, RoleName FROM users_in_roles WHERE UserId = $user_id AND RoleId = $role_id AND RoleName = '$role_name' LIMIT 1")
                or die($dataaccess_error);

                if(mysqli_num_rows($check_if_exist) == 0)
                {
                    // add user to roles
                    $add_user_to_roles = mysqli_query($conn, "INSERT INTO users_in_roles(UserId, RoleId, RoleName) VALUES($user_id, $role_id, '$role_name')")
                    or die($dataaccess_error.mysqli_error($conn));

                    $count1 = $i1++ + 1;
                    $count2 = $i2;
                    $msg = "<div class='msgBox3'>SUCCESS: USER have been ADDED to ($count1) ROLES - AND ALREADY EXISTS in ($count2).</div>";
                }
                elseif(mysqli_num_rows($check_if_exist) == 1)
                {
                    $count1 = $i1;
                    $count2 = $i2++ +1;
                    $msg = "<div class='msgBox4'>NOTE: USER have been ADDED to ($count1) ROLES - AND ALREADY EXISTS in ($count2).</div>";
                }
            }
        }
        else
        {
            $msg = $msg_error2;
        }
    }
}
?>
Was it helpful?

Solution

Delete any existing user/role relationships before creating new ones from the submitted checkboxes. You can also insert all the roles in a single MySQL statement if you set the checkbox values to the role_id's instead of the role_name's. Also, there's no reason for the users_in_roles table to duplicate the role_name column. Here's what I'd use (simplified pseudo-statements of course):

// New data structure
mysqli_query("DROP TABLE users_in_roles");
mysqli_query("CREATE TABLE users_in_roles ( user_id ..., role_id ....)");

....

// Build SQL fragments for multi-row INSERT.
$a = array();
foreach($checked as $role_id) {
 $a[]= sprintf('(%d, %d)', $user_id, $role_id);
}
// Delete existing user/role relationships for the user.
mysqli_query("DELETE FROM users_in_roles WHERE user_id = $user_id");
// Insert multiple rows in a single statement.
mysqli_query(
 sprintf('INSERT INTO users_in_roles (user_id, role_id) VALUES %s', 
   implode(', ', $a)));

This method accomplishes the same thing - using only two sql statements. One downside: in the unlikely event that there's an error before/during the INSERT statement no roles will be assigned. You can executing DELETE and INSERT in a transaction.

OTHER TIPS

Simple solution is to use something other than checkboxes, as they don't submit values when unchecked.

Alternatively, you could keep the checkboxes and build a PHP array of possible role values. In your current loop, you could remove those values when checked. After the loop, the array would be left with only the unchecked roles and you could then remove them accordingly.

$roles = array('key' => 'Nice Name', 'admin' => 'Administrator');

This could be used not only to output the checkboxes, but also manage roles. Ideally this would be in a database table.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top