FuelPHP

FuelPHPでメッセージ(伝言板)アプリ(その1)

更新日:

基本テーブルの作成と基本設定

今までPHPで作成していた社内専用サイトは携帯(ガラケー)用でした。スマートフォンの普及に伴い、全面的にリニューアルしたいと思い、あれこれフレームワークを捜してましたが、ようやくFuelPHPに落ち着きそうです。

1. いままでの伝言板も設計から一新することにしました。そこで、今日からメッセージ(伝言板)アプリを作成していきたいと思います。

メッセージ用テーブルの作成

2. それでは、まずメッセージ用テーブルを下記のように作成します。

CREATE TABLE `messages` (
`id` int( 11 ) NOT NULL AUTO_INCREMENT ,
`title` varchar( 255 ) NOT NULL ,
`body` text NOT NULL ,
`contributor` int( 11 ) NOT NULL COMMENT,
`group` int( 11 ) default NULL COMMENT,
`person` text,
`comment` text,
`created_at` int( 11 ) NOT NULL ,
`updated_at` int( 11 ) NOT NULL ,
PRIMARY KEY ( `id` )
) ENGINE = MYISAM DEFAULT CHARSET = utf8;

ざっとmessagesテーブルの説明をします。titleはメッセージのタイトル、bodyがメッセージの内容、contributorはメッセージ発信者のID、groupはusersテーブルのgroupID、personは個人宛てメッセージの送信先IDか個人情報の配列のシリアライズ(どちらにしようか、まだ迷っています)、commentは、このメッセージに対するコメントの連想配列のシリアライズ、created_atは作成日、updated_atは更新日です。commentは別テーブルを作成する方法もあるのですが、掲示板と違って、スレッドが立つわけではありませんので、一つのメッセージに対するコメントはそう多くは無いので、コメントの連想配列を保存することにしました。

未読メッセージ管理用のフィールド

3. 次に、未読メッセージを管理するためのフィールドをusersテーブルに追加作成します。

ALTER TABLE `users` ADD `unread` TEXT NULL ;

考え方としては、未読メッセージがある場合は、トップページに未読メッセージのリンクが表示されるようにして、メッセージを読めばトップページから消えるように作成したいと思います。

Userモデルの修正

4. ログインしているユーザーの情報を簡単に取得する為に新しいメソッドを作成します。

app/classes/model/user.php

/***********************************
 * ログインユーザー情報の取得
 ***********************************/
 public static function login(){ 
 //data配列の初期化
 $data=array();
 //Authのインスタンス化
 $auth=Auth::instance();
 //ログインユーザー情報の取得
 $data=Model_User::find()
 ->where('username',$auth->get_screen_name())
 ->get_one();
 return $data;
 }

SimpleAuthのメソッドで、簡単にユーザー情報は取得できるのですが、メソッド名が長いのと、user_idが簡単に取得できない(get_user_idメソッドはユーザーidの配列構造体を返しますので、user_idを取得するには一手間必要)、新規作成したプロパティ(フィールド)が取得できないので、loginメソッドを作成しました。これは、Model_User::login()でログインしているユーザー情報が簡単に取得できますので、Model_User::login()->idでログインユーザーのIDが取得できます。

5. たびたびの変更ですが、テーマを取得する為のメソッドを下記のように修正します。

app/classes/model/user.php

public static function theme($content,$data=array()){
//テーマのインスタンス化
 $theme=\Theme::forge();
 //テーマにテンプレートのセット
 $theme->set_template('template');
 //テーマのテンプレートにタイトルをセット
 $theme->get_template()->set('title','Builwing');
 //ビューにデータを引き渡す
 $view=$theme->view($content,$data);
 //テーマのテンプレートにビューをセット
 $theme->get_template()->set('content',$view);
 return $theme;
 }

前回(FuelPHPで会員管理)までは、データの引き渡しは、モデルで行っていました。ところが、この方法だとページごと(アクションごと)に、テーマを呼び出すメソッドを作成するか、そのページに必要のないデータまであらかじめ作成しておく必要があります。使っているうちに、余り効率的では無いと思い、上記のようにコントローラからビューファイルにデータを引き渡すように修正しました。

トップページの作成

6. FuelPHPの既存のトップページwelcome.pnpをそのままトップページとして使用します。コントローラを下記のように書き換えます。

app/classses/controller/welcome.php

<?php
class Controller_Welcome extends Controller{

 /************************
 * beforeアクション
 ************************/

