FuelPHPでメッセージアプリ(その4)

detailアクション(明細ページ)の作成

今日は、前回『Createアクションの作成』の続きとして、detailアクション(明細ページ)の作成を行いたいと思います。createアクションで作成されたメッセージは、トップページ(welcome/index)に、未読メッセージの一覧として表示され、未読メッセージをクリックすると明細ページへ移動して、次回からトップページに表示されないように作成します。

1. detailアクションを下記のように作成します。

app/classes/controller/message.php

/*********************************
 * メッセージ詳細表示
 *********************************/ 
 public function action_detail($id=null){
 //指定のメッセージが無い場合
 if(!Model_Message::find($id)){
 $user=Model_User::login();
 $unread=unserialize($user->unread);
 Arr::delete($unread,$id);
 $user->unread=serialize($unread);
 $user->save();
 //エラー表示
 Session::set_flash('error','指定のメッセージは既に削除されています');
 Response::redirect('message/index');
 }
 //ユーザー情報の取得
 $user=Model_User::login();
 //メッセージ情報の取得
 $message=Model_Message::find($id);
 $unread=unserialize($user->unread);
 //POST送信なら
 if(Input::method()=='POST'){
 //バリデーションの初期化
 $val=Validation::forge();
 //バリデーションフィールドの追加
 $val->add_field('comment','コメント','required');
 //バリデーションOKなら
 if($val->run()){
 //配列の作成
 $new_comment=array(
 time()=>array(
 'commentator'=>Auth::get_screen_name(),
 'body'=>Input::post('comment')));
 //コメントの配列を取得
 $comment=unserialize($message->comment);
 //新規コメントをセット
 Arr::set($comment,$new_comment);
 //データベースに保存
 $message->comment=serialize($comment);
 $message->save();
 }
 //バリデーションNGなら
 Session::set_flash('error',$val->show_errors());
 }
 //未読メッセージの既読処理
 Arr::delete($unread,$message->id);
 $user->unread=serialize($unread);
 $user->save();
 //明細データの取得
 $data['detail']=$message;
 //コメントの取得(アンシリアライズ処理)
 $data['comments']=unserialize($data['detail']->comment);
 //テーマの表示
 return Model_Message::theme('message/detail',$data);
 }
  • 5行目から15行目は、未読メッセージが作成者によって既に削除されている場合は、エラーが生じます。ですので、既に削除されているメッセージはusersテーブルのunreadの配列から削除するために作成しました。
  • 20行目から40行目はコメントが入力された場合の処理です。コメントがPOST送信されたら、既存のコメントに新しいコメントを配列としてセットしてシリアライズ処理しています。タイムスタンプをキーとして、作成者と本文の内容を新規コメントとして登録します。
  • 44行目から47行目は、未読メッセージの既読処理をしています。19行目で取得したusersテーブルのunreadフィールドの配列から、明細を表示しているメッセージを削除して、再びシリアライズ処理して保存しています。
  • 48行目から53行目で明細データを$detail、コメントの配列を$commentsとして、テーマに渡しています。

2. 明細ページ表示のためのビューファイルdetail.phpを下記のように表示します。尚、ビューファイルは、スマートフォン用のビューファイルを記述しています。PC用のビューファイルは皆さんで作成して下さい。

app/themes/mobile/message/detail.php

