php – 我可以使用相同的表以不同的方式重构我的多个用户类型的设置吗?

前端之家收集整理的这篇文章主要介绍了php – 我可以使用相同的表以不同的方式重构我的多个用户类型的设置吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个my_users表,我现在需要通过删除角色列来重构它,以支持每个用户支持多个角色.例如,我正在处理的3种用户类型是:

>战士
>裁判
>经理

因此表设置如下所示:

Users.PHP

use CakeDC\Users\Model\Table\UsersTable as BaseUsersTable;

class UsersTable extends BaseUsersTable
{
    public function initialize(array $config)
    {   
        parent::initialize($config);

        $this->setEntityClass('Users\Model\Entity\User');

        $this->belongsToMany('UserRoles',[
            'through' => 'users_user_roles'
        ]); 

        $this->hasMany('UsersUserRoles',[
            'className' => 'Users.UsersUserRoles','foreignKey' => 'user_id','saveStrategy' => 'replace',]);
    }

    public function findRole(Query $query,array $options)
    {
        return $query
            ->innerJoinWith('UserRoles',function($q) use ($options) {
                return $q->where(['role_key' => $options['role_key']]);
            });
    }
}

MyUsersTable.PHP

class MyUsersTable extends Table
{   
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->setTable('my_users');

        $this->setPrimaryKey('user_id');

        $this->belongsTo('Users',[
            'className' => 'Users.Users',]);
    }

    /**
     * @param Cake\Event\Event $event
     * @param Cake\ORM\Query $query
     * @param ArrayObject $options
     */
    public function beforeFind(Event $event,Query $query,\ArrayObject $options)
{
        // set the role
        if (defined(static::class.'::ROLE') && mb_strlen(static::ROLE) > 0) {
            $role = static::ROLE;

            // set user conditions
            $query->innerJoinWith('Users',function($query) use ($role) {
                return $query->find('role',[
                    'role_key' => $role,]);
            });
        }
    }

    /**
     * @param \Cake\ORM\Query $query
     * @param array $options
     */
    public function findByRegistrationCode(Query $query,array $options): Query
    {
        $query->where([
            $this->aliasField('registration_no') => $options['registration_no']
        ]);

        return $query;
    }
}

FightersTable.PHP

use MyUsers\Model\Table\MyUsers;

class FightersTable extends MyUsersTable
{       
    const ROLE = 'fighter';

    public function initialize(array $config)
    {   
        parent::initialize($config);

        $this->setEntityClass('Fighters\Model\Entity\Fighter');
    }       

    /**
     * @param Validator $validator
     * @return Validator $validator
     */
    public function validationDefault(Validator $validator): Validator
    {
        $validator = parent::validationDefault($validator);

        $validator->allowEmpty('field');
    }
}

RefereesTable.PHP和ManagersTable.PHP类似于FightersTable,但有自己的验证规则,可能有自己的特殊实体虚拟属性,而不是.

问题:是否有一种更好的结构方式,或者更具体地说是另一种方法来进行beforeFind以区分角色?如果角色的要求与用户保持1:1,我可能会做这样的事情:

$this->belongsTo('Fighters',[
    'conditions' => [
        'role' => 'fighter'
    ],'className' => 'MyUsers',]);

我很欣赏任何有关重组的见解.

您可以定义belongsTo关联以使用findByRole finder
$this->belongsTo('Fighters',[
    'foreignKey' => 'user_id','finder' => ['byRole' => ['role' => 'fighter']]
]);

当然,你必须在MyUsers中定义finder:

public function findByRole(Query $query,\ArrayObject $options)
{
    $role = $options['role'];

    // set user conditions
    $query->innerJoinWith('Users',function($query) use ($role) {
       return $query->find('role',[
          'role_key' => $role,]);
        });
    }
}

我还将beforeFind逻辑提取到RoleBehavior或MultiRoleBehavior behavior中,即:
SRC /型号/性能/ RoleBehavior.PHP

<?PHP
namespace App\Model\Behavior;

use Cake\ORM\Behavior;
use Cake\ORM\Query;
use Cake\Event\Event;

/**
 * Role-specific behavior
 */
class RoleBehavior extends Behavior
{

    /**
     * @var array multiple roles support
     */
    protected $_defaultConfig = [
        'roles' => []
    ];


    public function initialize(array $config)
    {
        parent::initialize($config);
        if (isset($config['roles'])) {
            $this->config('roles',$config['roles'],false /* override,not merge*/);
        }
    }

    public function beforeFind(Event $event,\ArrayObject $options,$primary) {
        // set user conditions
        $query->innerJoinWith('Users',function($query) use ($roles) {
            return $query->find('role',[
                'role_key' => $roles,]);
        });
    }
}

它使用多个角色,但如果需要,您只需将其更改为单个角色即可.以下是其他一些事情要做 – 可能将$query-> innerJoinWith(‘Users’…提取到行为中的单独方法中,并在MyUsers :: findByRole(…)中调用它…

接下来,您可以将此行为直接附加到扩展类,只需使用行为配置替换静态ROLE:

use MyUsers\Model\Table\MyUsers;

class FightersTable extends MyUsersTable
{       
    public function initialize(array $config)
    {   
        parent::initialize($config);

        $this->setEntityClass('Fighters\Model\Entity\Fighter');

        $this->addBehavior('Role',[ 'roles' => ['fighter']]);
    }
}

或者,您可以通过将行为附加到MyUsers表(即从控制器)来管理您的特定于角色的逻辑:

$this->MyUsers->addBehavior('Role',['roles' => ['manager']])

You also can change the behavior setup on the fly

$this->MyUsers->behaviors()->get('Role')->config([
   'roles' => ['manager'],]);

我希望它有所帮助.

原文链接:https://www.f2er.com/php/136892.html

猜你在找的PHP相关文章