我刚刚开始使用看起来非常漂亮的闪亮的新 ATK 4.2。但是,我在使用 BasicAuth 类时遇到了问题。我想使用 User 模型扩展 BasicAuth。但是,我的 User 模型不包含“电子邮件”字段,而是引用了包含电子邮件地址的 Person 模型。
DB表结构如下:
人表
- id:主键
- 名称:字符
- 房间号:整数
- 电子邮件:char
用户表
- id:主键
- person_id:人表的外键(id)
- 密码:char
ATK4.2类如下:
人物模型
class Model_Person extends Model_Table {
public $entity_code='person';
function init(){
parent::init();
$this->addField('name');
$this->addField('roomnumber');
$this->addField('email');
}
}
用户模型
“用户”表包含密码字段。
class Model_User extends Model_Table {
public $entity_code='user';
function init(){
parent::init();
$this->hasOne('Person');
}
}
用户认证类
class UserAuth extends BasicAuth {
function init() {
parent::init();
$this->setModel('Model_User', 'email', 'password');
$this->getModel()->addField('password')->system(true);
$this->usePasswordEncryption('sha256/salt');
}
}
经理页面。
// 管理员管理 mySQL 数据库中的表。
class page_mgr extends Page {
function init() {
parent::init();
$tabs=$this->add('Tabs');
$crud=$tabs->addTab('Users')->add('CRUD');
$crud->setModel('User');
if($crud->grid){
// Add prompt using user model id field.
$crud->grid->addColumn('prompt','set_password_prompt');
if($_GET['set_password_prompt']){
$auth = $this->add('UserAuth');
// load User from DB using row ID.
$model = $auth->getModel()->loadData($_GET['set_password_prompt']);
$model->set('password', $_GET['value'])->debug()->update();
$this->js()->univ()->successMessage('Changed password for '.$model->ref('person_id')->get('email'))
->execute();
}
}
}
}
当我尝试在 CRUD 中设置用户密码时,按“确定”后出现以下错误。
#Error in AJAXec response: SyntaxError: invalid XML attribute value
基本异常
模型字段未加载
附加信息:
Raised by object: Object Model_User(testing_admin_mgr_userauth_model_user)
id: 1
field: email
可能的行动:
Debug this Model
/var/www/html/testing/atk4/lib/BaseException.php:38
Stack trace:
/var/www/html/testing/atk4/lib/BaseException.php :38 BaseException BaseException->collectBasicData(Null, 1, 0)
/var/www/html/testing/atk4/lib/AbstractObject.php :292 BaseException BaseException->__construct("Model field was not loaded") / : (testing_admin_mgr_userauth_model_user Model_User->exception("Model field was not loaded")
/var/www/html/testing/atk4/lib/Model/Table.php :87 Loggercall_user_func_array(Array(2), Array(1))
/var/www/html/testing/atk4/lib/Model.php :115 testing_admin_mgr_userauth_model_user Model_User->exception("Model field was not loaded")
/var/www/html/testing/atk4/lib/Model.php :184 testing_admin_mgr_userauth_model_user Model_User->get("email")
/var/www/html/testing/atk4/lib/Auth/Basic.php :123 testing_admin_mgr_userauth_model_user Model_User->offsetGet("email") /: Logger{closure}(Object(Model_User))
/var/www/html/testing/atk4/lib/AbstractObject.php :427 (loggercall_user_func_array(Object(Closure), Array(1))
/var/www/html/testing/atk4/lib/Model/Table.php :531 testing_admin_mgr_userauth_model_user Model_User->hook("beforeSave")
/var/www/html/testing/atk4/lib/Model/Table.php :612 testing_admin_mgr_userauth_model_user Model_User->save()
/var/www/html/testing/admin/page/mgr.php :26 testing_admin_mgr_userauth_model_user Model_User->update()
/var/www/html/testing/atk4/lib/AbstractObject.php :189 testing_admin_mgr page_mgr->init()
/var/www/html/testing/atk4/lib/ApiFrontend.php :92 testing_admin Admin->add("page_mgr", "mgr", "Content")
/var/www/html/testing/atk4/lib/ApiWeb.php :332 testing_admin Admin->layout_Content()
/var/www/html/testing/atk4/lib/ApiFrontend.php :33 testing_admin Admin->addLayout("Content")
/var/www/html/testing/atk4/lib/ApiWeb.php :208 testing_admin Admin->initLayout()
/var/www/html/testing/admin/index.php :7 testing_admin Admin->main()
是否可以告诉 BasicAuth 引用 Person 模型来获取电子邮件字段,或者我们可以在 User 模型中以某种方式为电子邮件地址设置别名?
干杯
更新 1
谢谢詹查,
为了让 CRUD 为用户显示与以前相同的字段并正确更新密码,我进行了以下更改。
人物模型
和之前一样。
用户模型
“用户”表包含密码字段。
class Model_User extends Model_Table {
public $entity_code='user';
function init(){
parent::init();
$person = $this->join("person", "person_id");
$person->addField('email')->system(true);
// hasOne() links the referenced table so CRUD can use 'id' and 'name' for drop down menus, etc.
$this->hasOne('Person');
}
}
用户认证类
和之前一样。
经理页面。
// 管理员管理 mySQL 数据库中的表。
class page_mgr extends Page {
function init() {
parent::init();
$tabs=$this->add('Tabs');
$crud=$tabs->addTab('Users')->add('CRUD');
$crud->setModel('User');
if($crud->grid){
// Add prompt using user model id field.
$crud->grid->addColumn('prompt','set_password_prompt');
if($_GET['set_password_prompt']){
$auth = $this->add('UserAuth');
// load User from DB using row ID.
$model = $auth->getModel()->loadData($_GET['set_password_prompt']);
$model->set('password', $_GET['value'])->save();
$this->js()->univ()->successMessage('Changed password for '.$model->get('email'))
->execute();
}
}
}
}
以上更改效果很好,我可以成功更新用户的密码。
但是....因为用户和个人之间有一个 join() 。当我选择删除 User 条目时,Person 表中的相应人员也会被删除。来自 join() 文档:“查询将连接表、插入、更新和删除将应用于两个表”,因此会产生意想不到的副作用。
更新 2
好的,我想我已经通过将 join() 移动到身份验证类来解决它。这样 BasicAuth 类就可以访问“电子邮件”字段。而 CRUD 类看不到联接并删除用户模型中的联接条目。
用户模型
class Model_User extends Model_Table {
public $entity_code='user';
function init(){
parent::init();
$this->hasOne('Person');
}
}
用户认证类
class UserAuth extends BasicAuth {
function init() {
parent::init();
$this->setModel('Model_User', 'email', 'password');
$this->getModel()->addField('password')->system(true);
$person = $this->getModel()->join("person", "person_id");
$person->addField('email')->system(true);
$this->usePasswordEncryption('sha256/salt');
}
}