<div data-role="page" id="page1" data-theme="e">
<div data-role="header" data-theme="b">
<h1>メッセージ明細</h1>
<?php echo Html::anchor('/','ホーム',array('rel'=>'external','data-icon'=>'home','data-iconpos'=>'notext','class'=>'ui-btn-left'));?>
<?php echo Html::anchor('#menu','menu',array('data-rel'=>'dialog','data-icon'=>'info','class'=>'ui-btn-right'));?>
</div>
<nav data-role="navbar">
<ul>
<li><?=Html::anchor('message/','一覧',array('data-theme'=>'c'))?></li>
<li><?=Html::anchor('message/create/','グループメッセージ作成',array('data-theme'=>'c'))?></li>
<li><?=Html::anchor('message/person/','個人メッセージ作成',array('data-theme'=>'c'))?></li>
</ul>
</nav>
<div data-role="content">
<h3><?=$detail->title?></h3>
<hr>
<p><?=$detail->body?></p>
<hr>
作成者:<?=$detail->cont->username?><br>
作成日:<?=date('Y/m/d H:i',$detail->created_at)?>
<!--メッセージの作成者なら削除リンクの表示-->
<?php if(Model_User::login()->id==$detail->contributor):?>
<?php echo Html::anchor('message/delete/'.$detail->id,'<p>削除</p>',array('data-rel'=>'dialog'));?>
<?php endif;?>
</div>
<hr>
<div data-role="content">
<?php if($comments):?>
<h3>コメント一覧</h3>
<?php foreach($comments as $key=>$row):?>
<?php echo $row['commentator']."より<br>";?>
<?php echo date('Y/m/d H:i:s',$key)."<br>";?>
<?php echo "<p>".$row['body']."</p><hr>";?>
<?php endforeach;?>
<?php elseif(!$comments):?>
コメントはありません。
<?php endif;?>
</div>
<div data-role="content">
<!--コメントフォーム-->
<?php echo Form::open(array('name'=>'comment','method'=>'post')); ?>
<?php echo '<div class="alert-error">'.Session::get_flash('error').'</div>'?>
<div data-role="collapsible">
<h3>コメントの入力</h3>
<?php echo Form::hidden('user_name',Auth::get_screen_name());?>
<?php echo Form::hidden('message_id',$detail->id);?>
<?php echo Form::textarea('comment',Input::post('comment'),array('placeholder'=>'コメントを入力して下さい。'));?>
<?php echo Form::submit('submit','コメント送信');?>
<?php echo Form::close();?>
</div>
</div>
<!--フッター-->
<div data-role="footer" data-theme="b" style="text-align:center">
themes/mobile/message/detail
</div>
  • 21行目から24行目でメッセージの作成者にのみ削除リンクが表示されるように作成しています。
  • 28行目から37行目は、コメントがある場合は表示して、コメントが無い場合は、無い旨を表示するように作成しました。
  • 39行目から51行目でコメントの入力フォームを作成しています。コメントを入力すると、コメントの内容以外に、ユーザー名及びメッセージのIDをhiddenデータとして送信します。

3. ブラウザで表示してみます。ちなみにPC用のビューファイルはホームページビルダーのテンプレートを使用しています。

コメントの入力

4. スマートフォン用のビューファイルのアコーディオンパネルをクリックして、コメントを入力してみます。

5. 下記のようにコメントが表示されました。

deleteアクション

6. deleteアクションを下記のように記述します。

app/classes/controller/message.php

/*********************************
 * メッセージの削除
 *********************************/ 
 public function action_delete($id=null){
 //POST送信なら
 if(Input::method() == 'POST'){
 $id=Input::post('id');
 //削除データの抽出
 $delete_message=Model_Message::find()
 ->where('id',$id)
 ->where('contributor',Model_User::login()->id);
 if($delete_message->count()==0){
 Session::set_flash('error','メッセージを削除できません');
 }else{
 Session::set_flash('error','メッセージを削除しました');
 $delete_message->delete();
 }
 //メッセージ一覧へ移動
 Response::redirect('message/index');
 }
 //削除メッセージのデータ取得
 $data['message']=Model_Message::find($id);
 //テーマの表示
 return Model_Message::theme('message/delete',$data);
 }

11行目は、投稿者以外がメッセージを勝手に削除できないように記述しています。今回、明細ページに削除ページへのリンクを作成しましたが、送信メッセージの一覧ページを作成して、そこに削除ページへのリンクを作成する方法が無難だと思います。又、既にコメントの入力があるメッセージは削除できないようにするなども状況に応じて対応してください。

7. deleteビューを下記のように記述します。

app/themes/mobile/message/delete.php

<div data-role="page" id="page1" data-theme="e">
<div data-role="header" data-theme="b">
<h1>メッセージ削除</h1>
<?php echo Html::anchor('/','ホーム',array('rel'=>'external','data-icon'=>'home','data-iconpos'=>'notext','class'=>'ui-btn-left'));?>
<?php echo Html::anchor('#menu','menu',array('data-rel'=>'dialog','data-icon'=>'info','class'=>'ui-btn-right'));?>
</div>
<nav data-role="navbar">
<ul>
<li><?=Html::anchor('message/','一覧',array('data-theme'=>'c'))?></li>
<li><?=Html::anchor('message/create/','グループメッセージ作成',array('data-theme'=>'c'))?></li>
<li><?=Html::anchor('message/person/','個人メッセージ作成',array('data-theme'=>'c'))?></li>
</ul>
</nav>
<div data-role="content">
<h3 style="color:red;">下記のメッセージを削除します。よろしいですか?</h3>
<h3><?=$message->title?></h3>
<hr>
<p><?=$message->body?></p>
<hr>
作成者:<?=$message->cont->username?><br>
作成日:<?=date('Y/m/d H:i',$message->created_at)?>
<hr>
<?php echo Form::open();?>
<?php echo Form::hidden('id',$message->id);?>
<?php echo Form::hidden('user_id',Model_User::login()->id);?>
<?php echo Form::submit('submit','メッセージ削除');?>
<?php echo Form::close();?>
<div data-role="footer" data-theme="b" style="text-align:center">
themes/mobile/message/delete
</div>

8. ブラウザを確認してみます。下記のようになりました。

9. メッセージのトップページ(message/index)を下記に記述しておきます。

app/themes/mobile/message/index.php

<div data-role="page" id="page1" data-theme="e">
<div data-role="header" data-theme="b">
<h1>受信メッセージ一覧</h1>
<?php echo Html::anchor('/','ホーム',array('rel'=>'external','data-icon'=>'home','data-iconpos'=>'notext','class'=>'ui-btn-left'));?>
<?php echo Html::anchor('#menu','menu',array('data-rel'=>'dialog','data-icon'=>'info','class'=>'ui-btn-right'));?>
</div>
<nav data-role="navbar">
<ul>
<li><?=Html::anchor('message/send','送信メッセージ一覧',array('data-theme'=>'c'))?></li>
<li><?=Html::anchor('message/create','グループメッセージ作成',array('data-theme'=>'c'))?></li>
<li><?=Html::anchor('message/person','個人メッセージ作成',array('rel'=>'dialog','data-theme'=>'c'))?></li>
</ul>
</nav>
<div data-role="content">
<?php echo '<h3 style="color:red">'.Session::get_flash('error').'</h3>'?>
<?php echo Form::open('message');?>
<?php echo Form::input('search','',array('type'=>'search','data-theme'=>'e','placeholder'=>'検索キーワードを入力して下さい'));?>
<?php echo Form::close();?>
<!--<div data-role="collapsible">-->
<!--<h3>メッセージ一覧</h3>-->
</div>
<div data-role="content">
<ul data-role="listview" data-theme="d">
<?php foreach($messages as $ms):?>
<li>
<?php echo Html::anchor('message/detail/'.$ms['id'],'<h2>'.$ms['title'].'</h2><span class="ui-li-count">'.date('m/d',$ms['created_at']).'</span><p>'.$ms['body'].'</p>')?>
</li>
<?php endforeach;?>
</ul>
<!--</div>-->
<div class="row">
<?php echo Pagination::create_links();?>
</div>
</div>
<div data-role="footer" data-theme="b" style="text-align:center">
themes/mobile/message/index
</div>

10. ブラウザで表示してみます。

本日は以上です。

このエントリーを含むはてなブックマーク Buzzurlにブックマーク livedoorクリップ Yahoo!ブックマークに登録

トラックバック&コメント

この投稿のトラックバックURL:

コメントをどうぞ

このページの先頭へ