 public function before(){
 parent::before();
 //許可するアクション
 $action=array('login','logout');
 //現状のアクション
 $active=Request::active()->action;
 //ログインしていなくて、許可アクション以外は
 if(!Auth::check() && !in_array($active,$action)){
 //ログインページへ移動
 Response::redirect('welcome/login');
 }
 }

 /*************************
 * トップページ
 *************************/

 public function action_index(){
 //テーマの表示
 return Model_Welcome::theme('welcome/index');
 }
 /*************************
 * ログインページ
 *************************/

 public function action_login(){
 //POST送信なら
 if(Input::method() == 'POST'){
 //Authのインスタンス化
 $auth=Auth::instance();
 //資格情報の取得
 if($auth->login(Input::post('username'),Input::post('password'))){
 //禁止ユーザーならWithoutページへ
 if(!$auth->has_access('user.index')){
 //Withoutページへ
 Response::redirect('user/login/without');
 }
 //認証OKならトップページへ
 Response::redirect('welcome/index');
 }else{
 //認証が失敗したときの処理
 Session::set_flash('error', 'ユーザー名かパスワードが違います。');
 }
 }
 //テーマの表示
 return Model_User::login_theme('welcome/login');
 }

 /*****************************
 * ログアウト
 *****************************/

 public function action_logout(){
 Auth::logout();
 //ログインページへ移動
 Session::set_flash('error', 'ログアウトしました。');
 Response::redirect('welcome/login');
 }
}

7. welcomeモデルを下記のように作成します。

app/classes/model/welcome.php

<?php
class Model_Welcome extends \Orm\Model{
 //テーブル名の指定(モデル名の複数形なら省略可)
 protected static $_table_name='users';
 //プロパティのセット
 protected static $_properties = array(
 'id',
 'username',
 'password',
 'group',
 'email',
 'last_login',
 'login_hash',
 'profile_fields',
 'created_at',
 'updated_at',
 'onepass', //ワンタイムパスワード
 'unread', //未読メッセージの配列(シリアライズ)
 );

 protected static $_observers = array(
 'Orm\Observer_CreatedAt' => array(
 'events' => array('before_insert'),
 'mysql_timestamp' => false,
 ),
 'Orm\Observer_UpdatedAt' => array(
 'events' => array('before_save'),
 'mysql_timestamp' => false,
 ),
 );
/***********************************
 * トップページ用テーマ
 ***********************************/
 public static function theme($content,$data=array()){
 //ログインユーザー情報の取得
 $user=Model_User::login();
 //未読メッセージの配列をセット(アンシリアライズ処理)
 $data['unread']=unserialize($user->unread);
 //テーマのインスタンス化
 $theme=\Theme::forge();
 //テーマにテンプレートのセット
 $theme->set_template('template');
 //テーマのテンプレートにタイトルをセット
 $theme->get_template()->set('title','Builwing');
 //ビューにデータを引き渡す
 $view=$theme->view($content,$data);
 //テーマのテンプレートにビューをセット
 $theme->get_template()->set('content',$view);
 return $theme;
 } 
}

welcomeモデルの基本テーブルはusersテーブルです。ですので、別段モデルは作成せずに、usersモデルでも構わないと思うのですが、トップページを扱うための色々なメソッドを作成する為にwelcomeモデルは作成しました。

8. トップページを表示するためのビューファイルを下記のように記述します。

app/views/welcome/index.php

<div class="row">
<?php if($unread!=null):?>
 <h3 style="color:red;"><marquee loop="-1"><?=Auth::get_screen_name()?>さん、<?=count($unread)?>件の未読メッセージがあります。確認して下さい。</marquee></h3>
 <ul data-role="listview">
 <?php foreach($unread as $key=>$value):?>
 <li>
 <?php echo Html::anchor('message/detail/'.$key,$value,array('data-rel'=>'dialog','rel'=>'external'));?></li>
 <?php endforeach;?>
 </ul>
 <?php elseif($unread==null):?>
 <h3 style="color:green;"><marquee loop="-1"><?=Auth::get_screen_name()?>さん、現在未読メッセージはありません。</marquee></h3>
 <?php endif;?>
</div>

9. これで、一応基本設定は終了です。次回は、メッセージデータを処理するためのmessageモデルを作成したいと思います。

本日は以上です。尚、次回からビューファイルは、スマートフォン用(themes/mobile)を中心に作成していきたいと思います。

