四面楚歌。
虐めかよ!
ソラトロボはまさかの超古臭い王道タイプのARPGでした。
大作大作連呼されると、どうしても通れる道が通れないことが気になってしまう。
とりあえずあれだ、エルが男だったことに大ショック。
いや、まだわからんぞ、夢は諦めない。
Fallout: New Vegas
先月あれだけ買っておきながらなんですが、今秋一番の本命がこちらです。
今のところFallout3の大型DLCって感覚ではっきりいってまったくそのままです。
せめてヘアピンがMiscに入ってるところくらいは変えてほしかった。
間違って売っちゃうんだよね。
まあFallout3が楽しめた人は本作も間違いなく楽しめるはずなのでつべこべ言わず買え。
ファンダメンタマウス 大間 九郎
☆☆☆
個人的に大当たりだった伝説兄妹ですら特別賞に甘んじる第一回『このライトノベルがすごい』大賞を獲得するほどのものだからどれだけすごいのだろうと期待して買ってみたランジーン×コードが完全に期待外れだったのであまり期待せずに読んだ僕たちは監視されているがまあ期待した程度には読めたので多少期待して読んだが微妙。
登場キャラがどいつもウザい感じを醸し出していてどうにもこうにも。
あと最後の解決編がありえないくらい適当な終わり方でがっくりした。
相当人を選ぶ作品だと思うが、私は文体は気にならなかったがそれ以外が気に合わなかった。
プレイスファジストマネー 片山 まさゆき
☆☆☆
麻雀で負けたら死ぬと公言したら周りに狙い撃ちされたのを返り討ちにしていたら立身出世とまあ、夢のある話。
まあ対戦相手にうっかり傀が混ざってたら即殺されてたレベル。
満潮!ツモクラテス1 片山 まさゆき
☆☆
いや、この主人公二人とも嫌いなんですよ。
波溜とミーコが出るから仕方なく買いますけどね。
そういえば実は賭け麻雀って違法らしいですよ。びっくりですね。
ファミ通Xbox360 2010年 12月号
相変わらず字が小さい。
千代丸×高橋名人スペシャル対談があったりなど、毎回制作者インタビューも豊富で読み応えがあります。
付録はFalloutNV、Fable3、RDR、Vankishの簡易攻略でした。
4本中3本持ってるってどうなの。
おかげで公式でFable3のネタバレ喰らってしまった。
これって前は違ったと思うんだがどうだったっけ?
ってことを公式フォーラムに書き込もうと思ったらフォーラムがサーバエラーの異常事態。
ってことでメールでカスタマーサポートに問い合わせようと思ったらメールの宛先に「電話」
色々と大丈夫か。
あと魚拓取ろうとしたらXdebugのエラーが出たんだがお前も大丈夫か?
2010/11/05の実績
Fallout: New Vegas
Ain't That a Kick in the Head 10
"Ain't That a Kick in the Head"を完了
2010/11/04の実績
Fable III
お宝くんをやっつけろ! 10
チェスでとある箱を打ち負かしました。どうひいき目に見ても、大変邪悪な箱でした
2010/11/03の実績
Fable III
人気投票 15
人をひきつける人柄のおかげか、たくさんの友人ができました。そう、多すぎるくらいたくさん
穴掘り屋 15
宝探しがいつも上手くいくとは限りません。ツメのあいだに入り込んだ土がその事実を物語っています
闇の聖堂 10
闇の聖堂がリニューアル オープンしました。また訪れると、新しい発見が待ってるかも
大魔導師 20
魔法に関してあなたにわからないことなどありません。あるとしたら、それはきっとあなたのかけた魔法のせい
楽園に最も近い島 10
あなたのおかげで、近代社会のしがらみから遠く離れた地に、豊かな楽園が生まれました
大爆発 10
嘆きの森の大砲で 2,000 ポイントを記録しました。ジャミー一等兵も誇らしげです
大物の器 50
財産を不動産につぎ込みました。この世界に窓税がなくてよかったですね
血が出て倒せぬものはない 20
まさに一騎当千! あなたこそ真の殺戮機械です
メダル オブ オナー
シングルプレイ:Have a Good One 15
デュースのミッションを全てクリアした
シングルプレイ:Friends From Afar 15
Friends From Afarをクリア
シングルプレイ:Like a Surgeon 10
敵の身体のすべての部位を撃った
シングルプレイ:Bad Guy Jamboree 15
Gunfightersをクリア
シングルプレイ:Full Battle Rattle 15
Belly of the Beastをクリア
2010/11/02の実績
Fable III
幽霊兄弟 10
死んでも兄弟ゲンカをやめない 2 人ですが、ひとまずは母親の元に戻ることができました
俺の嫁 ~あなただけの花嫁~
初めてのデート 50
初めてのデート……
恋人ができた 50
理想の恋人ができました
2010/11/01の実績
Fable III
ニワトリ参上 10
支配者たるものの真の貫録とは、こういうものです。羽毛がなくちゃ始まりません
世界を統べる者 80
革命を先導し、王の座を手に入れました。名君となるか、暴君となるか? すべては歴史が語ってくれます
2010/10/31の実績
Fable III
遠き友 20
オーロラの民を説得し、味方につけることに成功しました。今こそ革命の時です!
栄光と銃声 20
あなたにとっては、トリガーも命も軽すぎたようです
レジスタンス 50
あなたには、バウワーストーンの人々がついています。さあ、今こそ兄に立ち向かいましょう!
魔術師の逆襲 20
彼らは笑った。オタクだ、マヌケだ、ヒゲづらだと。そんな奴らを葬って何が悪いもんですか
チュートリアルには全く載っていない問題点を修正します。
チュートリアル通りに投稿フォームを作成し、日本語で記事を投稿した場合、以下のNoticeが発生します。
>Notice: iconv() [function.iconv]: Detected an illegal character in input string in symfony/lib/Jobeet.class.php on line 17
何処かというとslugifyやってるこの行です。
/lib/Jobeet.class.php
1
2
|
$text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
|
http://jp2.php.net/manual/ja/function.iconv.php
>文字列 //TRANSLIT を out_charset に追加すると、翻字機能が有効になります。これは、指定された文字集合で 表せない文字を、見た目の似ている別の文字に置き換える機能です。 文字列 //IGNORE を追加すると、指定された文字集合で 表せない文字は黙って切り捨てられます。 それ以外の場合は、str の中に変換できない文字が 出現した時点で変換が打ち切られ、E_NOTICE が発生します。
日本語をus-asciiに翻字できないよ、ということです。
日本語記事が投稿できないというのは非常に問題ですが、翻字しなければいいだけなので単純に//IGNOREを追加すれば解決します。
/lib/Jobeet.class.php
1
2
|
$text = iconv('utf-8', 'us-ascii//TRANSLIT//IGNORE', $text);
|
問題点として、リンクのURLから日本語が一切消えて無くなってしまいますが、まあ日本語URLとか面倒なので消えてもいいや。
…あれ?
見た目をわかりやすくするためのURL変換だった筈なんだがその理念は何処行った?
そんな理念最初から無かったということで一つ。
http://www.4gamer.net/games/084/G008467/20101029004/
カプコン稲船氏へのインタビュー記事を読んだグレフ丸山社長のつぶやき
http://togetter.com/li/64098
私の支援出来ることはせいぜい買い支えることくらいです。
車輪の国、向日葵の少女
毛糸のカービィ
俺の嫁 ~あなただけの花嫁~
ラジルギノアMASSIVE
Civilization4
スーパーマリオコレクション
メダルオブオナー
SIMLEDS THE推理
Fable3
HALO Reach
デッドライジング2
レッド・デッド・リデンプション
ソラトロボ
10月に買い支えたソフト。
絶対やる暇ねえよこんなの!
誰か時間くれ。
Fable3
のっけからとんでもない選択肢を突き付けてくれるオープンワールドRPG。
日本製ならそこでなんらかの回避手段があったりするのが普通なんだろうけど、本作はそんな要素もなく容赦ない展開でいきなり心が折れるかと思った。
通りがかりにストーリーと絡まないモブ同士が会話してたり歌ってたりと非常に細かい部分までよくできてます。
ただ実績の進行状況見てると数時間しかプレイしてないのにメインストーリーが既に半分くらい行ってるような気がして気になる。
好感度上げがやたら面倒になったのも少々いただけない。
親密イベントはともかく、好感度自体は2みたいに通りで踊ってればいいふうにしてほしかった。
また、できるかぎりステータスやHP等の情報を廃したいという開発の思想はわからないでもないですが、おかげでどれだけダメージを受けてるのかさっぱりわからないのは困る。
魔導物語であればまだ台詞でわかるのですが、本作はショートカットメニューが赤くなるだけだしな。
あとメニュー画面がないので所有しているアイテムとかどうやって確認するのかわからないんですが。
とりあえず面白くないということは全く無いんだが、開発の方向性が私の好みとはかなり違う方向に向かっていってしまっているかんじです。
ラジルギノアMASSIVE
ポップな画面に電波な台詞。
ローディング画面とか全然意味がわからないんですがどうすんだこれ。
戦闘中で忙しいというのに全く関係ない会話とかが入ってきた日にはどうしたものやら。
ゲーム自体はまだあんまりやってないのだが、突っ込んでアブゾネット開いて無敵を維持するゲームということでいいのかな?
俺の嫁 ~あなただけの花嫁~
車輪の国、向日葵の少女
メモオフ、WLOと未プレイソフトがたまってるのにどうすんだ!
ソラトロボ
正直全く眼中になかったのですが、うっかりこのエントリを見てしまったからには買わないわけにはいかないだろう。
販売がバンナムなだけに罠が待っているかもしれませんが(不完全版的な意味で)、あるかどうかもわからない未来のために今を疎かにするのは愚かと言えましょう。
未だにイヅナがクリアできてないんでプレイはその後になる予定ですが。
Fable III
姫、今お助けします! 10
ボール紙でできた人形を救い出し、ゲームの世界の奥深さを体験しました
ヒゲ パワー 20
スウィフト少佐とその部下が味方に加わりました。この頼もしいヒゲづらがついていれば、怖いものなしです!
コンボの使い手 5
スペルを合成した英雄なんて、史上初ではないでしょうか? 素晴らしい破壊力です
エアー シューティング 10
敵をカッコよく倒してこそ英雄! 宙に浮いた敵を見事仕留めました
2010/10/29の実績
Fable III
新たな一歩 20
兄に対抗するため、抵抗組織結成の第一歩を踏み出しました
悲劇で喜劇な古典劇 10
文学作品の調査を行い、世にふたつとない演劇を発掘しました。ヤレヤレです
彼は彼女で彼女は彼で 5
英雄という人種に一般常識を押しつけようなんて大間違い。だいたい「常識」って誰が決めるんですか?
バトル クレイジー 10
接近戦闘、遠隔戦闘、スペルのすべてを用いて敵を倒しました。結局、何が得意なんですか?
2010/10/28の実績
ラジルギノア MASSIVE
Point item 400 30
得点アイテムを400個獲得。
Stage6 Boss destroy 30
アーケードモードかエキスパンドモードで6面ボスを撃破する。
Point item 200 10
得点アイテムを200個獲得。
Stage4 Boss destroy 20
アーケードモードかエキスパンドモードで4面ボスを撃破する。
Full power 5
マッシブモード以外でショットを最大レベルまでアップ。
Stage2 Boss destroy 10
アーケードモードかエキスパンドモードで2面ボスを撃破する。
Cuts too hard 5
パワーアップアイテムを切り過ぎて得点アイテムに変化。
x16 10
アブゾネットの倍率を16倍まで上昇。
Power slash 5
タメ切りで敵を撃破する。
First step 10
チュートリアルを最後まで見る。
Fable III
ギルドの紋章 10
あなたが触れると、ギルドの紋章が反応を示します。あなたこそ英雄です! え、当たり前?
自己紹介 10
少なくとも 20 人のアルビオン住人が、英雄に触られたと言っています。変な意味じゃない… ですよね?
手に手をとって 5
手をつなぎました。つながりを求めるのに、これ以上の方法はありません
2010/10/26の実績
智代アフター
歴戦の証 60
パーティの誰かがLv.99に到達しました
Alan Wake
句読点なし 50
特別編エピソード「小説家」を一気にクリアした
メダル オブ オナー
シングルプレイ:Unexpected Guests 15
Dorothy's a Bitchをクリア
2010/10/25の実績
メダル オブ オナー
シングルプレイ:Develop the Situation 15
Running with Wolves…をクリア
シングルプレイ:Welcome to the TOC 15
Breaking Bagramをクリア
シングルプレイ:The Sledgehammer 10
1発の2000lb爆弾で、2両の車両を破壊した
シングルプレイ:The Scalpel 15
ナイフで20人の敵を倒した
現状では
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が立っていない求人は全部消えました。
めでたし。
先日受験した、PHP技術者認定初級試験ベータ試験の受験レポートが届きました。
まwさwかwのw不w合w格wwwwwww
いやいやいやいやwwwwwwwwwww
しかも平均値からも中央値からも最頻値からも外れた底辺レベルです。
曲がりなりにも現役PHP開発者なんですが。
まあ最近はAndroidとiPhoneばっかりやらされてますが、でも間違っても落ちるとは思っていなかったというか、落ちるという選択肢が存在するということすら考えていませんでしたよ。
私の開発者としての資質に赤信号が灯ったような気がしないでもないですが見なかったことにしましょう。
装飾を行いましょう。
まず、デフォルトではスキーマのカラム名がそのまま入力項目名として表示され、「Category id」や「Is public」等になっています。
ヴィジェットのsetLabels()メソッドで入力項目名を変更することができます。
JobeetJobForm.class.phpに追加。
lib/form/doctrine/JobeetJobForm.class.php
1
2
3
4
5
6
|
$this->widgetSchema->setLabels(array(
'category_id' => 'Category',
'is_public' => 'Public?',
'how_to_apply' => 'How to apply?',
));
|
>それぞれのフィールドに対して、symfonyは~ラベル|フォームラベル~(<label>タグに使われる)を自動的に生成します。
>ラベルはlabelオプションで変更できます。
チュートリアルだとこんなふうにわかりにくい表記がされているせいで、<label for="**">を変更するのか?とも読めてしまうのですが、単に左側の文言を変更するだけです。
これまで'Category id'と表示されていてIDなのに<select>?とか思わされていたわけですが、これで左辺の分類が'Category'となってわかりやすくなりました。
次に入力欄に説明を付加します。
setHelp()メソッドが用意されています。
lib/form/doctrine/JobeetJobForm.class.php
1
2
3
|
$this->widgetSchema->setHelp('is_public',
'Whether the job can also be published on affiliate websites or not.');
|
これまで'Public?'とだけ表示されていた謎のチェックボックスに、ヘルプメッセージが表示されるようになります。
setLabels()とsetHelp()ってなんか不平等だな、setLabel()やsetHelps()は無いのか、といえばどちらも有ります。
1
2
3
4
5
6
7
|
$this->widgetSchema->setHelps(array(
'category_id' => 'カテゴリを選択',
'is_public' => '公開するのであればチェック',
'how_to_apply' => '申込方法を記入',
));
$this->widgetSchema->setLabel('is_public', '公開フラグ');
|
フォームのテンプレートを修正します。
ここら辺は3日目に作ったままで中がどうなってるかとか全然覚えてねえよ。
apps/frontend/modules/job/templates/newSuccess.php
1
2
3
|
use_stylesheet('job.css')
<h1>Post a Job</h1>
include_partial('form', array('form' => $form))
|
下2行は元々入っているはずなので、CSSを付け足します。
リロードするとスタイルシート読み込みの行が増えているのがわかります。
フォームテンプレートはinclude_partial()されている中の_form.phpに書かれています。
このフォームテンプレート部分だけ分けることにより、新規登録画面とエディット画面でフォームを共用できるようになっているのですが後述。
現在のテンプレートは自動生成と5日目による修正を受けてこんなふうになっています。
apps/frontend/modules/job/templates/_form.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
32
33
|
include_stylesheets_for_form($form) include_javascripts_for_form($form)
<form action="
echo url_for('job/'.($form->getObject()->isNew() ? 'create' : 'update')
.(!$form->getObject()->isNew() ? '?id='.$form->getObject()->getId() : ''))
" method="post"
$form->isMultipart() and print 'enctype="multipart/form-data" '
>
if (!$form->getObject()->isNew()):
<input type="hidden" name="sf_method" value="put" />
endif;
<table>
<tfoot>
<tr>
<td colspan="2">
<a href=" echo url_for('job/index') ">Cancel</a>
if (!$form->getObject()->isNew()):
echo link_to('Delete',
'job/delete?id='.$form->getObject()->getId()
,array('method' => 'delete', 'confirm' => 'Are you sure?'))
endif;
<input type="submit" value="Save" />
</td>
</tr>
</tfoot>
<tbody>
echo $form
</tbody>
</table>
</form>
|
チュートリアルのフォームテンプレートでさくっと上書きします。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
include_stylesheets_for_form($form) include_javascripts_for_form($form)
echo form_tag_for($form, '@job')
<table id="job_form">
<tfoot>
<tr>
<td colspan="2">
<input type="submit" value="Preview your job" />
</td>
</tr>
</tfoot>
<tbody>
echo $form
</tbody>
</table>
</form>
|
ずいぶんわかりやすくなりました。
まあ面倒な削除ボタンなどを削除したせいではありますが。
あと、Previewとか書いてあるのにボタンを押したら何故か即座に登録されます。
form_tag_for()は自動的にフォームタグを作成してくれる便利な関数です。
@jobなのでルーティングのjob:に対応付けけられますが、何故'job/new'や'job/edit'ではなく'job/create'や'job/update'に正しくルーティングされるのかはよくわかりません。
あとひとつ問題があって、対となる閉じタグを作成する関数がありません。
勿論機能的には明らかに不要ですが、IDE使うと<form>タグが足りないってエラーが出っぱなしになって気持ち悪いんだよね。
include_stylesheets_for_form()とinclude_javascripts_for_form()は現時点では何の役に立っているのかさっぱりわかりません。
削除しても出力が全く変化しないし、ググってもチュートリアルとdiffのコピペしか見つからず、使用法が全く見あたらねえ。
echo $formとするとフォームの中身を全部纏めて勝手に<th><td>タグ付きで出力されますが、テーブルとか使いたくない、<ul><li>でやりたいんだ、みたいな場合に備えて中身を個別に出力する方法もあります。
囲み記事にも書いてありますが、
1
2
|
print($form['company']->renderLabel());
|
といった書き方ができます。
まあ今回は不要なのでとりあえずパス。
Symfonyにおけるフォームの流れは以下のようになっています。
・新規登録
new→(create→processForm→)edit
・更新
edit→(update→processForm→)edit
processFormはcreateやupdateの内部で呼ばれて投稿された値を保存しているだけなので、表には出てきません。
権限もprotectedになっています。
またprocessFormは保存に成功したらeditにリダイレクトするようになっているので、createやupdateは見えないようになっています。
アクションには3日目の最後あたりで作成したexecuteEdit()やらexecuteUpdate()が存在していますが、記事を取得するために
Doctrine::getTable('JobeetJob')->find($request->getParameter('id')
的なことを行っています。
5日目にルーティングを設定したので、
$this->getRoute()->getObject();
で記事を取得できるようになりました。
よくわかりませんが。
わざわざ引数からテーブルを探してこなくても、ルーティングから内容を取得できるようになったのでそちらを使用するようにします。
jobActions::executeNew()とjobActions::processForm()以外は中身が少しづつ違うので、チュートリアルに従って修正。
apps/frontend/modules/job/actions/actions.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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
/*
* フォーム新規作成
*/
public function executeNew(sfWebRequest $request){
$this->form = new JobeetJobForm();
}
/*
* フォームの作成画面からセーブ
*/
public function executeCreate(sfWebRequest $request){
$this->form = new JobeetJobForm();
$this->processForm($request, $this->form);
//失敗したら新規作成画面に戻る
$this->setTemplate('new');
}
/*
* フォームのエディット
*/
public function executeEdit(sfWebRequest $request){
$this->form = new JobeetJobForm($this->getRoute()->getObject());
}
/*
* フォームのエディット画面からセーブ
*/
public function executeUpdate(sfWebRequest $request){
$this->form = new JobeetJobForm($this->getRoute()->getObject());
$this->processForm($request, $this->form);
//失敗したらエディット画面に戻る
$this->setTemplate('edit');
}
/*
* 削除
*/
public function executeDelete(sfWebRequest $request){
$request->checkCSRFProtection();
$job = $this->getRoute()->getObject();
$job->delete();
$this->redirect('job/index');
}
/*
* フォーム、投稿された値を保存する
*/
protected function processForm(sfWebRequest $request, sfForm $form){
//値をバインド
$form->bind(
$request->getParameter($form->getName())
,$request->getFiles($form->getName())
);
//バインドに成功したら
if ($form->isValid()){
//セーブしてエディット画面に移動
$job = $form->save();
$this->redirect($this->generateUrl('job_show', $job));
}
}
|
jobActions::processForm()は、まず投稿された値をJobeetJobFormクラスにバインドし、その後$form->isValidでバリデータを実行しています。
バリデートに成功したらそのままセーブし、jobActions::executeEdit()にリダイレクトします。
バリデートに失敗したらそのまま呼び出し元のメソッドに戻り、登録画面やエディット画面に戻ります。
ルーティングから取得した内容をフォームオブジェクトに渡せば、エディット画面のデフォルト値にそのまま表示されます。
入力後にバリデーションで失敗した場合には、入力値がそのまま引き継がれて表示されます。
さらにこの間、エスケープ処理などは全て自動で行ってくれるのでこちら側では一切考慮する必要がありません。
非常に便利ですね。
どのオブジェクトをどのメソッドにどうやって結びつければいいか、がわかればの話ですが。
さっぱりわかりません。
先日、たまたまついうっかりニコニコで「シリーズ未経験者にもお勧め「Civilization4」プレイ講座」なるシリーズを見つけてしまいました。
ご多分に漏れず私も、あと一話だけ病、あと一シリーズだけ病に見事に罹患してしまい、気がついたら毎日の睡眠時間が凄いことに。
結局うp主失踪までを見届ける羽目になりました。
調べてみるとなんと来週ちょうど続編であるCivilization5が発売されるとか。
これは素晴らしい。
ただでさえ来週のスケジュールは凄いことになっているというのにこんな時間泥棒が現れてしまうとは!
だがしかしこれは買うしかない!
来週が楽しみだ!
…あれ?
シヴィライゼーション4 【完全日本語版】デラックスパック
☆☆☆☆☆
貴様は我々の時間を奪ったのだぞ!(+4)
今週実績の更新が全く無かったのは、まあそういうことです。
どこまで時間を盗んでいけば気が済むんだ!
メダル オブ オナー
私が初めてクリアするまでプレイしたFPSが、PS2のメダルオブオナー史上最大の作戦です。
それ以前にもグラボを買ったら何故かおまけでついてきたソルジャーオブフォーチュンとかをプレイしたことはありますが、操作方法がよくわからんとかですぐ投げ出した覚えが。
ノルマンディー上陸作戦の臨場感とかに凄いと思った記憶があります。
というわけで記念すべき作品なのですが、そういうわけでプレイする時間が全く取れそうにありません。
とりあえず第一章まではクリアしましたが画面が暗いよ…
スーパーマリオコレクション スペシャルパック
昔SFCで発売されたスーパーマリオコレクションの移植版です。
ゲーム自体はもはや今さらなものですが、サントラやファミコン当時の企画書などが収録されているメモリアル仕様。
ただサントラは収録曲が中途半端だしブックレットは薄いんだよね…
まあ実売2000円程度なので、VCで買うかわりに持っていてもいいです。
ただせっかくなのだからワールドも入れてほしかった。
とある魔術の禁書目録(インデックス)〈21〉 鎌池 和馬
☆☆☆☆
黒幕黒幕していた右方のフィアンマ、ついにその力を持って世界を変える…!
たった一人で世界を敵に回して平然としている強大
という前ふりで終わってしまう巻。
果たしてどう纏めるのか…!
ていうか、どうやって勝つつもりなのか?
とある魔術の禁書目録(インデックス)〈22〉 鎌池 和馬
☆☆☆
…えー。
もうちょっと戦い方というものがあるだろう。
超電磁砲も一方通行もその他諸々の敵役も何故か上条には本気で攻撃しないんだよね。
フィアンマとか遠くから部屋を崩して埋めるなり壁ごと殴るなり床を崩して墜落させるなり色々あるだろうがと。
その点いい線行ってたのはキャーリサくらいだよね。
ストーリーはともかく戦闘にがっかりですよ、
あと麦野は和解とかありえねーとか美琴は飛び移るくらいしろとか、どうしても結末に持って行くために無理矢理纏めた感があってどうにもこうにも。
Alan Wake
クリエイティブ スペース 25
自らのイマジネーションの真髄に触れた
告白 20
「アリス」の告白を聞いた
疾風 20
竜巻を制限時間内に撃退した
タイアップ 30
『ナイト スプリングス』のゲームを 10 本すべて集めた
鉄の意志 25
自らのうちに潜む悪魔との戦いを制した
メダル オブ オナー
シングルプレイ:First Incision 15
First Inをクリア
シングルプレイ:Smooth Operator 10
人質犯をヘッドショットで始末した