忍者ブログ
[PR]
×

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



2025/11/28 14:48 |
今週の実績 2011/02/06
2011/02/05の実績

End of Eternity

CHAPTER 13をクリア 15
CHAPTER 13をクリアしました。

CHAPTER 12をクリア 15
CHAPTER 12をクリアしました。

2011/02/03の実績

End of Eternity

CHAPTER 11をクリア 15
CHAPTER 11をクリアしました。

2011/02/01の実績

End of Eternity

CHAPTER 10をクリア 15
CHAPTER 10をクリアしました。

2011/01/30の実績

End of Eternity

CHAPTER 9をクリア 15
CHAPTER 9をクリアしました。

ターミナル4連鎖 15
異なるターミナルを4つ接続しました。
PR


2011/02/06 18:50 | Comments(0) | TrackBack() | 実績
ZF1.11 Zend_Tag_Cloud
前回作成したZend_TagをZend_Tag_Cloudに突っ込むとそのまんまタグクラウドになるよ、というわかりやすいクラスです。
ただオプションがわかりにくいです。
とりあえず試してみましょう。
<?php
	//require
		require_once('Zend/Tag/Cloud.php');
		require_once('Zend/Tag/ItemList.php');
	
	//アイテムリスト
		$list = new Zend_Tag_ItemList();
	
	//アイテムをアイテムリストに投入
		$list[] = new Zend_Tag_Item(array('title' => '紅莉栖', 'weight' => 45, 'params' => array('url' => '/kurisu')));
		$list[] = new Zend_Tag_Item(array('title' => 'まゆり', 'weight' => 45, 'params' => array('url' => '/mayuri')));
		$list[] = new Zend_Tag_Item(array('title' => 'るか', 'weight' => 44, 'params' => array('url' => '/rukako')));
		$list[] = new Zend_Tag_Item(array('title' => '鈴羽', 'weight' => 51, 'params' => array('url' => '/suzuha')));
		$list[] = new Zend_Tag_Item(array('title' => 'フェイリス', 'weight' => 43, 'params' => array('url' => '/faris')));
		$list[] = new Zend_Tag_Item(array('title' => '萌郁', 'weight' => 54, 'params' => array('url' => '/moeka')));
		$list[] = new Zend_Tag_Item(array('title' => '綯', 'weight' => 31, 'params' => array('url' => '/nae')));
		$list[] = new Zend_Tag_Item(array('title' => '倫太郎', 'weight' => 59, 'params' => array('url' => '/kyouma')));
		$list[] = new Zend_Tag_Item(array('title' => '至', 'weight' => 98, 'params' => array('url' => '/daru')));
 	
	//タグクラウド
		$cloud = new Zend_Tag_Cloud();
		$cloud->setItemList($list);
		//クラウドデコーダ、タグデコーダの選択
		$cloud->setCloudDecorator('HtmlCloud');
		$cloud->setTagDecorator('HtmlTag');
		//タグを変更
		$cloud->getCloudDecorator()->setHtmlTags(array('div'));
		$cloud->getTagDecorator()->setHtmlTags(array('span'=>array('style'=>'border:1px solid green;')));
		//文字サイズを指定
		$cloud->getTagDecorator()->setMinFontSize(100);
		$cloud->getTagDecorator()->setMaxFontSize(400);
		$cloud->getTagDecorator()->setFontSizeUnit('%');
	
	//表示
		print($cloud);

出力は以下のようになります。

まずZend_Tag_Cloud::setItemList()Zend_Tag_ItemListをそのまま突っ込みますが、それだけで実質完成です。

中身は二段階になっており、CloudDecoratorで全体の表示を、TagDecoratorが個別のアイテム表示を司っています。
Zend_Tag_Cloud::getCloudDecoratorおよびZend_Tag_Cloud::getTagDecoratorで各レンダラを取得でき、それぞれのオプションを変更することが可能です。

Zend_Tag_Cloud::setCloudDecoratorおよびZend_Tag_Cloud::setTagDecoratorでレンダラ自体を変更可能です。
が、デフォルトだとCloudDecoratorにはHtmlCloud、TagDecoratorにはHtmlTagしか用意されていないので、自力でレンダラを作成しないかぎり指定する意味はありません。

