スポンサードリンク

CakePHPで管理機能を作っているところなんですが、
ユーザーのパスワードを変更したい場合に
どの方法を取ろうかと色々と悩んだので
2つほど考えたのですが、
片方を色々な理由でボツにしました。
なんとなく、もったいないかもと思ったので
その覚え書きです。
スポンサードリンク
パスワードの変更画面をどうするか
最初パスワードの変更をどの画面でやるのかで迷いました。
とりあえず、考えられるのは
1.ユーザー名の変更と同じにする
2.パスワードのみの変更画面を作る
1番は画面とアクションを新たに作らなくてもいいので
最初は1番で作っていました。
この方法がボツになりました。
理由はモデルにあるbeforeSaveメソッドを消さないといけなくなったためです。
でも、何かに使えるかもしれないので
とりあえず、その構築を書いていきます。
パスワードの変更をユーザー名の変更と同じにする
まず、Viewファイルを作ります。
View/Users/edit.ctp
<?php echo $this->Form->create('User'); ?> <table> <tr> <th>ユーザー名</th> <td><?php echo $this->Form->input('username', array('label' => 'username'));?></td> </tr> <tr> <th>パスワード</th> <td><?php echo $this->Form->input('password', array('label' => '', 'value' => '')); ?></td> </tr> </table> <?php echo $this->Form->end('編集'); ?>
パスワードは空白の場合は以前のパスワードのままにして
入力されたら変更するという方法をとりました。
次に、バリデートを付けます。
Model/User.php
class User extends AppModel{ public $name = 'User'; public $validate = array( 'username' => array( 'required' => array( 'rule' => array('notEmpty'), 'message' => 'ユーザー名は必須です。' ) ), 'password' => array( 'rule1' => array( 'rule' => array('alphaNumeric'), 'required' => false, 'allowEmpty' => true, 'message' => '半角英数字で入力して下さい。' ), 'rule2' => array( 'rule' => array('minLength', 6), 'message' => '6文字以上で入力して下さい。' ) ) ); public function beforeSave($options = array()) { if (isset($this->data[$this->alias]['password'])) { $this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']); } return true; } }
※この段階ではbeforeSaveはまだあります。
バリデーションは空白を許可しています。
空白の場合は以前のパスワードのままという風にするためです。
Controller/UsersController.php
function edit($id = null) { if (!$id) { throw new NotFoundException(__('エラー:【戻る】を押して下さい!')); } $user = $this->User->findById($id); if (!$user) { throw new NotFoundException(__('エラー:データがありません【戻る】を押して下さい!')); } // POST送信なら if($this->request->is('post') || $this->request->is('put')) { $this->User->set($this->data); //バリデーションをハッシュ化前にチェック if ($this->User->validates()) { if ($this->request->data['User']['password'] == ""){ //入力されてなかったら元のパスワードのまま; $this->request->data['User']['password'] = $user['User']['password']; } $this->User->create(); if ($this->User->save($this->request->data)) { $this->Session->setFlash(__('変更しました')); $this->redirect(array('action' => 'index')); } else { $this->Session->setFlash(__('変更できませんでした。やり直して下さい')); } } }else{ //指定プライマリーキーのデータをセット $this->request->data = $user; } }
フォームから送られてきたデータからの場合は
元のパスワードを入れて保存するので
これでできたと思った・・・のですが。
スポンサードリンク
saveの時点でbeforeSaveが呼び出される
結果的に元のパスワードをフォームデータに入れても
saveメソッドの前にbeforeSaveメソッドが動いて
ハッシュされてたパスワードが
さらにハッシュされるという事態になりました。
じゃあ、befoerSaveをなくせばいいじゃんということで
function edit($id = null) { if (!$id) { throw new NotFoundException(__('エラー:【戻る】を押して下さい!')); } $user = $this->User->findById($id); if (!$user) { throw new NotFoundException(__('エラー:データがありません【戻る】を押して下さい!')); } // POST送信なら if($this->request->is('post') || $this->request->is('put')) { $this->User->set($this->data); //バリデーションをハッシュ化前にチェック if ($this->User->validates()) { if ($this->request->data['User']['password'] == ""){ //入力されてなかったら元のパスワードのまま $this->request->data['User']['password'] = $user['User']['password']; }else{ //※↓↓↓↓追加↓↓↓↓ //パスワードをハッシュ化 $this->request->data['User']['password'] = AuthComponent::password($this->request->data['User']['password']); } $this->User->create(); if ($this->User->save($this->request->data)) { $this->Session->setFlash(__('変更しました')); $this->redirect(array('action' => 'index')); } else { $this->Session->setFlash(__('変更できませんでした。やり直して下さい')); } } }else{ //指定プライマリーキーのデータをセット $this->request->data = $user; } }
以上のようにして
モデルに書いてあるbeforeSaveを消してしまえば
期待通りの動きができました。
しかし、befoerSaveを消してしまうと
後々面倒なので
この方法はあきらめて
最初に書いていた
2.パスワードのみの変更画面を作る
を実装することにしました。
最初からこっちにしておけばよかったな~
実装の仕方は次回書きます。
スポンサードリンク