とても素敵に見える光沢のある新しいATK4.2を理解し始めたところです。ただし、BasicAuthクラスで問題が発生しています。ユーザーモデルを使用してBasicAuthを拡張したいと思います。ただし、私のUserモデルには「email」フィールドが含まれていません。むしろ、電子メールアドレスを含むPersonモデルを参照しています。
DBテーブルの構造は次のとおりです。
人物テーブル
- id:主キー
- 名前:char
- room_number:int
- メール: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');
}
}
ユーザーモデル
'user'テーブルには、パスワードフィールドが含まれています。
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でユーザーパスワードを設定しようとすると、「ok」を押した後に次のエラーが発生します。
#Error in AJAXec response: SyntaxError: invalid XML attribute value
BaseException
モデルフィールドがロードされませんでした
追加情報:
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
Janchaに感謝します。
CRUDでユーザーの以前と同じフィールドを表示し、パスワードを正しく更新するために、次の変更を行いました。
人モデル
以前と同じ。
ユーザーモデル
'user'テーブルには、パスワードフィールドが含まれています。
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();
}
}
}
}
上記の変更はうまく機能し、ユーザーのパスワードを正常に更新できます。
ただし、.... UserとPersonの間にjoin()があるためです。Userエントリを削除することを選択すると、Personテーブルの対応する人物も削除されます。join()ドキュメントから:「クエリはテーブルを結合し、挿入、更新、削除は両方のテーブルに適用されます」、したがって意図しない副作用。
アップデート2
わかりました。join()を認証クラスに移動することで解決したと思います。BasicAuthクラスが「email」フィールドにアクセスできるようにします。CRUDクラスは結合を認識せず、Userモデルの結合されたエントリを削除します。
ユーザーモデル
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');
}
}