Zend_Tag_Cloud::getCloudDecorator()->setHtmlTagsでタグクラウド全体を包むタグ、Zend_Tag_Cloud::getTagDecorator()->setHtmlTagsで各アイテムを包むタグを指定できます。
デフォルトだと<ul><li>になってしまうので、使いやすい<div><span>に変えておくといいかもしれません。
値を配列として突っ込むと、各タグの属性として設定されます。
例では手っ取り早くstyleとかやってますが、普通はclassを指定します。

Zend_Tag_Cloud::getTagDecorator()->setMinFontSizesetMaxFontSizesetFontSizeUnitでタグクラウドの文字サイズを変更できます。
例では最低値が100%、最大値が400%となっています。
setFontSizeUnitには%以外にpx、em、inなんかを設定することができます。

さて、上記例ではZend_Tag_ItemList::spreadWeightValuesが無くなっているわけですが、どうやらこの指定を行ってもZend_Tag_Cloudには反映されないようです。
前回のように級数的なフォントサイズ設定を行おうとしても無視されてしまい、単純な比例になってしまいます。
ちょっとこれはバグ(機能未実装)な気がしますね。
spreadWeightValuesを反映させたい場合、いったんZend_Tag_Item->getParam('weightValue')spreadWeightValuesを反映した値を取得し、再度weightに代入し直すという手順が必要なようです。

ちなみにZend_Tag_Item作成時にparam→urlにURLを突っ込んでいますが、これがあると<a href>の値に反映されます。
無いと<a href="">になってしまってタグクラウドの意味が無くなるので指定しておきましょう。
/から始まると絶対パスで、無しだと現在のURLからの相対パスになります。


以上でとりあえずタグクラウドはできましたが、見た目的には単に<div><span>が並んでいるだけです。
平面的にプロットしたりうにうに動いたりするような時々見かける本格的なタグクラウドはZend_Tag_Cloudだけでは作れません。
正直そっちのほうがライブラリで処理してほしい機能のような気がしますが、そっちはJavaScriptにでも任せるってことで。


2011/02/04 23:54 | Comments(0) | TrackBack() | PHP
ZF1.11 Zend_Tag
http://framework.zend.com/manual/ja/zend.tag.html

日本語が難解すぎていくら読んでもまったく理解できないZend_Tagですが、てっきりニコニコ動画のタグみたいなフォークソノミーかと思っていたら全然違う機能でした。

とりあえず使ってみます。
<?php
//require
	require_once('Zend/Tag/Item.php');
	require_once('Zend/Tag/ItemList.php');

//アイテムリスト
	$list = new Zend_Tag_ItemList();

//アイテムをアイテムリストに投入
	$list[] = new Zend_Tag_Item(array('title' => '紅莉栖', 'weight' => 45));
	$list[] = new Zend_Tag_Item(array('title' => 'まゆり', 'weight' => 45));
	$list[] = new Zend_Tag_Item(array('title' => '鈴羽', 'weight' => 51));
	$list[] = new Zend_Tag_Item(array('title' => 'フェイリス', 'weight' => 43));
	$list[] = new Zend_Tag_Item(array('title' => 'るか', 'weight' => 44));
	$list[] = new Zend_Tag_Item(array('title' => '萌郁', 'weight' => 54));
	$list[] = new Zend_Tag_Item(array('title' => '倫太郎', 'weight' => 59));
	$list[] = new Zend_Tag_Item(array('title' => '至', 'weight' => 98));
	$list[] = new Zend_Tag_Item(array('title' => '綯', 'weight' => 31));
 	
//重みを付ける
	$list->spreadWeightValues(array(1, 2, 4, 8, 16, 32, 64, 128));

//確認
	foreach ($list as $item) {
	    printf("%s: %d\n", $item->getTitle(), $item->getParam('weightValue'));
	}
weightの意味を明らかに取り違えていますが気にしない。

結果は
 紅莉栖: 4 まゆり: 4 鈴羽: 8 フェイリス: 4 るか: 4 萌郁: 8 至: 128 倫太郎: 8 綯: 1
となります。

どういう意味?

動作を確認したところ、どうやら次のような意味のようです。