スマートフォン用templateとビューファイル

上記の右側に表示してあるスマートフォン用のtemplateとビューファイルの記述を忘れていましたので、下記に記述しておきます。PC用サイトとスマートフォン用サイトの自動切り替えは前回の『FuelPHPのテーマクラスでスマホサイトの振り分け』をご覧下さい。

app/themes/mobile/template.php

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title><?=$title?></title>
<meta name="ROBOTS" content="NOINDEX,NOFOLLOW">
<meta name="viewport" content="width=device-width,minimun-scale=1">
<?php echo Asset::css('jquery.mobile-1.1.1.min.css');?>
<?php echo Asset::js('jquery-1.8.2.min.js');?>
<?php echo Asset::js('jquery.mobile-1.1.1.min.js');?>
</head>
<body>
<?php echo $content;?>
</body>
</html>

app/themes/mobile/welcome/index.php

<div data-role="page" id="page1" data-theme="e">
<div data-role="header" data-theme="b">
<h1><?php echo Asset::img('winglogo.png');?></h1>
<?php echo Html::anchor('#menu','menu',array('data-rel'=>'dialog','data-icon'=>'info','data-iconpos'=>'left','class'=>'ui-btn-right'));?>
</div>
<nav data-role="navbar">
<ul>
<li><?=Html::anchor('message','メッセージ',array('data-theme'=>'c'))?></li>
<li><?=Html::anchor('#','現場',array('data-theme'=>'c'))?></li>
<li><?=Html::anchor('#','社員',array('data-theme'=>'c'))?></li>
<li><?=Html::anchor('#','予定',array('data-theme'=>'c'))?></li>
<li><?=Html::anchor('#','提出物',array('data-theme'=>'c'))?></li>
</ul>
</nav>
<div data-role="content">
<?php if($unread!=null):?>
<h3 style="color:red;"><marquee loop="-1"><?=Auth::get_screen_name()?>さん、<?=count($unread)?>件の未読メッセージがあります。確認して下さい。</marquee></h3>
<ul data-role="listview">
<?php foreach($unread as $key=>$value):?>
<li>
<?php echo Html::anchor('message/detail/'.$key,$value,array('data-rel'=>'dialog','rel'=>'external'));?></li>
<?php endforeach;?>
</ul>
<?php elseif($unread==null):?>
<h3 style="color:green;"><marquee loop="-1"><?=Auth::get_screen_name()?>さん、現在未読メッセージはありません。</marquee></h3>
<?php endif;?>
</div>
<div data-role="footer" class="ui-bar" data-theme="b" style="text-align:center">
app/themes/mobile/welcome/index.php
<?php echo Html::anchor('welcome/logout','ログアウト',array('data-ajax'=>false,'data-icon'=>'delete','data-iconpos'=>'notext','class'=>'ui-btn-right'));?>
</div>
</div>
<!--メニューページ-->
<div data-role="page" id="menu" data-theme="e">
<div data-role="header" data-theme="c">
<h1><?php echo Asset::img('winglogo.png');?></h1>
<a href="/" data-icon="home" data-iconpos="notext" class="ui-btn-right">ホーム</a>
</div>
<div data-role="content">
<ul data-role="listview">
<li data-role="list-divider">メッセージ</li>
<li><?php echo Html::anchor('message','メッセージ一覧');?></li>
<li><?php echo Html::anchor('message/create','グループメッセージ作成');?></li>
<li><?php echo Html::anchor('message/person','個人メッセージ作成');?></li>
<li data-role="list-divider">現場情報</li>
<li><?php echo Html::anchor('#','現場リスト');?></li>
<li><?php echo Html::anchor('#','作業日報');?></li>
<li data-role="list-divider">社員情報</li>
<li><?php echo Html::anchor('#','タイムカード');?></li>
<li><?php echo Html::anchor('#','出勤状況');?></li>
<?php if(Auth::member(100)):?>
<li data-role="list-divider">管理室</li>
<li><?php echo Html::anchor('welcome/logout','ログアウト');?></li>
<li><?php echo Html::anchor('user/admin','ユーザー一覧');?></li>
<?php endif;?>
</ul>
</div>
<div data-role="footer" data-theme="c" style="text-align:center">
app/themes/mobile/welcome/index
</div>
</div>

次回は、Messageモデルの作成です。

-FuelPHP
-

Copyright© WinRoad徒然草 , 2018 All Rights Reserved Powered by AFFINGER5.