symfony askeet Day 12
- パスワードの再発行フォームを作る
- メールを送信する
パスワードの再発行フォームを作る
まずはアクションを書く。
場所: askeet2/apps/frontend/modules/user/actions/actions.class.php
public function executePasswordRequest() { }
とりあえず、中身は空っぽ。あとで、実装すると。
テンプレートも書く。
場所: askeet2/apps/frontend/modules/user/templates/passwordRequestSuccess.php
<?php use_helper('Validation') ?> <h2>パスワード再発行</h2> <p>あなたのメールアドレスにパスワードをランダムで再発行してお届けします。</p> <?php echo form_tag('@user_require_password') ?> <?php echo form_error('email') ?> <label for="email">メールアドレス:</label> <?php echo input_tag('email',$sf_params->get('email'),'style=width:150px') ?><br /> <?php echo submit_tag('送信') ?> </form>
- use_helperを忘れるとエラーが出るから忘れないように。(というかこれでまたハマった)
パスワード再発行が求められるところにリンクを張っておく。
ログインフォームに必要なのでログインフォームのところに張っておく。
DRY原則を思い出したのでついでにログインフォームをパーシャル化しておく。
まずはパーシャル化
場所: askeet2/apps/frontend/modules/user/templates/_login.php
<?php echo form_tag('user/login') ?> <fieldset> <?php use_helper('Validation') ?> <div class="form-row"> <?php echo form_error('nickname') ?> <label for="nickname">ニックネーム:</label> <?php echo input_tag('nickname',$sf_params->get('nickname')) ?> </div> <div class="form-row"> <?php echo form_error('password') ?> <label for="password">パスワード:</label> <?php echo input_password_tag('password') ?> <?php echo link_to('[パスワードを忘れた方へ]','@user_require_password') ?> </div> </fieldset> <?php echo input_hidden_tag('referer',$sf_request->getAttribute('referer')) ?> <?php echo submit_tag('サインイン') ?> </form>
で、元々のタグがあったところに↓を張っていく。
場所: askeet2/apps/frontend/templates/layout.php
<?php include_partial('user/login',array('sf_params' => $sf_params, 'sf_request' => $sf_request)) ?>
場所: askeet2/apps/frontend/modules/user/templates/loginSuccess.php
<?php include_partial('login',array('sf_params' => $sf_params, 'sf_request' => $sf_request)) ?>
これで、リンクは完了。
ルーティングを設定する。
場所: askeet2/apps/frontend/config/routing.yml
user_require_password: url: /password_request param: { module: user, action: passwordRequest }
バリデーション
場所: askeet2/apps/frontend/modules/user/validate/passwordRequest.yml
methods: post: [email] names: email: required: Yes required_msg: メールアドレスが入力されていません。 validators: emailValidator emailValidator: class: sfEmailValidator param: email_error: 'メールアドレスの形式が正しくありません。(正しい例: example@example.com)'
アクションを修正する。
場所: askeet2/apps/frontend/modules/user/actions/actions.class.php
public function handleErrorPasswordRequest() { return sfView::SUCCESS; } public function executePasswordRequest() { if($this->getRequest()->getMethod() != sfRequest::POST) { // フォームを表示する return sfView::SUCCESS; } // フォーム投稿を取り扱う $c = new Criteria(); $c->add(UserPeer::EMAIL,$this->getRequestParameter('email')); $user = UserPeer::doSelectOne($c); // メールアドレスは存在するか? if($user) { // 新しいランダムパスワードを指定する $password = substr(md5(rand(100000,999999)),0,6); $user->setPassword($password); $this->getRequest()->setAttribute('password',$password); $this->getRequest()->setAttribute('nickname',$user->getNickname()); $raw_email = $this->sendEmail('mail','sendPassword'); $this->logMessage($raw_email,'debug'); // 新しいパスワードを保存する $user->save(); return 'MailSent'; } else { $this->getRequest()->setError('email','このメールアドレスは登録されていませんでした。ご確認の上もう一度お試しください。'); return sfView::SUCCESS; } }
確認ページのテンプレートを書く
場所: askeet2/apps/frontend/modules/user/templates/passwordRequestMailSent.php
<h2>新パスワードが送られました。</h2> <p>新パスワードが</p> <p><?php echo $sf_params->get('email') ?>に送られました。</p> <p>メールを受け取ったらすぐに<?php echo link_to('ログイン','@login') ?>してください。</p>
メールを送信する。
まずはモジュールをつくる
symfony init-module frontend mail
アクションを作る
場所: askeet2/apps/frontend/modules/mail/actions/actions.class.php
<?php /** * mail actions. * * @package askeet * @subpackage mail * @author Your name here * @version SVN: $Id: actions.class.php 2692 2006-11-15 21:03:55Z fabien $ */ class mailActions extends sfActions { public function executeSendPassword() { $mail = new sfMail(); $mail->addAddress($this->getRequestParameter('email')); $mail->setFrom('Askeet事務局 <askeet@example.com>'); $mail->setSubject('【Askeet】パスワード再発行通知'); $mail->setPriority(1); $mail->addEmbeddedImage(sfConfig::get('sf_web_dir').'/images/askeet_logo.gif','CID1','Askeet Logo','base64','image/gif'); $this->mail = $mail; $this->nickname = $this->getRequest()->getAttribute('nickname'); $this->password = $this->getRequest()->getAttribute('password'); } }
メールテンプレートを書く
HTMLメール用
場所: askeet2/apps/frontend/modules/mail/templates/sendPasswordSuccess.php
<p><?php echo $nickname ?>さんへ</p> <p>あなたがリクエストした結果を送信しました。</p> <p>パスワードは安全のためにランダムな数値で再発行しました。</p> <p>次のアカウントでログインできます。</p> <p> ニックネーム: <strong><?php echo $nickname ?></strong><br /> パスワード: <strong><?php echo $password ?></strong> </p> <p>ログインは<?php echo link_to('こちらから','@login') ?>どうぞ。</p> <p>これからもAskeet!をよろしくおねがいします。</p> <p>Askeet!事務局 < askeet@example.com ></p>
HTMLメールが読めなかった時用
場所: askeet2/apps/frontend/modules/mail/templates/sendPasswordSuccess.altbody.php
<?php echo $nickname ?>さんへ あなたがリクエストした結果を送信しました。 パスワードは安全のためにランダムな数値で再発行しました。 次のアカウントでログインできます。 ニックネーム: <?php echo $nickname ?> パスワード: <?php echo $password ?> これからもAskeet!をよろしくおねがいします。 Askeet!事務局 ( askeet@example.com )
sfMailの設定
開発環境ではメールを送信しないようにするなどの処置を設定します。
場所: askeet2/apps/frontend/modules/mail/config/mailer.yml
dev: deliver: off all: mailer: sendmail
あと、直接メールアクションにアクセスできないように設定します。
場所: askeet2/apps/frontend/modules/mail/config/module.yml
all: is_internal: on
テストデータを書き直す。
場所: askeet2/data/fixtures/test_data.yml
User: anonymous: nickname: anonymous first_name: Anonymous last_name: Coward crazyup: nickname: crazyup first_name: Shota last_name: Enomoto password: shota email: shota@example.com dinotaro: nickname: dino first_name: Taro last_name: Dino password: dino email: dinotaro@example.com
参考: askeet day twelve:Emails の解説 uthorofotus iruc
あとはテストデータを流し込みます。
php batch/load_data.php