・weightの最小値をspreadWeightValues()の左端、weightの最大値をspreadWeightValues()の右端にセット
・それぞれのweightを最小値から最大値までの割合でspreadWeightValues()の何れかの値にセット

綯を左端の1、至を右端の128とすると、紅莉栖は左端から3番目の4の位置あたりになり、鈴羽は4番目の8の位置あたりになるということです。

つまり、どうやらタグクラウドのタグという意味だったようです。
時々ある検索件数や重要度が高いものを大きな文字で表示したりするあれです。
使い方としては、単語と検索件数をZend_Tag_Itemに突っ込み、spreadWeightValues()でfont-sizeを段階的に指定するなどといった使い方になるでしょう。


つうか綯と10キロちょいしか違わないとかこいつらおかしい。


2011/01/31 22:50 | Comments(0) | TrackBack() | PHP
買ったものリスト 2011/01/30
新宿ヨドバシ、ソフマップでぎゃる☆がんが売り切れてたんだがどういうことよ。

知り合いにいい本屋を教えてもらった。
品揃えもだが多くの本に試し読みサンプルが用意されているのが素晴らしい。
これで今までのようにうっかりゴミをジャケ買いしてしまう可能性も減りそうだ。
そしてよくわからない作品を店頭買いしてしまう可能性も増えそうだ。

で、ついでにその知り合いお薦めの作品を幾つか購入してみた。
なんというかあれだ、趣味が偏りすぎてるぞ。
私が言うのもなんだが。


東海レトロスペクティブ 野口 芽衣
☆☆☆☆

夏休み、大学の遺跡発掘を手伝うことになった高校生の一夏の思い出を回想する話。
地味で地道で、そして非常に爽やかな青春の一ページです。
教えてもらった中では一番気に入った作品。


はつきあい1 カザマ アヤミ
☆☆☆☆

かっかっか痒いいいいい
ギップルも余裕で悶絶死する超初々しい初+つきあい作品集。
見ていて色々叫びたくなることこの上ありません。
画力は微妙なかんじですが、これ以上上手くなられてもこっちが死んでしまいます。


R-中学生1 ゴトウ ユキコ
☆☆

主に絵がキモい。
あとキャラと話と展開と下ネタと満遍なくキモい。
つうかこれが普通の中学生なのか?
私の中学校にはいくらなんでもこんな奴らいなかったぞ。たぶん。
ちょっとこれは全然合わなかった。


高杉さん家のおべんとう2 柳原 望
高杉さんちのおべんとう3
☆☆☆☆☆

これはこっちからお勧めしといた。
いやあちょっと久留里が可愛すぎて死ぬる。
料理漫画としては相当地味な料理しか作らない、読んでて料理漫画だと言うことをすぐ忘れてしまう作品。
まあ蜂の子とかは無理だけど実用性だけは高かったりします。

しかしハルと呼ばれると和六里と変換されてしまう脳内構造をどうにかしないことには今後読むときに困ってしまいそうだ。


2011/01/30 18:16 | Comments(0) | TrackBack() | 買ったもの
今週の実績 2011/01/30
2011/01/29の実績

End of Eternity

不幸な事故 15
爆発に巻き込まれてキャラクターが死亡しました。

マテリアルクリエイター 15
合成や分解を200回行いました。

トライ・レゾナンス 15
レゾナンス・ポイントが20以上になりました。貯めるの、お好きなんですね。

CHAPTER 8をクリア 15
CHAPTER 8をクリアしました。

サウザンド・スロー 15
投擲武器を1000回投げました。

2011/01/26の実績

End of Eternity

CHAPTER 7をクリア 15
CHAPTER 7をクリアしました。

2011/01/23の実績

End of Eternity

ヘヴィ・ホーネット 15
追撃成功数100回を達成しました。

バーゼル半開放 15
バーゼルを半分、通行可能にしました。

ビッグ・ショット 15
敵に与える一発のダメージが2000を超えました。

CHAPTER 6をクリア 15
CHAPTER 6をクリアしました。


2011/01/30 18:09 | Comments(0) | TrackBack() | 実績
PECL::OAuthでtwitterログイン
Zend_Oauthでリダイレクトを行いつつのTwitterログインtwitterauthでリダイレクト無しでのTwitterログインに成功しました。

