sfGuardPlugin
symfony(1.1)を使ってシステムを構築中、ユーザー認証が必要になった。(というか最初から必要だったんだけど。)
sf_sandboxのチュートリアルで使われていたsfGuardPluginを使うことにした。日本語に訳されているドキュメントもある。基本的なインストールの方法はそっちを見て欲しい。
ここで書くのは「sfAuthUserモデルをカスタマイズする」より先の話。さっきのページに書いてある通り、sfGuardPluginを普通に使うとユーザー名、パスワード、有効・無効フラグ、最終ログイン日程度の情報しか保存できない。しかし、普通にシステムを作る場合、ユーザーテーブルに名前、住所、メールアドレス等の情報を持たせたいはず。
sfGuardPluginではsfGuardUserProfileという、外部テーブルと連係する仕組みを持ってるのでそれを使用。
Customerというクラス(customerテーブル)に付加情報を持たせて、sfGuardUserと1対1でリレーションさせる。
まずはschema.ymlから。customerテーブルのuser_idフィールドとsf_guard_userテーブルのidフィールドをjoinする。
propel:
customer:
_attributes: { phpName: Customer }
id: ~
user_id:
type: integer
foreignTable: sf_guard_user
foreignReference: id
required: true
onDelete: cascade
customer_name: { type: varchar(255), required: true, index: unique }
created_at: ~
onDeleteをcascadeにして、customerテーブルからレコードを削除した時に、関連するレコードをsf_guard_userからも削除されるようにする。
次はapps/app_name/modules/customer/config/generator.yml。
generator:
class: sfPropelAdminGenerator
param:
model_class: Customer
theme: default
fields:
customer_name: { type: input_tag, params: size=30, name: お客様名 }
#sfGuardUser
username: { name: ユーザー名 }
password: { name: パスワード }
password_bis: { name: パスワード(確認) }
is_active: { name: 有効なユーザー }
list:
title: お客様一覧
layout: tabular
display: [=customer_name, username, is_active]
object_actions:
_edit: ~
_delete: ~
max_per_page: 20
edit:
title: お客様情報の編集
display:
"ログイン情報": [ _username, _password, _password_bis, _is_active ]
"その他情報": [ customer_name ]
actions:
_list:
_save:
_delete:
ここでのポイントは、ちょっと面倒くさいけど、sf_guard_userの情報を編集する部分はパーシャル(partial)を使用する事。具体的には_username, _password, _password_bis, _is_activeの4つ。
_username.phpはこんな感じ。ユーザー名は変更不可
<?php
if ($customer->isNew()) {
echo object_input_tag($customer, 'getUsername',
array ('size' => 64,
'control_name' => 'customer[username]'));
} else {
echo $customer->getUsername();
}
?>
_password.phpはこんなの(_password_bis.phpも同様)。
<?php
echo input_password_tag('password', '');
?>
で、あとはactions.class.phpのupdateCustomerFromRequestを以下のようにした。
protected function updateCustomerFromRequest()
{
// リクエストパラメータの取得
$customer = $this->getRequestParameter('customer');
$password = $this->getRequestParameter('password');
$password2 = $this->getRequestParameter('password_bis');
// パスワードがセットされていて、確認用の入力とマッチするなら
if (isset($password) && $password === $password2)
{
$this->customer->setPassword($password);
}
// 残りは親クラスに任せる
parent::updateCustomerFromRequest();
}