dre1080 / warden

More than just a user database auth package for FuelPHP
http://dre1080.github.com/warden
MIT License
46 stars 11 forks source link

Setting roles for user with id=0 #37

Closed kolipka closed 11 years ago

kolipka commented 11 years ago

Hi, I'm new to this library and quite newbie in PHP. I have a strange problem: roles assigning works for every user, except with ID 1. Here is the code:

            $user = Model_User::find($id);
            $roles = array();
            if (Input::post('role')){
                foreach (Input::post('role') as $selected_role) {
                    $roles[$selected_role] = Model_Role::find((int)$selected_role); 
                }
            }
            $user->roles=$roles;

I did some debugging and found out that in Model_User _event_before_save() calls _add_default_role() and finally in there I've found line:

if (empty($this->roles) || !static::query()->related('roles')->get_one()

seems that this static::query do some magic and as a (possibly unwanted) result in my $user object in _original_relations property gets roles inserted with values i want to add. In this case when I finally got to orm\classes\model.php:save() and call manytomany.php:save() with $_original_relations passed as $original_model_ids parameter and perform:

        // Check if the model was already assigned, if not INSERT relationships:
        if ( ! in_array($current_model_id, $original_model_ids))

condition detects that change in DB is already done, and does not perform insert! I don't get the big picture of FuelPHP and Warden so please make it work. I made workaround that check default role setting first and quit without checking other stuff.

BR

andreoav commented 11 years ago

Hi @kolipka . I have a similiar code to add roles to my user and it works without problems. This code you posted adds all user roles, or adds roles that the user does not have yet?

noxify commented 11 years ago

Hi @kolipka,

maybe this will fix your problem: https://github.com/webstone/fuel-administrator/blob/master/fuel/app/modules/users/classes/controller/admin/users.php#L165

I had the same problems, but with this code it works fine :)

Hope this helps.

Greets, marcus

kolipka commented 11 years ago

Thank for answers :) @andreoav - this is for all roles and works for all users except with ID 1. @webstone - what happens when you have some roles selected for a user, and you remove all of them? foreach will throw an exception ? Anyway I'll try this, but still there is a bug out there (or extremely hidden feature ;) )

noxify commented 11 years ago

Hi @kolipka,

i tested it in my local environment.

currently i got an error message "ErrorException [ Warning ]: Invalid argument supplied for foreach()", because i have no check - but normally it should set the default role, which is defined in the warden config.

Hope this helps :)

Greets, Marcus

dre1080 commented 11 years ago

@kolipka, Has this been resolved?

kolipka commented 11 years ago

No it is not. I have work around like solution._event_before_save() still does something that force one and only way of assigning roles. This should be investigated and solved or should be documented an known issue.

kolipka commented 11 years ago

Sorry for mess with close... I try to familiarize wth tablet and it sometimes does not goes easy. Wrong button...

andreoav commented 11 years ago

@kolipka, I use this code:

$user->roles = array();
foreach (\Input::put('user_roles') as $role)
{
    $role = \Warden\Model_Role::find((int) $role);
    $atleta->roles[] = $role;
}
.
.
.
$user->save();

This code works very well for me..

kolipka commented 11 years ago

@andreoav, I do have working solution. But !static::query()->related('roles')->get_one() causes some hidden magic that causes the one and only solution that works. Workaround is simple, but problem exists.

dre1080 commented 11 years ago

Hi, @kolipka. A role with ID=1 is or whatever int your autoincrement starts from is reserved for your default_role if set in warden/config.php. Also, you shouldn't add roles dynamically by passing in an ID, as you do not yet know how many roles a certain user has. So this line in your code:

$roles[$selected_role] = Model_Role::find((int)$selected_role); 

is actually saying that the variable $selected_role is an ID. It should be replaced with the code above by @andreoav:

$role = \Warden\Model_Role::find((int) $role);
$atleta->roles[] = $role;

this might actually be an issue with ORM if static::query()->related('roles')->get_one() is causing some hidden magic.

kolipka commented 11 years ago

Hi @dre1080, I have default role turned off. This code I took from Fuel Administrator project. Thanks for your answer. You're right. This can be ORM problem. I will close this ticket.

BTW: It is very nice lib!