何が障害になっていたかというとアクセストークンです。
TiwitterAPIを利用するアプリにはパスワードを知らせず、アクセストークンだけを教えることでパスワード漏洩を防ぐのがoAuthの目的です。
逆にパスワードを登録してもいいから直接投稿したいんだという場合でも直接の投稿はできず、一旦アクセストークンを入手し、それを利用して投稿する必要があります。
そのアクセストークンを入手するためにブラウザを経由してパスワードを入力したのが前々回で、直接アクセストークンを突っ込んだのが前回となります。

では、PHPだけでパスワードから直接アクセストークンを拾ってこれないのかというと、Zend_OauthやZend_Service_Twitterには何故かそういう機能が見あたらないんですよね。

実はPecl::OAuthという拡張モジュールがしれっと対応していたりします。
標準では入っていないのでLinuxであれば"pecl install oauth-beta"、XAMPPであれば"extension=php_oauth.dll"を有効にします。
<?php
	//xAuthオプション
		//アプリ認証
		$oauth_consumer_key		= 'hogehoge';
		$oauth_consumer_secret	= 'fugafuga';
		//ユーザ認証
		$x_auth_username		= '********';
		$x_auth_password		= '********';
		//固定
		$oauth_signature_method	= 'HMAC-SHA1';
		$oauth_version			= '1.0';
		$x_auth_mode			= 'client_auth';
		
		//URL
			$xAuthAccessTokenUrl = 'https://api.twitter.com/oauth/access_token';
			$oAuthStatusesUpdateUrl = 'http://twitter.com/statuses/update.xml';
	
	//xAuth認証
		//変数纏め
			$x_auth_params = array('x_auth_mode'=>$x_auth_mode, 'x_auth_username'=>$x_auth_username, 'x_auth_password'=>$x_auth_password);
		
		//PECL::oAuthを利用してxAuthもできる
			$oauth = new OAuth($oauth_consumer_key, $oauth_consumer_secret, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);
			$oauth->disableSSLChecks();
			
			$oauth->fetch($xAuthAccessTokenUrl, $x_auth_params, OAUTH_HTTP_METHOD_POST);
			$response = $oauth->getLastResponse();
		
	//oAuthトークンを取得
		//URLそのままになってるのでパースが必要
			parse_str($response, $accessTokenInfo);
			$oauthToken       = $accessTokenInfo['oauth_token'];
			$oauthTokenSecret = $accessTokenInfo['oauth_token_secret'];
	
	//投稿
		$status_string = '投稿てすと';
		
		//変数纏め
			$parameters = array('status'=>$status_string);
		
		//認証トークンセット
			$oauth->setToken($oauthToken, $oauthTokenSecret);
		
		//送信実行
			$oauth->fetch($oAuthStatusesUpdateUrl, $parameters, OAUTH_HTTP_METHOD_POST);
			$response = $oauth->getLastResponse();


完成しました。
さっそく実行

Fatal error: Uncaught exception 'OAuthException' with message 'Invalid auth/bad request (got a 401, expected HTTP/1.1 20X or a redirect)'

おうふ!

実はこのプログラムはOAuthではなく、xAuthという認証機構を使用しています。
内容は似たようなものですが、OAuthがアプリ側にパスワードを一切知らせることがないのに対し、xAuthはアプリにパスワードを知らせるという大きな違いがあります。
で、このxAuthはパスワードを扱える性質上、OAuthに比べて使用の敷居が高くなっています。

具体的には、Twitterにメールで許可を取らないとxAuth認証できません。
http://written.4403.biz/archives/2010/03/twitter-xauth.html

めんどくせー。


許可を取りさえすれば、$oauthToken$oauthTokenSecretを突っ込むだけで簡単に投稿ができるようになります。
めでたし。


2011/01/24 21:45 | Comments(0) | TrackBack() | PHP
買ったものリスト 2011/01/23
麻雀漫画の最高傑作バード完全復活!
……あれ?ゴドフリーは?ゴドフリーどこ??
ちゃんと撃たれるんだよね?


ソードアート・オンライン5 ファントム・バレット 川原 礫
☆☆☆☆

