前回の続き。
現状では
http://symfony.localhost/frontend_dev.php/job/1/edit
というURLで誰でも求人情報を編集できてしまいます。
これでは求人改竄し放題ですので、投稿者以外編集できないように保護しましょう。
方針としては、初回投稿時にランダムな文字列を作成しjobeet_job.tokenに保存、その文字列を知らないとエディットできない、というふうにします。
チュートリアルとはちょっと違った順番で行ってみます。
基本を修めず創作料理は核煮の第一歩ですが気にしない。
まずルーティングを変更。
今のままの/job/1/editでは到達できないように、ルーティングに引っかかるカラムを変更します。
apps/frontend/config/routing.yml
ルーティングはデフォルトではJobeetJob.idに結びつけられていますが、options:column:を追加することで任意のカラムに変更することができます。
今回はJobeetJob.tokenに結びつけました。
従って、
http://symfony.localhost/frontend_dev.php/job/job_sensio_labs/edit
といったURLでエディット画面に行くことが出来るようになります。
さて、この状態でサイトトップから求人詳細を見ようとするとサーバエラーになります。
ルーティングが変更になったのでエディット画面へのリンクがtokenを必要とすることになったのに、テンプレに
という行があるのでURLを解決できないのです。
このリンクを修正します。
apps/frontend/modules/job/templates/showSuccess.php
エディット画面へのリンクが正しく表示されるようになりました。
まあ、そもそもこのリンクは今後表示してはいけないのですが。
さらに引数を直接与えるのではなく、url_for()を使用して解決することも出来ます。
apps/frontend/modules/job/templates/showSuccess.php
ルーティングの設定によりトークンでアクセスできるようになりましたが、現在トークンはユーザが任意に登録できるようになっています。
ここでaaaaaとか入れられると困りますのでフォームに出さないようにし、トークンは自動生成するようにします。
JobeetJob::save()にトークン自動発行ルーチンを挿入。
lib/model/doctrine/JobeetJob.class.php
フォームからトークン入力欄を削除。
lib/form/doctrine/JobeetJobForm.class.php
これで初回登録時に自動で40桁のトークンが発行されるようになりました。
今後投稿したデータの編集を行う際は、
http://symfony.localhost/frontend_dev.php/job/ef59db48055f6cdde9819f3121d9e267f00f8f65/edit
というような第三者にはわからないアドレスを使用することになります。
どうでもいいですが、トークンに無理矢理日本語を入れると今後一切エディット不能になります。
現在求人情報は、
http://symfony.localhost/frontend_dev.php/job/n-a/n-a/1/n-a
という形式でルーティングのjob_show_user:に引っかかるタイプ、
http://symfony.localhost/frontend_dev.php/job/ef59db48055f6cdde9819f3121d9e267f00f8f65
という形式でjob:に引っかかるタイプの2種類のURLから閲覧することが出来ます。
前者の人は閲覧専用とし、エディット画面へのリンクは表示させたくありません。
一方、後者の人には編集、削除を行わせる必要があります。
テンプレートを修正します。
apps/frontend/modules/job/templates/showSuccess.php
リクエストパラメータにtokenがあって、それがjobeet_job.tokenと等しければエディット画面へのリンクを表示します。
元あったエディット画面へのリンクは削除しましょう。
さて、エディット以外にも削除やなにやら色々行いたいので部品化し、admin専用のメニューテンプレートを作成します。
apps/frontend/modules/job/templates/showSuccess.php
インクルードされる中身を作成します。
apps/frontend/modules/job/templates/_admin.php
作成した_adminパーシャルには、$job->expiresSoon()や$job->getDaysBeforeExpires()といったメソッドが書かれています。
ここらへんのメソッドは存在しないのでモデルに実装を追加します。
単に日付の比較などを行っているだけなのでテンプレートで行っても問題無いと言えば無いですが。
lib/model/doctrine/JobeetJob.class.php
さて、公開されているか否かのチェックに$job->getIsActivated()を使用していますが、jobeet_job.is_activatedは本日の最初にフォームから削除しました。
すなわち、現状$job->getIsActivated()は常にfalseです。
本来この求人は公開されていない状態になっているということです。
ということで求人を公開するアクションを作成しましょう。
まずはルーティングを編集。
apps/frontend/config/routing.yml
job:options:object_actionsを追加しました。
>object_actionsは与えられたオブジェクト用の追加アクションの配列をとります。
意味がわかりません。
PUTにすればobject_actions:publishになるってことなんだろうか?
テンプレートのPublishへのリンクを変更します。
apps/frontend/modules/job/templates/_admin.php
リンク先のPublishアクションを作成します。
apps/frontend/modules/job/actions/actions.class.php
lib/model/doctrine/JobeetJob.class.php
以上で求人フォームの投稿→公開が完成しました。
ただ問題点として、現在はjobeet_job.is_activatedがfalseの求人も全部公開されています。
非公開な求人は表示しないようにしましょう。
単に検索条件をひとつ追加するだけです。
lib/model/doctrine/JobeetJobTable.class.php
jobeet_job.is_activatedが立っていない求人は全部消えました。
めでたし。
現状では
http://symfony.localhost/frontend_dev.php/job/1/edit
というURLで誰でも求人情報を編集できてしまいます。
これでは求人改竄し放題ですので、投稿者以外編集できないように保護しましょう。
方針としては、初回投稿時にランダムな文字列を作成しjobeet_job.tokenに保存、その文字列を知らないとエディットできない、というふうにします。
チュートリアルとはちょっと違った順番で行ってみます。
基本を修めず創作料理は核煮の第一歩ですが気にしない。
まずルーティングを変更。
今のままの/job/1/editでは到達できないように、ルーティングに引っかかるカラムを変更します。
apps/frontend/config/routing.yml
1
2
3
|
class: sfDoctrineRouteCollection
options: { model: JobeetJob, column: token }
requirements: { token: \w+ }
|
ルーティングはデフォルトではJobeetJob.idに結びつけられていますが、options:column:を追加することで任意のカラムに変更することができます。
今回はJobeetJob.tokenに結びつけました。
従って、
http://symfony.localhost/frontend_dev.php/job/job_sensio_labs/edit
といったURLでエディット画面に行くことが出来るようになります。
さて、この状態でサイトトップから求人詳細を見ようとするとサーバエラーになります。
ルーティングが変更になったのでエディット画面へのリンクがtokenを必要とすることになったのに、テンプレに
1
|
<a href=" echo url_for('job/edit?id='.$job->getId()) ">Edit</a>
|
このリンクを修正します。
apps/frontend/modules/job/templates/showSuccess.php
1
|
<a href=" echo url_for('job/edit?token='.$job->getToken()) ">Edit</a>
|
エディット画面へのリンクが正しく表示されるようになりました。
まあ、そもそもこのリンクは今後表示してはいけないのですが。
さらに引数を直接与えるのではなく、url_for()を使用して解決することも出来ます。
apps/frontend/modules/job/templates/showSuccess.php
1
|
<a href=" echo url_for('job_edit', $job) ">Edit</a>
|
ルーティングの設定によりトークンでアクセスできるようになりましたが、現在トークンはユーザが任意に登録できるようになっています。
ここでaaaaaとか入れられると困りますのでフォームに出さないようにし、トークンは自動生成するようにします。
JobeetJob::save()にトークン自動発行ルーチンを挿入。
lib/model/doctrine/JobeetJob.class.php
1
2
3
4
5
|
//トークンが無ければ自動生成
if (!$this->getToken()){
$this->setToken(sha1($this->getEmail().rand(11111, 99999)));
}
|
フォームからトークン入力欄を削除。
lib/form/doctrine/JobeetJobForm.class.php
1
2
3
4
5
6
|
unset(
$this['created_at'], $this['updated_at'],
$this['expires_at'], $this['is_activated']
,$this['token']
);
|
これで初回登録時に自動で40桁のトークンが発行されるようになりました。
今後投稿したデータの編集を行う際は、
http://symfony.localhost/frontend_dev.php/job/ef59db48055f6cdde9819f3121d9e267f00f8f65/edit
というような第三者にはわからないアドレスを使用することになります。
どうでもいいですが、トークンに無理矢理日本語を入れると今後一切エディット不能になります。
現在求人情報は、
http://symfony.localhost/frontend_dev.php/job/n-a/n-a/1/n-a
という形式でルーティングのjob_show_user:に引っかかるタイプ、
http://symfony.localhost/frontend_dev.php/job/ef59db48055f6cdde9819f3121d9e267f00f8f65
という形式でjob:に引っかかるタイプの2種類のURLから閲覧することが出来ます。
前者の人は閲覧専用とし、エディット画面へのリンクは表示させたくありません。
一方、後者の人には編集、削除を行わせる必要があります。
テンプレートを修正します。
apps/frontend/modules/job/templates/showSuccess.php
1
2
3
|
if ($sf_request->getParameter('token') == $job->getToken()):
<a href=" echo url_for('job_edit', $job) ">Edit</a>
endif;
|
リクエストパラメータにtokenがあって、それがjobeet_job.tokenと等しければエディット画面へのリンクを表示します。
元あったエディット画面へのリンクは削除しましょう。
さて、エディット以外にも削除やなにやら色々行いたいので部品化し、admin専用のメニューテンプレートを作成します。
apps/frontend/modules/job/templates/showSuccess.php
1
2
3
|
if ($sf_request->getParameter('token') == $job->getToken()):
include_partial('job/admin', array('job' => $job)) endif;
|
インクルードされる中身を作成します。
apps/frontend/modules/job/templates/_admin.php
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
31
|
<div id="job_actions">
<h3>Admin</h3>
<ul>
if (!$job->getIsActivated()):
<li> echo link_to('Edit', 'job_edit', $job) </li>
<li> echo link_to('Publish', 'job_edit', $job) </li>
endif;
<li> echo link_to('Delete', 'job_delete', $job,
array('method' => 'delete', 'confirm' => 'Are you sure?')) </li>
if ($job->getIsActivated()):
<li $job->expiresSoon() and print ' class="expires_soon"' >
if ($job->isExpired()):
Expired
else:
Expires in <strong>
echo $job->getDaysBeforeExpires() </strong> days
endif;
if ($job->expiresSoon()):
- <a href="">Extend</a> for another
echo sfConfig::get('app_active_days') days
endif;
</li>
else:
<li>
[Bookmark this echo link_to('URL', 'job_show', $job, true) to manage this job in the future.]
</li>
endif;
</ul>
</div>
|
作成した_adminパーシャルには、$job->expiresSoon()や$job->getDaysBeforeExpires()といったメソッドが書かれています。
ここらへんのメソッドは存在しないのでモデルに実装を追加します。
単に日付の比較などを行っているだけなのでテンプレートで行っても問題無いと言えば無いですが。
lib/model/doctrine/JobeetJob.class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
/*
* テンプレートで利用するショートカット関数
* */
//JobeetJob.typeを取得
public function getTypeName(){
$types = Doctrine::getTable('JobeetJob')->getTypes();
return $this->getType() ? $types[$this->getType()] : '';
}
//期限切れであればtrue
public function isExpired(){
return $this->getDaysBeforeExpires() < 0;
}
//期限切れ間近であればtrue
public function expiresSoon(){
return $this->getDaysBeforeExpires() < 5;
}
//期限切れまでの日数
public function getDaysBeforeExpires(){
return floor((strtotime($this->getExpiresAt()) - time()) / 86400);
}
}
|
さて、公開されているか否かのチェックに$job->getIsActivated()を使用していますが、jobeet_job.is_activatedは本日の最初にフォームから削除しました。
すなわち、現状$job->getIsActivated()は常にfalseです。
本来この求人は公開されていない状態になっているということです。
ということで求人を公開するアクションを作成しましょう。
まずはルーティングを編集。
apps/frontend/config/routing.yml
1
2
3
4
5
6
7
8
|
job:
class: sfDoctrineRouteCollection
options:
model: JobeetJob
column: token
object_actions: { publish: put }
requirements:
token: \w+
|
job:options:object_actionsを追加しました。
>object_actionsは与えられたオブジェクト用の追加アクションの配列をとります。
意味がわかりません。
PUTにすればobject_actions:publishになるってことなんだろうか?
テンプレートのPublishへのリンクを変更します。
apps/frontend/modules/job/templates/_admin.php
1
2
|
<li> echo link_to('Publish', 'job_publish', $job,
array('method' => 'put')) </li>
|
リンク先のPublishアクションを作成します。
apps/frontend/modules/job/actions/actions.class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/*
* フォーム、Publishリンクを押したら公開状態に
*/
public function executePublish(sfWebRequest $request){
$request->checkCSRFProtection();
$job = $this->getRoute()->getObject();
$job->publish();
$this->getUser()->setFlash('notice',
sprintf('Your job is now online for %s days.',
sfConfig::get('app_active_days')));
$this->redirect($this->generateUrl('job_show_user', $job));
}
|
lib/model/doctrine/JobeetJob.class.php
1
2
3
4
5
6
|
//jobeet_job.is_activateをtrueに
public function publish(){
$this->setIsActivated(true);
$this->save();
}
|
以上で求人フォームの投稿→公開が完成しました。
ただ問題点として、現在はjobeet_job.is_activatedがfalseの求人も全部公開されています。
非公開な求人は表示しないようにしましょう。
単に検索条件をひとつ追加するだけです。
lib/model/doctrine/JobeetJobTable.class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/*
* 検索内容に現在有効なJobeetJobを追加する
*/
public function addActiveJobsQuery(Doctrine_Query $q = null){
if (is_null($q)){
$q = Doctrine_Query::create()
->from('JobeetJob j');
}
$alias = $q->getRootAlias();
$q->andWhere($alias . '.expires_at > NOW()')
->addOrderBy($alias . '.created_at DESC')
->andWhere($alias . '.is_activated = ?', 1);
return $q;
}
|
jobeet_job.is_activatedが立っていない求人は全部消えました。
めでたし。
PR
トラックバック
トラックバックURL: