チャット作るよ。9日目
超放置してた。やっぱりなかなか継続できないなー。
今日は表示系のアクションとテンプレ周り。
テンプレートは最初に作ったHTMLのモックに手をいれた。
メインページを作る。
まずはメインページ。indexページ的なもの。
基本的にこのページから遷移はしない予定。
iframeで会話ログも表示する。
未ログインならログインフォーム。
ログイン済みなら発言フォームを出す。
フォームの切り替えはテンプレートごと条件で切り替える。
それぞれ、index.phtml(ログイン前)、index2.phtml(ログイン済み)と分けておく。
まずはテストケース。
<?php class IndexActionTest extends PHPUnit_Extensions_OutputTestCase { /** * アプリケーションディレクトリ */ const APP_DIR_PATH = '/var/project/chat/fw/site'; public function setUp() { // インスタンス生成と初期化 $this->act = new IndexAction(); $config = array( 'appDirPath' => self::APP_DIR_PATH, 'renderer' => new Renderer() ); $this->act->initialize($config); } public function testRunIndex() { // テンプレートのHTMLが出力されること ob_start(); $render = new Renderer(); $render->setup(self::APP_DIR_PATH . '/template/index.phtml'); $render->run(); $buff = ob_get_contents(); ob_end_clean(); $this->expectOutputString($buff); $this->act->run(); } public function testRunIndex2() { // セッションにユーザ名を格納 $name = 'Test'; $_SESSION['identity'] = array('name' => $name); // セッションが存在する場合、専用テンプレートのHTMLが出力されること ob_start(); $render = new Renderer(); $render->setup(self::APP_DIR_PATH . '/template/index2.phtml', array('name' => $name)); $render->run(); $buff = ob_get_contents(); ob_end_clean(); $this->expectOutputString($buff); $this->act->run(); } }
で、アクションクラス。
<?php /** * Indexアクション */ class IndexAction extends Action { /** * アクションを実行します * * @return void */ public function run() { // ビューの初期化 $view = 'index'; if(isset($_SESSION['identity'])) { // ログイン済みの場合、ビューを切り替えてパラメータセット $view = 'index2'; $this->_set('name', $_SESSION['identity']['name']); } // ビューを描画 $this->_render($view); } }
そして、未ログイン用テンプレート。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link rel="stylesheet" type="text/css" href="./css/chat.css" /> <title>Chat</title> </head> <body> <div id="header"> <div class="title">Chat</div> </div> <div id="content"> <div id="form"> <form method="post" action="index.php?a=login"> <table> <tr> <th>name</th> <td> <input type="text" name="name" style="width:160px;" /> </td> </tr> </table> <input type="submit" value="Login" /> </form> </div> <iframe id="log" src="index.php?a=log"></iframe> </div> <div id="footer"> <div class="copyright">2010</div> </div> </body> </html>
もうひとつ。ログイン済みのテンプレート。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link rel="stylesheet" type="text/css" href="./css/chat.css" /> <title>Chat</title> </head> <body> <div id="header"> <div class="title">Chat</div> </div> <div id="content"> <div id="form"> <form method="post" action="index.php?a=comment" target="log_view"> <table> <tr> <th>name</th> <td><?php $this->out($name); ?></td> </tr> <tr> <th>comment</th> <td> <input type="text" name="comment" style="width:400px;" /> <input type="submit" value="Send" /> <input type="reset" value="Clear" /> </td> </tr> </table> </form> <form method="post" action="index.php?a=logout"> <input type="submit" value="Logout" /> </form> </div> <iframe id="log" name="log_view" src="index.php?a=log"></iframe> </div> <div id="footer"> <div class="copyright">2010</div> </div> </body> </html>
テンプレートの中でif文使って分岐かけても良かったかも。
ほとんど同じ内容だし。
会話ログページを作る。
続いてiframeの中身の方、会話のログを表示するページ。
metaタグのRefresh使って定期更新させて、最新ログの表示と有効期限の延長を担当する。
まずはテストケース。
<?php class LogActionTest extends PHPUnit_Extensions_OutputTestCase { /** * アプリケーションディレクトリ */ const APP_DIR_PATH = '/var/project/chat/fw/site'; public function setUp() { // インスタンスの生成 $this->act = new LogAction(); $this->member = new Member(FILE_MEMBER, 300); $this->arc = new Archive(FILE_ARCHIVE, 30); // アクションの初期化 $config = array( 'appDirPath' => self::APP_DIR_PATH, 'renderer' => new Renderer() ); $this->act->initialize($config); } public function testRun() { // ユーザを追加 $name = 'Test'; $id = $this->member->add($name); $members = $this->member->getAll(); $this->assertEquals(1, count($members)); // ログを追加 $this->arc->add($name, 'test'); $logs = $this->arc->getAll(); $this->assertEquals(1, count($logs)); // ユーザとログのデータが反映された、テンプレートHTMLが出力されること ob_start(); $render = new Renderer(); $params = array( 'members' => $members, 'archives' => $logs ); $render->setup(self::APP_DIR_PATH . '/template/log.phtml', $params); $render->run(); $buff = ob_get_contents(); ob_end_clean(); $this->expectOutputString($buff); $this->act->run(); } public function testRunWithIdentity() { // ユーザを追加 $name = 'Test'; $id = $this->member->add($name); $identity = array( 'id' => $id, 'name' => $name ); // セッションにユーザデータをセット $_SESSION['identity'] = $identity; // 確認用に登録ユーザデータを取得して保持 $members = $this->member->getAll(); $user = $members[0]; $this->assertEquals(1, count($members)); // ログを追加 $this->arc->add($name, 'test'); $logs = $this->arc->getAll(); $this->assertEquals(1, count($logs)); // データが反映されたテンプレートHTMLが出力されること ob_start(); $render = new Renderer(); $params = array( 'members' => $members, 'archives' => $logs ); $render->setup(self::APP_DIR_PATH . '/template/log.phtml', $params); $render->run(); $buff = ob_get_contents(); ob_end_clean(); $this->expectOutputString($buff); // タイムスタンプ更新用に1秒待機 sleep(1); $this->act->run(); // セッションが存在する場合、ユーザのタイムスタンプが更新されていること $members = $this->member->getAll(); $update = $members[0]; $this->assertEquals(1, count($members)); $this->assertEquals($user['id'], $update['id']); $this->assertEquals($user['name'], $update['name']); $this->assertLessThan($update['tstamp'], $user['tstamp']); } public function tearDown() { // テストデータの後始末 if(file_exists(FILE_ARCHIVE)) { unlink(FILE_ARCHIVE); } if(file_exists(FILE_MEMBER)) { unlink(FILE_MEMBER); } } }
続いてアクションクラス。
<?php class LogAction extends Action { public function run() { $member = new Member(FILE_MEMBER, 300); if(isset($_SESSION['identity'])) { // ログイン済みの場合は期限を延長 $identity = $_SESSION['identity']; $member->update($identity['id']); } // 期限切れユーザを削除 $member->gc(); $arc = new Archive(FILE_ARCHIVE, 30); // 現在のログインメンバーと会話ログをViewに渡す。 $this->_set('members', $member->getAll()); $this->_set('archives', $arc->getAll()); $this->_render(); } }
最後にテンプレート。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Refresh" content="30;URL=index.php?a=log" /> <link rel="stylesheet" type="text/css" href="./css/chat.css" /> <title>Chat</title> </head> <body> <div id="members"> <span>members:</span> <?php foreach($this->gets('members') as $member): ?> <span><?php $this->out($member['name']); ?></span> <?php endforeach; ?> </div> <hr/> <div id="archive"> <?php foreach($this->gets('archives') as $row): ?> <p><?php $this->out($row['name']); ?> : <?php $this->out($row['comment']); ?> <?php $this->out(date('Y/m/d H:i:s', intval($row['date']))); ?></p> <?php endforeach; ?> </div> </body> </html>
metaタグのRefresh使うの久しぶりで、フォーマット忘れてた。
あとは書き込みとかログイン周りで完成なはず。