6はやってたけど5を書いてなかったのに気がついた。
12でSAO、34でALOのトッププレイヤーに上り詰めた主人公、今度はGGOに参加。
GGOは銃と硝煙が支配する、現実のMMOFPS的なMMORPG。
そしてそこでも入った瞬間世界大会へ出場を決める主人公。
どんだけ規格外だよ。
レベル制じゃないとはいえちょっと主人公がチート性能過ぎる気はしますが、まあそれでも面白いので仕方がない。


史上最強の弟子ケンイチ 38 松江名 俊
史上最強の弟子ケンイチ 39
史上最強の弟子ケンイチ 40
史上最強の弟子ケンイチ 41
☆☆☆☆

一見よくある格闘漫画ですが、本作の特徴は達人と弟子という明確な格差が設定されているところでしょう。
これによって弟子がいくらがんばってもそう簡単に天下一武闘会で優勝したりはできないようになっています。
つうか、あんだけ達人がごろごろしてるのに世間には全く知られていないってのはどういう世界なんだろうか。

てか、ふと思ったが既にタイトルほぼ達成してないか。
まだ美羽には勝てないんじゃろうか。
あと美羽の漢字をひっくり返したら大変なことに。
あと宇喜田が可哀相なのでそろそろどうにかしてあげて。あとカニ頭とか。


2011/01/23 19:23 | Comments(0) | TrackBack() | 買ったもの
今週の実績 2011/01/23
俺の嫁 ~あなただけの花嫁~ 1000/1000達成
FFは全アイテムとミッション☆☆☆☆☆が残ってるけどおなかいっぱいなのでもういいです。

2011/01/22の実績

End of Eternity

シリアル・ショット 15
初めて連続500ヒットを達成しました。ボッコボコにしてやんよ!

クレイジーショッパー 15
服やアクセサリーの購入代金が500,000ルビーになりました。

CHAPTER 5をクリア 15
CHAPTER 5をクリアしました。

KOF SKY STAGE

金勲章の誘惑 20
1ステージで金勲章のみ50個達成!(1Player Game)

2011/01/21の実績

End of Eternity

エクストリームスパイカー 15
撃ち落とし100回を達成しました。

KOF SKY STAGE

なぜボムを使わないっ!? 20
ボムを使わずにステージ5までクリア!(1Player Game)

2011/01/20の実績

智代アフター

ラッキー鷹文 10
ラッキー鷹文に遭遇しました、ほら、ラッキー

2011/01/19の実績

End of Eternity

カスタマイズマエストロ 15
カスタムパーツの連結数が10を超えました。

KOF SKY STAGE

破滅へのカウントダウン 20
ステージ5クリア達成!(1Player Game)

赤き世界 10
1プレイ中に挑発を30回以上達成!(1Player Game、コンティニュー不可)

ilomilo

やっと会えたね 20
ゲームをクリアした

2011/01/18の実績

ilomilo

クサいゼリー 15
チャプター 4 へ進んだ

シャッフラー 10
“ilomilo シャッフル” のミニゲームで 500 ポイント以上のスコアを獲得した

2011/01/17の実績

メモリーズオフ ゆびきりの記憶

記憶の再生 10
クイックロードを使用した。

記憶のリピート 10
バックログ画面で音声を再生させた。

2011/01/16の実績

ilomilo

ミュージシャン 20
メイン メニューでカーソル音を利用してテーマ曲を演奏した

道なかば 15
チャプター 3 へ進んだ

お茶でもいかが? 20
チャプター 2 へ進んだ

ひとりずつ 20
全色の safka を集めた

勉強熱心 20
チュートリアルを完了した

再会 20
レベルをクリアした

メモリーズオフ ゆびきりの記憶

はじまりの記憶 25
オープニングムービーを鑑賞した。

はじめてのゆびきり 5
勇気を出してゆびきりをしてみよう。

記憶の暴走 10
スキップモードを使用した。

記憶の反芻 10
セーブ・ロード画面を開いた。

記憶の自動送り 10
オートモードを使用した。

記憶の扉 10
バックログ画面を開いた。

記憶の設定 10
オプションモードを使用した。

俺の嫁 ~あなただけの花嫁~

洗濯のお手伝い 20
嫁の洗濯のお手伝いをしました

