[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…
…