【问题标题】:CakePHP: reaching related tables from $Auth->user()CakePHP:从 $Auth->user() 到达相关表
【发布时间】:2019-05-12 08:37:12
【问题描述】:

CakePHP 3.7.7。这是我的用户表:

CREATE TABLE users (
 id int(11) NOT NULL AUTO_INCREMENT,
 user_level_id int(11) NOT NULL,
 email varchar(255) NOT NULL,
 password varchar(255) NOT NULL,
 PRIMARY KEY (id),
 UNIQUE KEY email (email),
 KEY user_level_id (user_level_id),
 CONSTRAINT users_ibfk_1 FOREIGN KEY (user_level_id) REFERENCES user_levels (id) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

和用户级别:

CREATE TABLE user_levels (
 id int(11) NOT NULL AUTO_INCREMENT,
 level varchar(255) DEFAULT NULL,
 PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

在我看来,我可以通过外键以这种方式访问​​level 值:

<td><?= $user->has('user_level') ? $this->Html->link($user->user_level->level, ['controller' => 'UserLevels', 'action' => 'view', $user->user_level->id]) : '' ?></td>

我需要做同样的事情(在sidebar-menu.ctp, that as no controller associated) with the current logged user retrieved by$Auth->user()`. 在这种情况下,我不明白正确的语法是什么:

$Auth->user()['user_level']

导致:

未定义索引:user_level

但是:

$Auth->user()['user_level_id']

有效,即使它不是我想要的。

更新

这是我在 AppController.php 中定义$Auth 的方式:

公共函数初始化() { 父::初始化();

    $this->loadComponent('RequestHandler', [
        'enableBeforeRedirect' => false,
    ]);
    $this->loadComponent('Flash', ['clear' => true]);
    $this->loadComponent('Auth', [
        'authenticate' => [
            'Form' => [
                'fields' => [
                    'username' => 'email',
                    'password' => 'password'
                ]
            ]
        ],
        'loginAction' => [
            'controller' => 'Users',
            'action' => 'login'
        ],
        'unauthorizedRedirect' => $this->referer()
    ]);
}

public function beforeRender(Event $event)
{
    $this->viewBuilder()->setTheme('AdminLTE');
    $this->viewBuilder()->setClassName('AdminLTE.AdminLTE');
    $this->set('Auth', $this->Auth);
}

public function isAuthorized($user = null)
{
    return false;
}

在 UsersController.php 中:

public function initialize()
{
    parent::initialize();
    $this->Auth->allow(['login']);
}

public function login()
{
    if ($this->request->is('post')) {
        $user = $this->Auth->identify();
        if ($user) {
            $this->Auth->setUser($user);
            return $this->redirect($this->Auth->redirectUrl());
        }
        $this->Flash->error(__('Username or password is incorrect.'));
    }
}

【问题讨论】:

  • 要获取关联数据,您必须使用包含,您使用了吗?见文档book.cakephp.org/3.0/en/orm/…\ORM
  • 是的,我将contain 指令放在UsersController.phpindexget 函数中
  • 为什么不使用这些方法? user() 是一个无通知的便捷包装器,因此 -&gt;user('user_level') 通常是正确的做法。
  • @mark $Auth-&gt;user('user_level') in sidebar-menu.ctp 为空。而是在控制器的视图中包含实际值。
  • 不确定您的 Auth 对象是什么。我使用AuthUser 助手,它有效。

标签: cakephp


【解决方案1】:

默认情况下,Auth 组件仅从单个模型(在本例中为用户)获取数据。

如果您想在 Auth 会话中存储来自关系的数据,请在您的 UsersTable 中使用自定义查找器。

验证设置示例:

'authenticate' => [
                'Form' => [
                    'finder' => 'emailOrNameAuth',
                    'fields' => ['username' => 'name', 'password' => 'password']
                ]
            ],

用户表:

public function findEmailOrNameAuth(\Cake\ORM\Query $query, array $options)
{
    $query
        ->where(
            [
                'OR' => [
                'email' => $options['username'],
                'name' => $options['username']
                ],
                'activated' => 1,
            ]
        )
        ->contain(['UserLevels']); // <---- 

    return $query;
}

阅读:

https://api.cakephp.org/3.7/class-Cake.Auth.FormAuthenticate.html

https://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#custom-find-methods

https://book.cakephp.org/3.0/en/controllers/components/authentication.html#customizing-find-query

【讨论】:

    猜你喜欢
    • 2015-01-07
    • 1970-01-01
    • 2011-12-20
    • 2013-12-15
    • 2015-05-13
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多