メイドさんと遊ぼう 20
メイドさんモードに突入しました

トランプで勝負 20
嫁とトランプで遊びました

FINAL FANTASY XIII

運命の覇者 80
世界の命運を決する最終決戦で最高の評価を得た証です。

巨獣の討伐者 30
魔境の荒野をうろつく巨獣をしとめた証です。

ガラフの聖杯 30
冥碑より示されたミッションをすべて達成した証です。

鎮魂の献杯 30
魔境をさまよう強大な亡者と7度戦い、勝利した証です。

全能のダイヤモンド 30
あらゆる能力の頂点まで成長した証です。


2011/01/23 17:30 | Comments(0) | TrackBack() | 実績
twitterauth.phpでログイン
前回までZend_Oauthでtwitter認証を行いましたが、この仕組みはブラウザ経由でログインさせて云々しないといけません。

何故このような作りになっているかというとそれはOauthの目的そのものなのですが、前回のプログラムをよく見ると、プログラム自体には投稿を行うユーザのID、パスワードの情報が一切渡されていません。
ID、パスワードは直接twitterのサイトに入力します。
するとIDに紐付くAccessTokenおよびAccessTokenSecretというものが発行され、パスワード代わりにこのAccessTokenAccessTokenSecretを使用することで投稿が可能になります。
プログラムはパスワードを一切知らないのに、認証できたという結果だけを利用できるのです。

これはあくまで不特定のユーザにアプリを公開して使ってもらう際に、私はIDやパスワードを盗んだりできませんよという証明に使うものです。
本来AccessTokenAccessTokenSecretには有効期限があるため、それを過ぎると再度パスワードを入力したりする必要があります。
ただ現在のtwitterは何故か無制限になってるみたいですが、これだと結局ID/パスワードを渡したのと同レベルに弄ばれてしまう気がするんだがどうなんだろう。
一応ユーザで取り消すことはできますが、毎回削除とか面倒だし普通しないでしょうし。

もっと手っ取り早く、ブラウザを経由しないで自分専用にローカルに保存したID、パスワードで直接投稿とかはできないでしょうか。
自分専用に期間無制限のAccessTokenAccessTokenSecretをtwitterのサイトから発行できるので、これを予め保存しておくことで、前回まで行っていたOauth認証をパスしていきなり投稿を行うことができます。

http://dev.twitter.com/apps/からアプリケーションを選択し、メニューの「My Access Token」を選びます。
AccessTokenAccessTokenSecretが表示されますが、これがIDやパスワードのかわりになります。

では投稿してみましょう。
今回はtwitterauthというものを使ってみます。
http://apiwiki.twitter.com/OAuth-Examples
こちらの「Code(GitHub)」リンクからサンプルプログラムが一式ダウンロード出来ます。
認証には、twitteroauthディレクトリ下にある
・twitteroauth.php
・OAuth.php
を使います。
<?php
	//require
	require_once('twitterauth.php');
	
	//定義
	$consumer_key = '*****';
	$consumer_secret = '*****';
	$access_token = '*****';
	$access_token_secret = '*****';
	
	//投稿
	$TwitterAuth = new TwitterOAuth($consumer_key,$consumer_secret,$access_token,$access_token_secret);
	$req = $TwitterAuth->OAuthRequest("https://twitter.com/statuses/update.xml","POST",array("status"=>"投稿テスト"));

実に簡単ですね。


元々Zend_Service_Twitterで呟こうとしたらZend_OAuthのリダイレクトにぶち当たり、PHPPRO掲示板で聞いてtwitterauthを紹介され、どうにかここまで解消したのですが、今さらになってまったくそのままの回答が書いてあるのを発見してしまった。

なんてこったい。


2011/01/21 21:51 | Comments(0) | TrackBack() | PHP
Symfony1.4 11日目その5
前回の続き。

求人を一旦公開してしまったら、その後の編集は行うことができません。
直接該当のtokenを指定してURLを辿っても、現れるリンクは削除用だけになります。
http://symfony.localhost/frontend_dev.php/job/token

が、実はエディット画面のURLを直接指定すれば平然と編集ができてしまいます。
http://symfony.localhost/frontend_dev.php/job/token/edit

公開後に編集とかされるとブラック的に色々とアレなので防ぎましょう。

