2011-12-26 5 views
0

Я пытаюсь написать свой собственный модуль RBAC в Кохане. Я не хочу использовать существующий модуль, я просто хочу это сделать, чтобы узнать.Объединение таблиц в ORM

Мои таблицы: пользователи, роли, разрешения и users_roles, role_permissions (из-за многих-многих отношений между пользователями < -> роли и роли < -> разрешения);

Моя модель Пользователь:

class Model_User extends ORM { 

    protected $_primary_key = 'user_id'; 

    protected $_has_many = array(
     'roles' => array(
      'model' => 'role', 
      'through' => 'users_roles', 
     ), 
    ); 
} 

Моя Role Model:

class Model_Role extends ORM { 

    protected $_primary_key = 'role_id'; 

    protected $_has_many = array(
     'users' => array(
      'model' => 'user', 
      'through' => 'users_roles', 
     ), 

     'permissions' => array(
      'model' => 'permission', 
      'through' => 'roles_permissions', 
     ), 
    ); 
} 

и моя модель Разрешение:

class Model_Permission extends ORM { 

    protected $_primary_key = 'permission_id'; 

    protected $_has_many = array(
     'roles' => array(
      'model' => 'role', 
      'through' => 'roles_permissions', 
     ), 
    ); 
} 

Я создаю пользователей:

$user = ORM::factory('user'); 
$user->username = 'johndoe'; 
$user->email = '[email protected]'; 
//etc 
$user.save(); 

я создаю роли:

$author = ORM::factory('role'); 
$author->name = 'author'; 
$author->save(); 

создать разрешение:

$read = ORM::factory('permission'); 
$read->name = 'read'; 
$read->description = 'can read posts'; 
$read->save(); 

$write = ORM::factory('permission'); 
$write->name = 'write'; 
$write->description = 'can write posts'; 
$write->save(); 

Я добавить роли пользователей:

$user->add('roles', $author); 

добавить разрешения ролей:

$author->add('permissions', $read); 
$author->add('permissions', $write); 

и все это wo отлично.

Но мой вопрос как проверить, если пользователь имеет данное разрешение: в этом случае, как проверить, если JohnDoe имеет разрешение на писать сообщение?

Благодарим за помощь!

+0

Получите все разрешения авторов, а затем просмотрите их и посмотрите, разрешено ли разрешение на запись в этом наборе объектов разрешений. – hakre

+0

Я хочу проверить, имеет ли $ user разрешение на запись, а не если $ author имеет разрешение на запись .. –

+0

Затем вам сначала нужно получить роль (и) пользователя, а затем просмотреть их, чтобы посмотреть, разрешено ли разрешение. Что с этим сложно? – hakre

ответ

1

один запрос, но только два присоединяется по сравнению с предыдущим ответом

class Model_User extends ORM { 

// ... some stuff here 

public function has_permission($permission_name) 
{ 
    return (bool) ORM::factory('permission') 
     ->where('permission.name', '=', $permission_name) 
     ->join('roles_permissions') 
      ->on('roles_permissions.permission_id', '=', 'permision.permission_id') 
     ->join('roles_users') 
      ->on('roles_users.role_id', '=', 'roles_permissions.role_id') 
      ->on('roles_users.user_id', '=', DB::expr((int) $this->user_id)) 
     ->count_all(); 
} 

}

0

Я нашел решение, в 1 запрос:

$count = ORM::factory('permission') 
          ->join('roles_permissions') 
          ->on('permission.permission_id', '=', 'roles_permissions.permission_id') 
          ->join('roles') 
          ->on('roles.role_id', '=', 'roles_permissions.role_id') 
          ->join('users_roles') 
          ->on('roles.role_id', '=', 'users_roles.role_id') 
          ->join('users') 
          ->on('users.user_id', '=', 'users_roles.user_id') 
          ->on('users.user_id', '=', DB::expr($user->user_id)) 
->where('permission.name', '=', 'write') 
          ->find_all() 
          ->count(); 

, а затем, если $count > 0, это означает, что $ пользователь имеет разрешение на записи.

Есть ли более простое решение?

-1

Вот это лучшее решение, которое будет выполнять быстрый запрос, когда первичный ключ или экземпляр модели поставляется:

<?php 

class Model_User extends ORM { 

    // ... 

    /** 
    * Check if a user is allowed to perform an action based on permissions 
    * attached to the user's roles. 
    * 
    * @param int|string|Model_Permission $permission name, primary key or instance of permission 
    * @return boolean TRUE if allowed; FALSE otherwise 
    */ 
    public function is_allowed_to($permission) 
    { 
     // We have a permission name 
     if (is_string($permission) AND ! is_numeric($permission)) 
      return (bool) ORM::factory('permission') 
       ->where('permission.name', '=', $permission) 
       ->join('roles_permissions') 
        ->on('roles_permissions.permission_id', '=', 'permission.permission_id') 
       ->join('roles_users') 
        ->on('roles_users.role_id', '=', 'roles_permissions.role_id') 
       ->where('roles_users.user_id', '=', $this->pk()) 
       ->count_all(); 

     // We can get the permission primary key 
     // to perform a faster query 
     $permission_id = ($permission instanceof Model_Permission) 
      ? $permission->pk() 
      : $permission; 

     return (bool) DB::select(array(DB::expr('COUNT(*)'), 'records_found')) 
      ->from('roles_permissions') 
      ->join('roles_users') 
       ->on('roles_users.role_id', '=', 'roles_permissions.role_id') 
      ->where('roles_permissions.permission_id', '=', $permission_id) 
      ->where('roles_users.user_id', '=', $this->pk()) 
      ->execute() 
      ->get('records_found'); 
    } 

    // ... 
} 
Смежные вопросы