[symfony] askeet 5日目
5日目はログイン処理の追加とページ処理です。
ログイン処理
ログインリンク追加
askeet/apps/frontend/templates/layout.php
about のリンクの前に入れる
<li><?php echo link_to('sign in', 'user/login') ?></li>
デバッグモードだと symfony のツールバーにログインのリンクが隠れてしまう。[sf]ボタンをクリックするとデバッグ用のツールバーを隠すことができます。
ユーザモジュールの追加
symfony init-module frontend user
上記コマンドを実行すると下記のようなファイルが作成されます。
>> dir+ /home/askeet/apps/frontend/modules/user/actions >> file+ /home/askeet/apps/frontend/modu.../user/actions/actions.class.php >> dir+ /home/askeet/apps/frontend/modules/user/templates >> file+ /home/askeet/apps/frontend/modu...user/templates/indexSuccess.php >> file+ /home/askeet/test/functional/frontend/userActionsTest.php >> tokens /home/askeet/test/functional/frontend/userActionsTest.php >> tokens /home/askeet/apps/frontend/modu.../user/actions/actions.class.php >> tokens /home/askeet/apps/frontend/modu...user/templates/indexSuccess.php
ログインアクション
askeet/apps/frontend/modules/user/actions/actions.class.php
public function executeLogin() { $this->getRequest()->setAttribute('referer', $this->getRequest()->getReferer()); return sfView::SUCCESS; }
これは仮の処理でとりあえずログインフォームを表示するだけの処理です。
ログインビュー
ログインフォームを表示するビューを作成します。
askeet/apps/frontend/modules/user/templates/loginSuccess.php
<?php echo form_tag('user/login') ?> <fieldset> <div class="form-row"> <label for="nickname">nickname:</label> <?php echo input_tag('nickname', $sf_params->get('nickname')) ?> </div> <div class="form-row"> <label for="password">password:</label> <?php echo input_password_tag('password') ?> </div> </fieldset> <?php echo input_hidden_tag('referer', $sf_request->getAttribute('referer')) ?> <?php echo submit_tag('sign in') ?> </form>
さっそく先ほど作成したリンクからログインフォームを表示させてみると
Call to undefined function form_tag()
とエラーになった。Form ヘルパーが使えていないようです。
調べたところ
<?php use_helper('Form'); ?>
として使用するヘルパーを宣言しないといけないようです。バージョンが変わってデフォルトで使用できるヘルパーが変わったのでしょうか。
ログイン処理
先ほど仮に入れた処理を削除してログイン処理を実装します。
しかし、まだデータベースにパスワードフィールドがないので存在するユーザならパスワードが何でも認証します。
askeet/apps/frontend/modules/user/templates/loginSuccess.php
public function executeLogin() { if ($this->getRequest()->getMethod() != sfRequest::POST) { // display the form $this->getRequest()->setAttribute('referer', $this->getRequest()->getReferer()); } else { // handle the form submission $nickname = $this->getRequestParameter('nickname'); $c = new Criteria(); $c->add(UserPeer::NICKNAME, $nickname); $user = UserPeer::doSelectOne($c); // nickname exists? if ($user) { // password is OK? if (true) { $this->getUser()->setAuthenticated(true); $this->getUser()->addCredential('subscriber'); $this->getUser()->setAttribute('subscriber_id', $user->getId(), 'subscriber'); $this->getUser()->setAttribute('nickname', $user->getNickname(), 'subscriber'); // redirect to last page return $this->redirect($this->getRequestParameter('referer', '@homepage')); } } } }
ログアウト処理
public function executeLogout() { $this->getUser()->setAuthenticated(false); $this->getUser()->clearCredentials(); $this->getUser()->getAttributeHolder()->removeNamespace('subscriber'); $this->redirect('@homepage'); }
レイアウトの変更
ログイン状態によってログインフォームへのリンク部分を変更するようにレイアウトを変更します。
<?php if ($sf_user->isAuthenticated()): ?> <li><?php echo link_to('sign out', 'user/logout') ?></li> <li><?php echo link_to($sf_user->getAttribute('nickname', '', 'subscriber').' profile', 'user/profile') ?></li> <?php else: ?> <li><?php echo link_to('sign in/register', 'user/login') ?></li> <?php endif ?>
ログインしていない場合は[sign in/register]を表示し、ログインしている場合は[sign out]とログインしているユーザ名を表示しリンク先をプロフィール表示画面にします。
実際にログインしてみる
テストデータを見るとユーザが3名ほど登録されています。その中から[fabpot]というユーザでログインしてみます。nicknameに[fabpot]、パスワードは空で[sign in]ボタンをクリックすると認証後に質問一覧ページにリダイレクトされました。
ページ処理
一覧表示アクションの修正
1ページに表示する質問数を取得してページ処理する処理を追加する
askeet/apps/frontend/modules/question/actions.class.php
public function executeIndex () { $pager = new sfPropelPager('Question', sfConfig::get('app_pager_homepage_max')); $c = new Criteria(); $c->addDescendingOrderByColumn(QuestionPeer::INTERESTED_USERS); $pager->setCriteria($c); $pager->setPage($this->getRequestParameter('page', 1)); $pager->setPeerMethod('doSelectJoinUser'); $pager->init(); $this->question_pager = $pager; }
アプリケーション設定ファイルを変更
設定ファイル(app.yml) に1ページに表示する質問数を追加する
askeet/apps/frontend/config/app.yml
all: pager: homepage_max: 2
この設定を取得するには下記のようにします。
sfConfig::get('app_pager_homepage_max')
これで ’2′ が取得できる。この部分は1ページの質問数を設定している部分です。現在3つしか質問がないので1ページに2つの質問を表示することによりページング処理のテストを行います。
ビューの変更
一覧を表示する foreach の部分を下記に変更。これでページ処理された一覧を取得。
<?php foreach($question_pager->getResults() as $question): ?>
一覧の下にページナビゲーションを追加
<div id="question_pager"> <?php if ($question_pager->haveToPaginate()): ?> <?php echo link_to('«', 'question/list?page=1') ?> <?php echo link_to('<', 'question/list?page='.$question_pager->getPreviousPage()) ?> <?php foreach ($question_pager->getLinks() as $page): ?> <?php echo link_to_unless($page == $question_pager->getPage(), $page, 'question/list?page='.$page) ?> <?php echo ($page != $question_pager->getCurrentMaxLink()) ? '-' : '' ?> <?php endforeach; ?> <?php echo link_to('>', 'question/list?page='.$question_pager->getNextPage()) ?> <?php echo link_to('»', 'question/list?page='.$question_pager->getLastPage()) ?> <?php endif; ?> </div>
ルーティングの変更
apps/frontend/config/routing.yml
popular_questions: url: /index/:page param: { module: question, action: list } login: url: /login param: { module: user, action: login }
リファクタリング
(チュートリアル通りなので省略)
ここまで進めてきて自分の環境とチュートリアルの環境が違う(question/list アクションが index だったり)のがどうもやりにくいので合せることにしました。
SVNレポジトリより routing.yml を落としてきてまずルーティングを合せました。
次に question コントローラの index アクションを list アクションに変更、indexSccess.php を listSuccess.php に変更。
これですっきりしました。
関連する投稿
One comment
コメントをどうぞ
Additional comments powered by BackType
1atheist…
…