Messageアプリのモデル作成

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

前回『FuelPHPでメッセージアプリ(その1)』は、Messageアプリを作成する上で必要なデータベーステーブル、usersテーブルの追加フィールド、その他基本的な設定を作成しました。本日はmessageモデルを作成したいと思います。

基本的なモデルの作成

1. まず、基本的なモデルを下記に記述します。これはoilで簡単に作成できると思います。

app/classes/model/message.php

<?php
class Model_Message extends \Orm\Model{
 //テーブル名の指定(モデル名の複数形なら省略可)
 protected static $_table_name='messages';
 //プロパティのセット
 protected static $_properties = array(
 'id',
 'title',
 'body',
 'contributor', //発信者ID
 'group', //受信者グループID
 'person', //個人受信者IDか配列(シリアライズ)
 'comment',//コメントの配列(シリアライズ)
 'created_at',
 'updated_at',
 );

 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,
 ),
 );
}

リレーションの設定

2. この基本的なモデルにリレーション(アソシエーション)の設定を追加します。モデル間のリレーションの詳細は、『FuelPHPのORM(オブジェクトリレーショナルマッパー)』の後半の記事を参照して下さい。

app/classes/model/message.php

/***********************************
 * belongsToの設定
 ***********************************/
 protected static $_belongs_to =array(
 'cont'=>array( //発信者
 'key_from'=>'contributor',
 'model_to'=>'Model_User',
 'key_to'=>'id',
 'cascade_save'=>true,
 'cascade_delete'=>false,
 ),
 );

 belongsToは、一対多のリレーションです。5行目の’cont’はリレーションを呼び出すための名前(任意)で、key_fromで指定しているcontributorの数値を元にして、Model_User(usersテーブル)のidが同じ数値のデータを抽出します。つまり、$messageがインスタンス化したオブジェクトだとすれば、$message->cont->usernameで、messagesテーブルのcontributorのID番号と同じID番号のユーザー名(username)をusersテーブルから取得することが出来ます。

テーマクラスの呼び出し用メソッド

3. そして、テーマクラスを呼び出すためのメソッドを下記のように作成します。

app/classes/model/message.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;
 }

ページネーションの作成

4. メッセージデータが増えてきたときに全てを1ページで表示するには無理があります。そこで1ページあたりの表示件数を区切って表示するために、ページネーションの設定をしなければなりません。ページネーション用のメソッドもモデル内に作成しておきます。ページネーションの詳細は、『FuelPHPのPaginationクラス』及び、『FuelPHPでページネーション(実践編その6)』をご覧下さい。

app/classes/model/message.php

/**********************************************
 * 受信メッセージのデータ取得(ページネーション)
 *********************************************/
 public static function pagedata($lines=20){
 //ユーザー情報の取得
 $user=Model_User::login();
 //受信メッセージの抽出
 $message=Model_Message::find()
 ->where('group','<=',$user->group)
 ->or_where('person',$user->id);
 //メッセージ件数の取得
 $count=$message->count();
 //Paginationの環境設定
 $config=array(
 'pagination_url'=>'message/index',
 'uri_segment'=>3,
 'num_links'=>3,
 'per_page'=>$lines,
 'total_items'=>$count,
 'template'=>array(
 ));
 //Paginationのセット
 Pagination::set_config($config);
 //メッセージのページデータ取得
 $data=$message
 ->order_by('created_at','desc')
 ->limit(Pagination::$per_page)
 ->offset(Pagination::$offset)
 ->get();
 return $data;
 }

9行目のWHERE句ですが、messagesテーブルのgroupフィールドの値より大きなgroupに所属しているユーザーは、メッセージを受信できます。つまり、user宛てに送ったメッセージは、adminユーザーも閲覧することが出来るようにしています。10行目のor_whereは、個人宛に送ったメッセージも取得する為にOR文で記述しています。現状、personはIDを入力するような形にしていますが、グループ宛では無いけれども複数の人に同時にメッセージを送る場合もありますので、いずれ、usernameの配列に変更していこうかと考えています。

尚、Paginationの環境設定ですが、以前作成したのと違って、template以下のページレイアウトのHTMLマークアップを削除しています。FuelPHP1.3以降は、TwitterBootstrap2.0に対応していますので、基本的なテンプレートは最適化されています。

検索用メソッドの作成

5. メッセージページのトップ(message/index)ページに、メッセージの検索用の窓を作成したいと思いますので、メッセージ検索用のメソッドもついでに作成しておきます。

app/classes/model/message.php

/***********************************
 * 検索データのページ別データ取得
 ***********************************/
 public static function search($search){
 //ユーザー情報の取得
 $user=Model_User::login();
 //検索文字を空白で区切って配列に代入
 $keywords=preg_split('/ |\\s/',$search);
 //検索データの取得
 $messages=Model_Message::find()
 ->where_open()
 ->where('group','<=',$user->group)
 ->or_where('person',$user->id)
 ->where_close();
 foreach($keywords as $word){ //配列の数だけ繰り返し
 $messages
 ->and_where_open()
 ->where('title','LIKE',"%".$word."%")
 ->or_where('body','LIKE',"%".$word."%")
 ->and_where_close();
 }
 //メッセージ件数の取得
 $count=$messages->count();
 //Paginationの環境設定
 $config=array(
 'pagination_url'=>'message/index',
 'uri_segment'=>3,
 'num_links'=>3,
 'per_page'=>20,
 'total_items'=>$count,
 'template'=>array(
 ));
 //Paginationのセット
 Pagination::set_config($config);
 //メッセージのページデータ取得
 $data=$messages
 ->order_by('created_at','desc')
 ->limit(Pagination::$per_page)
 ->offset(Pagination::$offset)
 ->get();
 return $data;
 }

検索は絞り込み検索が出来るように複合語検索にしました。方法としては、受け取った文字を空白で区切って分解して、配列に代入します(8行目)。その代入した配列を配列の数だけWHERE句を繰り返します(15~21行目)。検索データも多すぎると見づらいので、20行ずつで区切ってページネーション処理をしました。尚、お分かりだとは思いますが、念のため、8行目の『(‘/』の後には、全角の空白を入力して下さい。つまり、(‘/『全角の空白』|\\s/’,$search)という形になります。

6. これで、一応の基本設計は出来ました。次回から、コントローラとアクションを作成していきたいと思います。

本日は以上です。

次回は『Createアクションの作成』です。

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

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

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

コメントをどうぞ

このページの先頭へ