ラスタ
(0 件のコメント, 47 件の投稿)
ラスタ による投稿
認証 その3 SimpleAuthのユーザ管理画面を作る
0前の記事では認証画面の表示とユーザ管理テーブルのスキャフォールドまでで、ユーザデータの操作はできませんでした。
スキャフォールドを元に、Authクラスでユーザデータを操作するようにコードを変更してみます。
新規追加のための変更
最初にビューを変更します。
last_login、login_hashは新規ユーザ追加や変更時に入力する必要はありませんから削除しましょう。
また、profile_fieldsもとりあえず必要ないので削除します。
fuel/app/views/admin/user/_form.phpから以下の部分を削除します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<div class="clearfix"> <?php echo Form::label('Last login', 'last_login'); ?> <div class="input"> <?php echo Form::input('last_login', Input::post('last_login', isset($user) ? $user->last_login : ''), array('class' => 'span4')); ?> </div> </div> <div class="clearfix"> <?php echo Form::label('Login hash', 'login_hash'); ?> <div class="input"> <?php echo Form::input('login_hash', Input::post('login_hash', isset($user) ? $user->login_hash : ''), array('class' => 'span4')); ?> </div> </div> <div class="clearfix"> <?php echo Form::label('Profile fields', 'profile_fields'); ?> <div class="input"> <?php echo Form::textarea('profile_fields', Input::post('profile_fields', isset($user) ? $user->profile_fields : ''), array('class' => 'span8', 'rows' => 8)); ?> </div> </div> |
グループは管理者をデフォルトにすることにします。
同じくfuel/app/views/admin/user/_form.phpから以下の部分を削除します。
1 2 3 4 5 6 7 8 |
<div class="clearfix"> <?php echo Form::label('Group', 'group'); ?> <div class="input"> <?php echo Form::input('group', Input::post('group', isset($user) ? $user->group : ''), array('class' => 'span4')); ?> </div> </div> |
次に、モデルのvalidateメソッドから上記で削除した項目の検証を削除します。
削除後、fuel/app/classes/model/user.phpのvalidateメソッドは以下のようになります。
1 2 3 4 5 6 7 8 9 |
public static function validate($factory) { $val = Validation::forge($factory); $val->add_field('username', 'Username', 'required|max_length[50]'); $val->add_field('password', 'Password', 'required|max_length[255]'); $val->add_field('email', 'Email', 'required|valid_email|max_length[255]'); return $val; } |
最後に、コントローラがusersテーブルにデータを追加している部分を、Auth::user_createを実行するように書き換えます。 fuel/app/classes/controller/admin/user.phpのaction_createメソッドから以下の記述を削除し、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$user = Model_User::forge(array( 'username' => Input::post('username'), 'password' => Input::post('password'), 'group' => Input::post('group'), 'email' => Input::post('email'), 'last_login' => Input::post('last_login'), 'login_hash' => Input::post('login_hash'), 'profile_fields' => Input::post('profile_fields'), )); if ($user and $user->save()) { Session::set_flash('success', e('Added user #'.$user->id.'.')); Response::redirect('admin/user'); } |
以下のコードで置き換えます。
1 2 3 4 5 6 7 8 9 10 |
$userid = Auth::create_user( Input::post('username'), Input::post('password'), Input::post('email'), 100 ); if ($userid > 0) { Session::set_flash('success', e('Added user #'.$userid.'.')); Response::redirect('admin/user'); } |
それでは早速Add new Userしてみましょう。
Username、Password、Emailを入力してSaveします。
ユーザfuelが追加されました。 ログアウトしてfuelでログインしてみます。
ログインできました。うまくいったようです。
編集のための変更
SimpleAuthはユーザ名の変更が出来ません。
また、パスワードを変更するには新しいパスワードと共に元のパスワードが必要な仕様になっています。
このため、新規追加の入力フォームは流用できませんから、新しく作ることにします。
変更する項目はメールアドレスとパスワードとし、メールアドレスは変更されていれば上書き、パスワードは古いパスワードと新しいパスワードの両方が入力されたとき変更するようにします。
fuel/app/views/admin/user/_form.phpをコピーして_form_edit.phpを作り、編集フォームのための変更を行います。
Usernameの部分を削除し、Old PasswordとNew Passwordを追加します。
パスワードの初期状態はどちらも空にしておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?php echo Form::open(); ?> <fieldset> <div class="clearfix"> <?php echo Form::label('Email', 'email'); ?> <div class="input"> <?php echo Form::input('email', Input::post('email', isset($user) ? $user->email : ''), array('class' => 'span4')); ?> </div> </div> <div class="clearfix"> <?php echo Form::label('Old Password', 'oldpassword'); ?> <div class="input"> <?php echo Form::input('oldpassword', '', array('class' => 'span4')); ?> </div> </div> <div class="clearfix"> <?php echo Form::label('New Password', 'newpassword'); ?> <div class="input"> <?php echo Form::input('newpassword', '', array('class' => 'span4')); ?> </div> </div> <div class="actions"> <?php echo Form::submit('submit', 'Save', array('class' => 'btn btn-primary')); ?> </div> </fieldset> <?php echo Form::close(); ?> |
fuel/app/views/admin/user/edit.phpで表示するフォームを_form_edit.phpに変更します。
1 2 3 4 5 6 7 |
<h2>Editing user <?php echo $user->username?></h2> <br> <?php echo render('admin/user/_form_edit'); ?> <p> <?php echo Html::anchor('admin/user/view/'.$user->id, 'View'); ?> | <?php echo Html::anchor('admin/user', 'Back'); ?></p> |
上記のコードは、見出しにユーザ名を表示するようにしています。
次に、モデルに入力の検証コードを追加します。
fuel/app/classes/model/user.phpにvalidate_editメソッドを追加します。
1 2 3 4 5 6 7 8 9 |
public static function validate_edit($factory) { $val = Validation::forge($factory); $val->add_field('oldpassword', 'Old Password', 'required|max_length[255]'); $val->add_field('newpassword', 'New Password', 'required|max_length[255]'); $val->add_field('email', 'Email', 'required|valid_email|max_length[255]'); return $val; } |
続いてコントローラを変更します。
fuel/app/classes/coltroller/user.phpのaction_editメソッドから以下の部分を削除します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$user->username = Input::post('username'); $user->password = Input::post('password'); $user->group = Input::post('group'); $user->email = Input::post('email'); $user->last_login = Input::post('last_login'); $user->login_hash = Input::post('login_hash'); $user->profile_fields = Input::post('profile_fields'); if ($user->save()) { Session::set_flash('success', e('Updated user #' . $id)); Response::redirect('admin/user'); } else { Session::set_flash('error', e('Could not update user #' . $id)); } |
削除した部分を以下のコードで置き換えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
$succeed = true; if ($user->email != Input::post('email')) { if (! Auth::update_user(array('email' => Input::post('email')), $user->username)) { $succeed = false; Session::set_flash('error', e('Could not update user\'s Email')); } } if ($succeed) { $oldpw = Input::post('oldpassword'); $newpw = Input::post('newpassword'); if ((!empty($oldpw)) && (!empty($newpw))) { if (! Auth::change_password($oldpw, $newpw, $user->username)) { $succeed = false; Session::set_flash('error', e('Could not update password for ' . $user->username)); } } } if ($succeed) { Session::set_flash('success', e('Updated user ' . $user->username)); Response::redirect('admin/user'); } else { $this->template->set_global('user', $user, false); } |
モデルの編集フォーム検証メソッドを呼び出している部分をvalidateからvalidate_editに変更します。
1 |
$val = Model_User::validate_edit('edit'); |
それでは動作を確認しましょう。 ユーザadminでログインします。
ユーザfuelをEditします。
まずはメールアドレスを変更してみます。
fuel@example.comをmail@example.comに変更します。
mail@example.comに変更されました。 次にパスワードを変更してみます。
一旦ログアウトして、ユーザfuelの新しいパスワードでログインします。
ログイン出来ました。
これでユーザのメールアドレスとパスワードの変更ができるようになりました。
削除のための変更
このままでもユーザの削除はできるのですが、せっかくなので削除もAuthクラスを使うように変更しましょう。
コントローラの削除処理を変更します。
fuel/app/classes/controller/admin/user.phpのaction_deleteメソッドの以下の部分を
1 |
$user->delete(); |
以下のコードで置き換えます。
1 |
Auth::delete_user($user->username); |
ユーザadminでログインしてユーザfuelをDeleteします。
確認ダイアログでOKをクリックします。
ユーザfuelが削除されました。
WordPressのMystiqueテーマ
0当サイトはWordPressで構築しているわけですが、テーマはMystiqueというものを使っています。
このMystiqueをアップデートしたら、テーマ設定画面でJavaScriptがエラーを吐いて画面構成をデフォルトから変更できなくなってしまいました。
気に入っていたテーマなので、どうにかならないものかと調べてみたら、Mystiqueのサポートページに対策が投稿されていたのでメモっておきます。
wp-content/themes/mystique/atom-hooks.phpの
if(!ATOM_DEV_MODE && $app->options('optimize')){
という部分を
if(!ATOM_DEV_MODE || $app->options('optimize')){
に変更することで解消しました。
WordPress3.5とMystique3.3.2で起こる現象で、jquery.atomとjquery最新版の互換性の問題のようです。
MySQLにリモート接続できない
0たまに新規サーバーを建てたりすると、ローカルでしかmysqlに接続できなくて焦ったりします。
これはmy.cnfのbind-address
がデフォルトで127.0.0.1
になっているためで、このままでは127.0.0.1
へのアクセスしかlistenしてくれず、リモートから接続しようとしても知らんぷりでログさえ残らず原因不明に苦しむわけです。
このbind-address
を、192.168.1.
などにしておけばローカルネットワーク限定でlistenするようになります。
それでもサーバーのセグメントを引っ越したときにまた同じ現象にハマったりするので、いっそのこと0.0.0.0
にしてしまえばその後の変更も不要になります。
ubuntuのApacheドキュメントルート
0ubuntuの場合、CentOSと違ってDocumentRootをhttpd.confに書いてもうまく行きません。
というのも、ubuntuではhttpd.confの内容を/etc/apache2/sites-enabled下のファイルで上書きするようになっていて、デフォルトでは/etc/apache2/sites-enabled/000-defaultにDocumentRootが書かれているからです。
/etc/apache2/sites-enabled/000-defaultの内容を変更することで、DocumentRootが通るようになります。
認証 その2 SimpleAuthの認証画面を試す
0oil g admin
コマンドを使うとスキャフォールドと認証画面を一気に生成することができます。
ここでは、認証用ユーザ管理テーブルのスキャフォールドと認証画面をまとめて作ってみます。
まず、ユーザ管理テーブルのスキャフォールドを生成します。
FuelPHP 1.5ではfuel/packages/auth/exampleにSimpleAuth用のマイグレーションファイルがありますが、ここではoil g admin
を使うことが目的なので、oilコマンドでマイグレーションを生成します。
$ oil g admin user username:varchar[50] password:varchar[255] group:int:default[1] email:varchar[255] last_login:varchar[25] login_hash:varchar[255] profile_fields:text
マイグレーションをデータベースに反映させます。
$ oil r migrate
テーブルが出来たら、ユーザーを新規追加します。
oilコマンドでテストコンソールを開き、Authパッケージのcreate_userメソッドを実行します。
$ oil c
Fuel 1.4 - PHP 5.3.10-1ubuntu3.5 (cli) (Jan 18 2013 23:39:11) [Linux]
>>> Auth::create_user('admin', 'pass', 'admin@example.com', 100)
1
>>>
create_userメソッドの引数は、ユーザ名、パスワード、メールアドレスのほか、グループIDが必須です。
ここで指定している値100は、simpleauth.phpで設定している管理者グループのIDです。
成功すると追加されたレコードのidが表示されます。成功したらCtrl+Cでコンソールを終了します。
これだけで完了です。
public/adminをブラウザで開いてみましょう。
認証画面が表示されます。
さきほど新規追加したユーザでログインします。
ダッシュボードが表示されます。
上部のリンクUserをクリックするとスキャフォールドで作成されたUsersテーブル管理画面が表示されます。
以上でSimpleAuthの認証画面を確認できました。
ただし、この例ではAuth::create_user
の処理を入れていないので、このスキャフォールドを使った新規ユーザ追加や変更はできません。
追補
いろいろやっているうちに、ログインすると310リダイレクトループエラーになるようになってしまったときは、マイグレーションをやり直すと解消します。
認証 その1 SimpleAuthのシンプルな設定
0Authパッケージを使うと、ユーザ認証(Authentication)と認可(Authorization)のインターフェースを利用できます。
ここでは実装サンプルとして添付されているSimpleAuthを試してみます。
まずはfuel/app/config/config.phpにauthパッケージを読み込む記述を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 |
return array( 'language' => 'ja', 'log_threshold' => Fuel::L_ALL, 'always_load' => array( 'packages' => array( # Authパッケージを読み込みます 'auth', # ユーザ管理にORMを使います 'orm', ) ) ); |
次にfuel/packages/auth/config/auth.phpとfuel/packages/auth/config/simpleauth.phpをfuel/app/configディレクトリにコピーします。
auth.phpではAuthドライバの設定を行います。これはこのままで構いません。
simpleauth.phpではSimpleAuthの設定を行います。ユーザにアクセス権限を与えるためにグループIDの設定が必要ですが、コメントアウトされているので、これを外します。
1 2 3 4 5 6 7 |
'groups' => array( -1 => array('name' => 'Banned', 'roles' => array('banned')), 0 => array('name' => 'Guests', 'roles' => array()), 1 => array('name' => 'Users', 'roles' => array('user')), 50 => array('name' => 'Moderators', 'roles' => array('user', 'moderator')), 100 => array('name' => 'Administrators', 'roles' => array('user', 'moderator', 'admin')), ), |
以上でとりあえずSimpleAuthを動かす設定ができました。
データベースを使う その5 スキャフォールド生成
0スキャフォールドは足場という意味で、これを生成することでORMの機能に加えてテーブル管理のコントローラとビューまでコマンドひとつで出来てしまうという、恐ろしく便利なものです。
さっそく試してみましょう。
ここではnameフィールドとageフィールドを持つuserテーブルを作成することとします。
$ oil g scaffold user name:varchar[32] age:int
fuel/app/classes/model/user/phpから見ていきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?php use Orm\Model; class Model_User extends Model { protected static $_properties = array( 'id', 'name', 'age', 'created_at', 'updated_at', ); protected static $_observers = array( 'Orm\Observer_CreatedAt' => array( 'events' => array('before_insert'), 'mysql_timestamp' => false, ), 'Orm\Observer_UpdatedAt' => array( 'events' => array('before_save'), 'mysql_timestamp' => false, ), ); public static function validate($factory) { $val = Validation::forge($factory); $val->add_field('name', 'Name', 'required|max_length[32]'); $val->add_field('age', 'Age', 'required|valid_string[numeric]'); return $val; } } |
ORMパッケージのModelを継承しているのはORMモデル生成の場合と同様ですが、validateメソッドが追加されています。このメソッドはコントローラから呼び出され、データのバリデーション条件を返します。
また、マイグレーションファイルもモデル生成時と同じくfuel/app/migrationsディレクトリに生成されています。
次に、fuel/app/classes/controller/user.phpを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
<?php class Controller_User extends Controller_Template { public function action_index() { $data['users'] = Model_User::find('all'); $this->template->title = "Users"; $this->template->content = View::forge('user/index', $data); } public function action_view($id = null) { $data['user'] = Model_User::find($id); is_null($id) and Response::redirect('User'); $this->template->title = "User"; $this->template->content = View::forge('user/view', $data); } public function action_create() { if (Input::method() == 'POST') { $val = Model_User::validate('create'); if ($val->run()) { $user = Model_User::forge(array( 'name' => Input::post('name'), 'age' => Input::post('age'), )); if ($user and $user->save()) { Session::set_flash('success', 'Added user #'.$user->id.'.'); Response::redirect('user'); } else { Session::set_flash('error', 'Could not save user.'); } } else { Session::set_flash('error', $val->error()); } } $this->template->title = "Users"; $this->template->content = View::forge('user/create'); } public function action_edit($id = null) { is_null($id) and Response::redirect('User'); $user = Model_User::find($id); $val = Model_User::validate('edit'); if ($val->run()) { $user->name = Input::post('name'); $user->age = Input::post('age'); if ($user->save()) { Session::set_flash('success', 'Updated user #' . $id); Response::redirect('user'); } else { Session::set_flash('error', 'Could not update user #' . $id); } } else { if (Input::method() == 'POST') { $user->name = $val->validated('name'); $user->age = $val->validated('age'); Session::set_flash('error', $val->error()); } $this->template->set_global('user', $user, false); } $this->template->title = "Users"; $this->template->content = View::forge('user/edit'); } public function action_delete($id = null) { if ($user = Model_User::find($id)) { $user->delete(); Session::set_flash('success', 'Deleted user #'.$id); } else { Session::set_flash('error', 'Could not delete user #'.$id); } Response::redirect('user'); } } |
メソッド | 処理内容 |
action_index | 一覧表示 |
action_view | 個別データ表示 |
action_create | 新規追加 |
action_edit | 変更 |
action_delete | 削除 |
action_createとaction_editでは、入力されたデータがモデルのvalidateから得た規定に合っているかを確認しています。
fuel/app/views/userディレクトリにはビューのコードが生成されています。
template.php | ページのテンプレート |
_form.php | 入力フォーム |
index.php | 一覧表示 |
view.php | 個別表示 |
create.php | 新規追加 |
edit.php | 変更 |
コードが生成されているのを確認したらデータベースに反映させます。
$ oil r migrate
それではページを表示してみましょう。ブラウザでpublic/usersを開きます。
データ一覧ページが表示されます。
まだデータはありません。
Addボタンをクリックすると新規追加ページが表示されます。
データを入力したらSaveボタンをクリックします。
データ一覧ページに戻ります。
入力したデータが追加されています。
次にViewをクリックしてデータを表示してみます。
選択したデータが表示されます。
Editをクリックしてデータを変更してみます。
変更してSaveボタンをクリックすると、再び一覧ページが表示されます。
変更が反映されているのがわかります。
最後にDeleteをクリックして削除してみます。
一覧が表示され、データは削除されています。
このように、スキャフォールドを使うことで簡単にデータベースアプリケーションの基本機能を構築することができます。
データベースを使う その2 フィールド型
0データベースを使うにはoilコマンドのマイグレーション機能とモデル生成機能を利用します。
oilコマンドで使用できるフィールド型は以下のとおりです。
フィールドの書式はフィールド名:フィールド型
です。
string[n]
varchar[n]
int[n]
enum[value1, value2]
decimal[n n]
float[n n]
text
blob
datetime
date
timestamp
time
データベースを使う その6 マイグレーション
0oilコマンドでデータベースをいろいろと変更してみましょう。
これらのコマンドはfuel/migrationsディレクトリにマイグレーションファイルを生成します。
マイグレーションファイルを実際にデータベースに反映させるにはoil r migrate
を実行します。
マイグレーションによる変更はデータベースに対してのみ有効です。oil g model
で生成したコードのテーブルやフィールドには反映されません。
テーブル作成
書式:
oil g migration create_テーブル名 フィールド [フィールド] ...
例:
$ oil generate migration create_users name:text email:string[50] password:string[125]
テーブル名変更
書式:
oil g migration rename_table_テーブル名_to_新しいテーブル名
例:
$ oil generate migration rename_table_users_to_accounts
フィールド追加
書式:
oil g migration add_フィールド名_to_テーブル名 フィールド
例:
$ oil generate migration add_bio_to_accounts bio:text
フィールド名変更
書式:
oil generate migration rename_field_フィールド名_to_新しいフィールド名_in_テーブル名
例:
$ oil generate migration rename_field_name_to_username_in_accounts
テーブル削除
書式:
oil generate migration drop_テーブル名
例:
$ oil generate migration drop_accounts
データベースを使う その4 CRUDモデル生成
0oilコマンドでCRUDモデル(Create、Retrieve、Update、Deleteの機能を持ったModel_Crudクラス)のコードを自動生成してみます。
CRUDモデルはORMモデルほど強力ではありませんが、機能が絞られているぶん、簡単なアプリケーション手軽に作るのに向いています。
oilコマンドに--crud
オプションを付ける以外は、ORMモデルと同じ方法で生成できます。ORMモデル生成の記事も参照してください。
ここでは、varchar[32]のnameカラムを持つuserテーブルを生成します(テーブルの命名には少し注意が必要です)。
$ oil g model user name:varchar[32] --crud
上記のコマンドを実行すると、fuel/app/classes/model/user.phpファイルが生成されます。
oilコマンドは$ oil create
で作成したディレクトリで実行することに注意してください。
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php class Model_User extends \Model_Crud { protected static $_properties = array( 'id', 'name' ); protected static $_table_name = 'users'; } |
idはoilによって自動的に付加されます。
fuel/migrationsディレクトリにはusersテーブルをcreateする001_create_users.phpが生成されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php namespace Fuel\Migrations; class Create_users { public function up() { \DBUtil::create_table('users', array( 'id' => array('constraint' => 11, 'type' => 'int', 'auto_increment' => true), 'name' => array('constraint' => 32, 'type' => 'varchar'), ), array('id')); } public function down() { \DBUtil::drop_table('users'); } } |
ORMモデルと違って、CRUDモデルはオブザーバー機能を持たないため、テーブルにはcreate_atとupdate_atが付加されません。
モデルとマイグレーションを生成したら、データベースに反映させましょう。
$ oil r migrate
を実行すると、データベースにテーブルが作成されます。