前回の続き。
ここまではリンクの書き方とrouting.ymlで完結していました。
ここまでは単にURLとルーティングをマッチングさせているだけなのでまあわからないこともないです。
この後突然ルートクラスという単語が登場し、全然意味がわからなくなってしまいます。
個人的には、下記のように一カ所を変更したいと思う度に至る所を修正しなければならない作りが正しいとはとても思えないんですがどうなんですかね。
まずsfRequestRoute。
こちらは通常ルーティングで使われるはずのsfRouteに、リクエストメソッドによる分岐機能を追加したものになります。
同じURLにリクエストが来た場合でも、<a>や<form method="GET">で飛んできた場合はsf_method:[get]に合致し、<form method="POST">で飛んできた場合はsf_method:[post]に合致する、というふうに分岐を行うことができます。
routing.ymlのjob_show_user:url:を変更。
1
2
3
4
5
6
7
|
job_show_user:
url: /job/:company/:location/:id/:position
class: sfRequestRoute
param: { module: job, action: show }
requirements:
id: \d+
sf_method: [get]
|
class: sfRequestRouteとrequirements:sf_method: [get]が増えました。
これで
http://symfony.localhost/frontend_dev.php/job/sensio-labs/paris-france/1/web-developer
というURLに対し、リクエストメソッドがGETである場合のみにjob_show_userにマッチするようになります。
<form method="POST">で来た場合はルートが見つからないためエラーになります。
こちらは比較的わかりやすい。
次にsfDoctrineRoute。
routing.ymlのjob_show_user:url:をsfRequestRouteからsfDoctrineRouteに変更。
1
2
3
4
5
6
7
8
|
job_show_user:
url: /job/:company/:location/:id/:position
class: sfDoctrineRoute
options: { model: JobeetJob, type: object }
param: { module: job, action: show }
requirements:
id: \d+
sf_method: [get]
|
apps/frontend/modules/job/templates/indexSuccess.phpを変更。
url_for(array('sf_route' => 'job_show_user', 'sf_subject' => $job))
class:sfDoctrineRouteでルーティングにsfDoctrineRouteを指定し、model:JobeetJobでルートに関係するモデルクラスを指定し、type:objectでこのルートに関係するオブジェクトを定義します。
何を言ってるんだこいつは?
全く全然さっぱりちっとも意味がわかりませんが、何故かリンクは表示されました。
/frontend_dev.php/job/Sensio+Labs/Paris%2C+France/1/Web+Developer
というようなURLになります。
なんで?
どこがどう繋がってこんなことになってるの?
さらにカスタマイズします。
URLに+とか%2Cといった文字が出てくるのはあまりよろしくないのでURLをslugifyします。slugifyって何よ?
lib/model/doctrine/JobeetJob.class.phpにgetSlug系メソッドを追加。
// lib/model/doctrine/JobeetJob.class.php
1
2
3
4
5
6
7
8
9
|
public function getCompanySlug(){
return Jobeet::slugify($this->getCompany());
}
public function getPositionSlug(){
return Jobeet::slugify($this->getPosition());
}
public function getLocationSlug(){
return Jobeet::slugify($this->getLocation());
}
|
lib/Jobeet.class.phpを作成してチュートリアルからJobeetクラスをコピペ。
// lib/Jobeet.class.php
1
2
3
4
5
6
7
8
9
|
class Jobeet{
static public function slugify($text){
// 文字ではないもしくは数値ではないものすべてを-に置き換える
$text = preg_replace('/\W+/', '-', $text);
// トリムして小文字に変換する
$text = strtolower(trim($text, '-'));
return $text;
}
}
|
routing.ymlのjob_show_user:url:を変更。
url: /job/:company_slug/:location_slug/:id/:position_slug
jobActions::executeShowを変更。
$this->job = $this->getRoute()->getObject();
http://symfony.localhost/frontend_dev.php/job/sensio-labs/paris-france/1/web-developer
リンクが正しくなりました。めでたしめでたし。
JobeetJob::getCompanySlugは何処からどうやって呼ばれてるんだ?
lib/Jobeet.class.phpはいったい何処で此処に置くことを決定しているんだ?
getRouteって何?getObjectって何?
全然わかりません。
なんでリンクするだけのためにこんな馬鹿みたいなことをしないといけないのでしょうか。
あと日本語は文字化けします。
ルートコレクションという機能もあります。
基本的なフォームの閲覧から作成、編集までのひとまとまりのルーティングを纏めてキャッチしてくれます。
apps/frontend/config/routing.ymlに以下を追加します。
1
2
3
|
job:
class: sfDoctrineRouteCollection
options: { model: JobeetJob }
|
なんか色々なルートを纏めて作成できるそうです。
皆さんわかりましたか?
私にはさっぱりわかりません。
最後にデフォルトルートを削除します。
デフォルトルートを削除した場合、定義したルート以外には辿り着けなくなります。
変なURLによるアクセスを簡単に排除することが出来ます。
逆に、今後モジュールを追加したとしても、routing.ymlを編集しない限りアクセスできなくなります。
Symfonyの記事一覧