まず自動投稿を行うJobeetTestFunctional::createJob()に公開機能を付けてみます。

/lib/test/JobeetTestFunctional.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
<?php
  public function createJob($values = array(), $publish = false){
    $this->
      get('/job/new')->
      click('Preview your job', array('job' => array_merge(array(
        'company'      => 'Sensio Labs',
        'url'          => 'http://www.sensio.com/',
        'position'     => 'Developer',
        'location'     => 'Atlanta, USA',
        'description'  => 'You will work with symfony',
        'how_to_apply' => 'Send me an email',
        'email'        => 'for.a.job@example.com',
        'is_public'    => false,
        'type'         => 'freelance',
      ), $values)))->
      followRedirect()
    ;
    if ($publish){
      $this->
        click('Publish', array(),
           array('method' => 'put', '_with_csrf' => true))->
        followRedirect()
      ;
    }
    return $this;
  }

第二引数$publishにtrueを指定すると、新たな投稿を行ったあとでPublishリンクを踏んで公開状態にまでしてくれます。

次にテストを書くわけですが、公開完了ページには編集画面へのリンクがありません。
投稿内容からtokenを拾ってきてURLに突っ込む仕組みを作りましょう。

/test/functional/frontend/jobActionsTest.php
1
2
3
4
5
6
7
8
9
<?php
$browser->info('3.5 - When a job is published, it cannot be edited anymore')->
  createJob(array('position' => 'FOO3'), true)->
  get(sprintf('/job/%s/edit',
     $browser->getJobByPosition('FOO3')->getToken()))->
  with('response')->begin()->
    isStatusCode(404)->
  end()
;

求人を作成、投稿した後、エディット画面を拾ってきて、そのステータスコードが404であることを確認するという流れになります。
エディット画面はリンクがないので、/job/:token/editってURLを直接作って取得してきます。
tokenを取得するために、JobeetJobオブジェクトを取得するgetJobByPosition()メソッドを新設します。

/lib/test/JobeetTestFunctional.class.php
1
2
3
4
5
6
7
<?php
  public function getJobByPosition($position){
    $q = Doctrine_Query::create()
      ->from('JobeetJob j')
      ->where('j.position = ?', $position);
    return $q->fetchOne();
  }

さっくりできました。
さて実行。

>php test/functional/frontend/jobActionsTest.php
>   3.5 - When a job is published, it cannot be edited anymore
# get /job/new
# post /job
# put /job/03586d0f02dd19df6158eee0ccd0369529fb48e2/publish
# get /job/03586d0f02dd19df6158eee0ccd0369529fb48e2/editnot ok 1 - status code is 404
#     Failed test (symfony/test/sfTesterResponse.class.php at line 412)
#            got: 200
#       expected: 404

404が返ってくるはずなのに200が返ってきました。
現状ではエディット画面に行けてしまいます。
公開後の求人は編集できないようにしましょう。

エディット画面のURLは/job/:token/editとなり、ルーティングのjob:sfDoctrineRouteCollectionにひっかかってjobモジュールのeditアクションが実行されます。

/apps/frontend/modules/job/actions/actions.class.php
1
2
3
4
5
6
7
8
9
10
11
12
<?php
    /*
     * フォームのエディット
     */
    public function executeEdit(sfWebRequest $request){
        //オブジェクト取得
        $job = $this->getRoute()->getObject();
        //is_activatedがtrueであれば404
        $this->forward404If($job->getIsActivated());
         //フォームに投入
        $this->form = new JobeetJobForm($job);
    }

$job->getIsActivated()がtrueであれば404という処理を追加しました。

>php test/functional/frontend/jobActionsTest.php
>   3.5 - When a job is published, it cannot be edited anymore
# get /job/new
# post /job
# put /job/38bd3acdf34b045c27f69b53d02e48fe10efdf42/publish
# get /job/38bd3acdf34b045c27f69b53d02e48fe10efdf42/edit
ok 1 - status code is 404

きちんと404がかえってきました。
ブラウザで見ても一旦公開した求人はエディットできません。


2011/01/17 21:54 | Comments(0) | TrackBack() | PHP

<<前のページ | HOME | 次のページ>>
忍者ブログ[PR]