忍者ブログ

uthorofotus iruc

プログラムを組むために考えたり憶えたりした、いろいろなことを記録していきます。タイトルの読みは「ウソロフォトス イルーク」

[19]  [18]  [17]  [16]  [15]  [14]  [13]  [12]  [11]  [10]  [9

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

askeet day five:forms and pager の解説

askeetチュートリアルの5日目『フォームとページャー』です。ここでいうページャーとは、googleで検索した際、検索結果を全件表示するかわりにページ下部に[1 2 3 4 5 …次へ]と出るような機能です。

5日目の日本語版はまだ無いようです。本家英語版はこちらです。フォーラムにはすべて翻訳完成していると報告があるみたいですので、5日目以降のチュートリアルもそのうち公開されるでしょう。かわりに有志の翻訳があるみたいです。
日本語版がないので、少し解説文を多めに書いておきます。

■これまでのsymfony(Previously on symfony)
今日はユーザ認証の機能と、質問一覧ページにページャーを付けます。

■ログインフォーム(Login form)
ログイン機能へのリンクをレイアウトテンプレートに追加します。その後、ユーザログインのためにUserモジュールを作成します。

symfonyコマンドでUserモジュールを作成すると、indexアクションとテンプレートを作ってくれます。ただし、これらは使わないので削除します。後でログインアクションを追加しますので、action.class.php自体は残しておきます。

▽user/loginアクションを作成する(Create the user/login action)
Userモジュールにloginアクションを追加します。ログインに成功したら、ログイン前にいたページに戻せるように、リファラ(referer)パラメータをリクエストクラスに保存します。return sfView::SUCCESS;というのは、特にreturnする変数が無い場合に指定します。この場合、デフォルト設定のビューテンプレート(myactionSuccess.php)を使用します。

▽loginSuccess.phpテンプレートを作成する(Create the loginSuccess.php template)
先ほどのアクションに対応するテンプレートloginSuccess.phpを作成します。symfonyにはビューテンプレートでフォームヘルパーが用意されていますので、それを使用します。ここでのポイントはフォームの送信先が、同じアクション(user/login)になっていることです。送信後の処理はこの次で用意します。リクエストクラスに保存したリファラの値をフォームで送信するように、hiddenで入れています。
ログインフォーム

フォームヘルパーはフォームタグを自動生成する関数です。form_tag[<form>]/input_tag[<input type="text">]/input_password_tag[<input type="password">/input_hidden_tag[<input type="hidden">/submit_tag[<input type="submit">]などを使用しています。ただし、フォームの閉じタグ(</form>)は素のhtmlになっています。これは、どんなフォームでも同じタグで済むからでしょうか?

日本語のフォームヘルパーの詳細説明はここにあります。

▽送信したログインフォームの処理(Handle the login form submission)
先ほどのログインアクションに、フォーム送信後の処理を追加します。まず、フォームから来たニックネームがUserテーブルに入ってるかチェックします。ニックネームが入っていなければさっき作ったログインフォームページを表示します。ログイン情報のパスワードや権限のチェックについてはそのうち追加します。

チェックが通ったならば、ニックネームとユーザIDをセッションに入れておきます。他のアクションはセッション情報を見ることにより、ユーザがログインしているか判断ができます。このアクションで$this->getUserというメソッドを使っています。$thisはsfActionを差していますので、これはユーザセッションを呼び出すメソッドです。Questionクラスなどが持っているModelのUserクラスを呼ぶメソッドとは違う機能ですので注意しましょう。

▽権限を付与する(Grant privileges)
askeetアプリケーションでは、ログインしたユーザだけ質問の投稿、質問に興味を示す(お気に入り)、回答の評価ができるようにします。他のアクションについてはログインしなくても実行出来る仕様になります。ユーザ権限によってアクション実行の制限するのは6日目で行います。

setAuthenticatedはログイン状況を設定するメソッドです。addCredentialは権限を付与するメソッドになります。"subscriber"は、ログインユーザに付与される権限名です。もし、管理者権限を与えようとする場合は"administrator"などの権限名になるでしょうか。

▽user/logoutアクションの追加(Add the user/logout action)
ログインを作りましたので、ログアウトも作ります。setAuthenticatedをfalseすることにより認証の解除します。clearCredentialsメソッドで複数の権限が付与されていても全部解除されます。ログアウト後は特に表示する情報もないので、サイトトップページを表示させます。

▽レイアウトの更新(Update the layout)
ログインしていないなら、user/loginへのリンクを表示します。ログインしているのなら、user/logoutへのリンクとユーザセッションに保存されているログインユーザ名を表示します。user/profileのリンク先アクションは後日のチュートリアルで作成しますので、そのままにしておきます。これらのリンクを追加する場所は、aboutリンクの前です。
レイアウトのナビゲーション

■Questionページャー(Question pager)
質問が大量に登録された場合、listページがとても長くなってしまうため分割をします。symfonyにはページャーという機能があり、1ページに10件だけ表示させたりできます。

▽question/listアクションの修正(Modify the question/list action)
listアクションをページャー(sfPropelPager)を使って書き換えます。sfPropelPagerインスタンスの作成時に1ページに表示する件数、setPageメソッドで現ページ数を指定するGETパラメータ名と何ページ目から表示を開始するのかの指定をします。これら詳細はSymfonyBookのPagerページを見てください。

addDescendingOrderByColumnにて、興味を持ったユーザ数が多い順(order by DESC intersted_users)と指定しています。setPeerMethodでは、QuestionPeerのどのメソッドを使ってデータを取得するのか指定しますが、その際にdoSelectではなくdoSelectJoinUserを使っています。これは、質問内容だけでなく質問を登録したユーザ内容(Userテーブル)も持ってこなければならないため、userテーブルのjoin句を含んだSQLを発行するメソッドを指定しました。

▽カスタムパラメータを使う(Use a custom parameter)
今までのチュートリアルでは、アプリケーションの設定は設定ファイルに保存していました。symfonyでは開発者が好きなデータを設定ファイル(sfConfig)に保存しておくことができます。1ページあたり2件表示といった情報もアクション内で設定するよりは、設定ファイルで指定した方が見通しが良くなります。先ほどのlistアクションをそのように修正し、設定をapp.ymlに記述します。設定ファイルを書き換えたので、prod環境にも反映されるように"symfony cc"をしておきましょう。

▽listSuccess.phpテンプレートの修正(Modify the listSuccess.php template)
listアクションを修正したことにより、テンプレートに渡される変数名がquestionからquestion_pagerへと変わりました。テンプレートの変数名を直しておきます。

▽ページナビゲーションの追加(Add page navigation)
今のビューテンプレートでは、初めの2質問しか表示出来ません。後ろにある質問も見れるようにナビゲーションリンクを追加します。ページャーの情報を使って、テンプレートにナビゲーションリンクを追加します。$question_pagerのforeachが終わった後にコードを入れましょう。

▽ページ切り替えのルーティングルールの追加(Add a routing rule for the subsequent pages)
ページャーでページを切り替えた際のルーティングルールを追加します。ついでにさっき作ったログインページもルーティングルールを追加しておきます。

■リファクタリング(Refactoring)
▽モデル(Model)
先ほど、question/listアクションをページャーを使って書き換えました。ただ、ここでやっていることはデータ取得処理なので、アクションに置くよりはModelクラスにコードを移した方が見通しが良くなります。

symfonyでは、DB接続をするModelコードはPeerクラスに置き、DBに関わらないModelコードはPeerのつかない方のクラスに置くようです。propelが生成するModelはそのルールに則っているようです。

▽テンプレート(Templates)
質問のリスト(一覧)表示は他でも使えそうなので、パーシャルで切り分けておきます。

テンプレート修正例として、Subversionを見るように指示されています。Subversion内を見ると、パーシャルのファイル名が違っっていたり(_question_list.php)、テンプレート内で独自のQuestionヘルパーを使っていたりとチュートリアルの内容とかなり違います。ただし、後日のチュートリアルはSubversion版に合わせて書かれていないので、ファイル名list.php、Questionヘルパー無しで作っておきます。
この修正は、コメント#12の内容をやっているようです。ヘルパーを作成したりしていますが、コード読むだけにしておきます。この修正をやってしまうと、後日のチュートリアルとファイル名などが遭わなくなるので、自分で対応しなくてはならなくなります。

■また明日(See you Tomorrow)
5日目はログインと一覧表示のページャー化をsymfonyを使って簡単に実装しました。そして、最後にリファクタリングしました。明日は登録ユーザだけが各機能にアクセスできるようにログイン処理の続きと、フォーム送信時の不正データのチェックについてです。

PR

この記事にコメントする

お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード   Vodafone絵文字 i-mode絵文字 Ezweb絵文字

この記事へのトラックバック

この記事にトラックバックする:

askeet day six:security and form validation の解説 HOME askeet day four:refactoring の解説

プロフィール

HN:
flyfront
性別:
非公開
自己紹介:
PHPプログラマ。東京でsymfonyな仕事してます。

HNはflyfrontですが、
仕事関係ではr_koike名義を使ってる場合もあります。

Wassr

カレンダー

08 2017/09 10
S M T W T F S
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

最新コメント

[01/02 通りすがり]
[10/18 flyfront]

バーコード

アクセス解析

忍者ブログ [PR]
Template by repe