7 * LICENSE: This source file is licensed under the terms of the GNU General Public License.
9 * @package Magic3 Framework
10 * @author 平田直毅(Naoki Hirata) <naoki@aplo.co.jp>
11 * @copyright Copyright 2006-2011 Magic3 Project.
12 * @license http://www.gnu.org/copyleft/gpl.html GPL License
13 * @version SVN: $Id: m_bbs_2chTopWidgetContainer.php 4039 2011-03-21 05:37:18Z fishbone $
14 * @link http://www.magic3.org
16 require_once($gEnvManager->getCurrentWidgetContainerPath() . '/m_bbs_2chBaseWidgetContainer.php');
18 class m_bbs_2chTopWidgetContainer extends m_bbs_2chBaseWidgetContainer
20 private $threadCount; // スレッド表示数
21 private $threadId; // スレッドID
22 private $threadIdArray = array(); // 表示するスレッドID
23 private $threadInfoArray = array(); // 表示中のスレッドの情報
24 private $headTitle; // METAタグタイトル
25 private $headDesc; // METAタグ要約
26 private $headKeyword; // METAタグキーワード
27 private $headCss; // ヘッダ追加CSS
28 private $threadStyle; // スレッド部表示スタイル
29 private $subjectColor; // 件名文字色
30 private $nameColor; // 登録者名文字色
31 private $createEmailLink; // Eメールのリンクを作成するかどうか
32 private $isExistsMessage; // メッセージが存在するかどうか
33 private $ticket; // POST確認用ハッシュキー
34 private $bbsName; // 入力再設定用(名前)
35 private $bbsEmail; // 入力再設定用(Eメールアドレス)
36 private $bbsMessage; // 入力再設定用(投稿メッセージ)
37 const DEFAULT_MENU_NAME = 'menu'; // スレッドメニューの名前
42 function __construct()
45 parent::__construct();
50 * _assign()でデータを埋め込むテンプレートファイルのファイル名を返す。
51 * 読み込むディレクトリは、「自ウィジェットディレクトリ/include/template」に固定。
53 * @param RequestManager $request HTTPリクエスト処理クラス
54 * @param object $param 任意使用パラメータ。そのまま_assign()に渡る
55 * @return string テンプレートファイル名。テンプレートライブラリを使用しない場合は空文字列「''」を返す。
57 function _setTemplate($request, &$param)
59 $act = $request->trimValueOf('act');
60 return 'main.tmpl.html';
65 * _setTemplate()で指定したテンプレートファイルにデータを埋め込む。
67 * @param RequestManager $request HTTPリクエスト処理クラス
68 * @param object $param 任意使用パラメータ。_setTemplate()と共有。
71 function _assign($request, &$param)
73 $act = $request->trimValueOf('act');
74 $postTicket = $request->trimValueOf('ticket'); // POST確認用
75 $this->threadId = $request->trimValueOf(M3_REQUEST_PARAM_BBS_THREAD_ID); // スレッドID
76 $message = $request->mobileTrimValueOf('bbs_message');// 投稿メッセージ
77 $name = $request->mobileTrimValueOf('bbs_name');// 名前
78 $email = $request->trimValueOf('bbs_email');// Eメールアドレス
80 if ($act == 'add'){ // 投稿追加のとき
81 if (!empty($postTicket) && $postTicket == $request->getSessionValue(M3_SESSION_POST_TICKET)){ // 正常なPOST値のとき
83 $this->checkMessageInput($this->_boardId, $this->threadId, $name, $email, $message);
86 if ($this->getMsgCount() == 0){
88 if (strcasecmp($email, self::DEFAULT_EMAIL_NOT_UPDATE) == 0){ // 日付更新を行わないとき
91 $updateDt = true; // 日付を更新
93 $ret = $this->_db->addMessage($this->_boardId, $this->threadId, $name, $email, $message, $updateDt, $newSerial);
95 if ($ret){ // データ追加成功のとき
96 //$this->setMsg(self::MSG_GUIDANCE, 'スレッドを作成しました');
97 $this->setMsg(self::MSG_GUIDANCE, '書きこみが終わりました。');
100 $this->tmpl->addVar("_widget", "name_disabled", 'disabled ');
101 $this->tmpl->addVar("_widget", "email_disabled", 'disabled ');
102 $this->tmpl->addVar("_widget", "subject_disabled", 'disabled ');
103 $this->tmpl->addVar("_widget", "message_disabled", 'disabled ');
104 $this->tmpl->addVar("_widget", "button_disabled", 'disabled ');
106 // スレッドが最大数に達したときはメッセージを追加
107 $ret = $this->_db->getThreadInfo($this->_boardId, $this->threadId, $row);
109 $resCount = $this->_configArray[self::CF_THREAD_RES];
110 if ($row['th_message_count'] >= $resCount){
111 $adminName = $this->_configArray[self::CF_ADMIN_NAME]; // サイト運営者名
112 if (empty($adminName)) $adminName = self::DEFAULT_ADMIN_NAME;
113 $overMessage = $this->_configArray[self::CF_THREAD_END_MESSAGE]; // デフォルトのレス上限メッセージ
114 if (empty($overMessage)) $overMessage = self::DEFAULT_THREAD_END_MESSAGE;
115 $overMessage = str_replace(M3_TAG_START . self::MACRO_RES_MAX_NO . M3_TAG_END, $resCount, $overMessage);// レス上限数を埋め込む
116 $ret = $this->_db->addMessage($this->_boardId, $this->threadId, $adminName, ''/*Eメール*/, $overMessage, $updateDt, $newSerial);
120 //$this->setMsg(self::MSG_APP_ERR, 'スレッドを作成に失敗しました');
121 $this->setMsg(self::MSG_APP_ERR, '書きこみに失敗しました。');
125 $this->bbsName = $name; // 入力再設定用(名前)
126 $this->bbsEmail = $email; // 入力再設定用(Eメールアドレス)
127 $this->bbsMessage = $message; // 入力再設定用(投稿メッセージ)
130 $this->setMsg(self::MSG_APP_ERR, '不正な投稿により、書きこみに失敗しました。');
132 $request->unsetSessionValue(M3_SESSION_POST_TICKET); // セッション値をクリア
135 $this->ticket = md5(time() . $this->gAccess->getAccessLogSerialNo());
136 $request->setSessionValue(M3_SESSION_POST_TICKET, $this->ticket); // セッションに保存
139 $this->createEmailLink = $this->_configArray[self::CF_SHOW_EMAIL]; // Eメールのリンクを作成するかどうか
140 $threadColor = $this->_configArray[self::CF_THREAD_COLOR]; // スレッド表示部背景色
141 $this->threadStyle .= 'background-color:' . $threadColor . ';';
142 //$this->tmpl->addVar("_widget", "thread_style", $this->threadStyle);
143 $makeThreadColor = $this->_configArray[self::CF_MAKE_THREAD_COLOR]; // スレッド作成部背景色
144 $makeThreadStyle .= 'background-color:' . $makeThreadColor . ';';
145 $this->subjectColor = $this->_configArray[self::CF_SUBJECT_COLOR]; // 件名文字色
146 $this->nameColor = $this->_configArray[self::CF_NAME_COLOR]; // 登録者名文字色
149 if (!empty($this->_configArray[self::CF_FILE_UPLOAD])){ // ファイルアップロード許可のとき
150 $this->tmpl->setAttribute('file_upload', 'visibility', 'visible');// ファイルアップロード領域追加
154 $this->threadCount = $this->_configArray[self::CF_THREAD_COUNT];
155 $this->_db->getThread(array($this, 'itemsLoop'), $this->_boardId, $this->_configArray[self::CF_MENU_THREAD_COUNT]/*メニューに表示するスレッド最大数*/);
158 // メッセージの最小インデックス番号を求める
159 $resCount = $this->_configArray[self::CF_RES_COUNT]; // トップ画面に表示するレス最大数
160 $minIndexArray = array();
161 for ($i = 0; $i < count($this->threadIdArray); $i++){
162 $minIndex = 2; // 2番目のメッセージ以降
163 if ($this->threadInfoArray[$i]['th_message_count'] > $resCount + 1) $minIndex = $this->threadInfoArray[$i]['th_message_count'] - $resCount + 1;
164 $minIndexArray[] = $minIndex;
166 $this->_db->getThreadMessage(array($this, 'messagesLoop'), $this->_boardId, $this->threadIdArray, $minIndexArray);
168 // スレッドが存在しないときはタグを非表示にする
169 if (!$this->isExistsMessage) $this->tmpl->setAttribute('thread_list', 'visibility', 'hidden');
172 $this->tmpl->addVar("_widget", "make_thread_style", $makeThreadStyle);
173 $this->tmpl->addVar("_widget", "menu_name", self::DEFAULT_MENU_NAME);// スレッドメニューの名前
174 $this->tmpl->addVar("_widget", "menu_anchor", '#' . self::DEFAULT_MENU_NAME);// スレッドメニューへのアンカーリンク
175 if ($this->isExistsMessage){
176 $firstAnchorTag = '<a href="#1">▼</a>';
178 $firstAnchorTag = '▼';
180 $this->tmpl->addVar("_widget", "first_anchor", $firstAnchorTag); // 最初のスレッドへのアンカーリンク
183 $bottomMessage = $this->_configArray[self::CF_BOTTOM_MESSAGE];
184 if (is_null($bottomMessage)) $bottomMessage = self::DEFAULT_BOTTOM_MESSAGE;
185 $this->tmpl->addVar("_widget", "bottom_message", $bottomMessage);
188 $this->tmpl->addVar("_widget", "post_url", $this->_currentPageUrl);
191 $this->tmpl->addVar("_widget", "ad", ""); // 広告バナー等
192 $this->tmpl->addVar("_widget", "spacer", "$this->_spacer"); // スペーサ
195 * 取得したスレッド件名をテンプレートに設定する
197 * @param int $index 行番号
198 * @param array $fetchedRow 取得行
199 * @param object $param 任意使用パラメータ
200 * @return bool trueを返すとループ続行。falseを返すとその時点で終了。
202 function itemsLoop($index, $fetchedRow)
206 $subject = $fetchedRow['th_subject'] . '(' . $fetchedRow['th_message_count'] . ')';
207 $threadLinkUrl = $this->_currentPageUrl . '&' . M3_REQUEST_PARAM_BBS_THREAD_ID . '=' . $fetchedRow['th_id'] . '&' . M3_REQUEST_PARAM_LIST_NO . '=l' . self::DEFAULT_LAST_MESSAGE_COUNT;
208 if ($index < $this->threadCount){
209 $subject = $no . ':</a><a href="#' . $no . '">' . $this->convertToDispString($subject);
212 $this->threadIdArray[] = $fetchedRow['th_id'];
215 $this->threadInfoArray[] = $fetchedRow;
217 $subject = $no . ':' . $this->convertToDispString($subject);
221 'url' => $this->convertUrlToHtmlEntity($this->getUrl($threadLinkUrl, true)), // スレッドリンク先
222 'subject' => $subject // スレッド件名
224 $this->tmpl->addVars('itemlist', $row);
225 $this->tmpl->parseTemplate('itemlist', 'a');
229 * 取得したスレッドメッセージをテンプレートに設定する
231 * @param int $index 行番号
232 * @param array $fetchedRow 取得行
233 * @param object $param 任意使用パラメータ
234 * @return bool trueを返すとループ続行。falseを返すとその時点で終了。
236 function messagesLoop($index, $fetchedRow)
238 static $threadIndex = 0;
240 $threadId = $fetchedRow['te_thread_id'];
241 $messageCount = $this->threadInfoArray[$threadIndex]['th_message_count']; // メッセージ総数
242 $no = $fetchedRow['te_index']; // メッセージインデックス番号
245 if ($no > $messageCount) return true;
247 $findLastMessage = false;
248 if ($no == $messageCount) $findLastMessage = true;// 最後のメッセージかどうか
250 // ##### メッセージ部分を作成 #####
252 $name = $this->convertToDispString($fetchedRow['te_user_name']); // ユーザ名
253 if (empty($name)) $name = $this->_configArray[self::CF_NONAME_NAME]; // 名前未設定時の表示名
254 $email = $this->convertToDispString($fetchedRow['te_email']); // Eメール
255 if (!empty($email) && !empty($this->createEmailLink)){ // Eメールリンク作成のとき
256 $name = '<a href="mailto:' . $email . '">' . $name . '</a>';
258 $name = '<span style="color:' . $this->nameColor . ';">' . $name . '</span>';
262 $weekDay = array('日', '月', '火', '水', '木', '金', '土');
263 $timestamp = strtotime($fetchedRow['te_regist_dt']);
264 $weekNo = intval(date('w', $timestamp));
265 $date = date('Y/m/d(' . $weekDay[$weekNo] . ') H:i:s', $timestamp);
268 $message = $this->convertToDispString($fetchedRow['te_message']);// 文字エスケープ処理
269 $message = $this->convertToPreviewText($message); // 改行をBRタグに変換
270 if ($fetchedRow['te_index'] == 1) $message .= '<br />'; // トップのメッセージは改行を追加
273 $message = $this->convDispMessage($message, $threadId);
276 if ($fetchedRow['te_deleted']){
278 $message = '参照できません。';
282 'no' => $no, // メッセージインデックス番号
283 'name' => $name, // 投稿者名
284 'date' => $date, // 投稿日付
285 'message' => $message // 投稿文
287 $this->tmpl->addVars('message_list', $row);
288 $this->tmpl->parseTemplate('message_list', 'a');
290 // ##### スレッドごとの出力 #####
291 if ($findLastMessage){ // 最後のメッセージの場合
292 $threadInfo = $this->threadInfoArray[$threadIndex];
293 $threadUrl = $this->_currentPageUrl . '&' . M3_REQUEST_PARAM_BBS_THREAD_ID . '=' . $threadId;
294 $thread50Url = $this->_currentPageUrl . '&' . M3_REQUEST_PARAM_BBS_THREAD_ID . '=' . $threadId . '&' . M3_REQUEST_PARAM_LIST_NO . '=l' . self::DEFAULT_LAST_MESSAGE_COUNT;
295 $thread100Url = $this->_currentPageUrl . '&' . M3_REQUEST_PARAM_BBS_THREAD_ID . '=' . $threadId . '&' . M3_REQUEST_PARAM_LIST_NO . '=' . self::DEFAULT_MESSAGE_COUNT_PER_PAGE;
296 $reloadUrl = $this->_currentPageUrl;
299 if ($threadIndex == 0){
300 $foreAnchor = '#' . count($this->threadIdArray);
301 if (count($this->threadIdArray) == 1){
304 $nextAnchor = '#' . ($threadIndex + 2);
306 } else if ($threadIndex < count($this->threadIdArray) -1){
307 $foreAnchor = '#' . $threadIndex;
308 $nextAnchor = '#' . ($threadIndex + 2);
310 $foreAnchor = '#' . $threadIndex;
315 $enctype = 'application/x-www-form-urlencoded';
316 if (!empty($this->_configArray[self::CF_FILE_UPLOAD])){ // ファイルアップロード許可のとき
317 $enctype = 'multipart/form-data';
320 $bbsName = ''; // 入力再設定用(名前)
321 $bbsEmail = ''; // 入力再設定用(Eメールアドレス)
322 $bbsMessage = ''; // 入力再設定用(投稿メッセージ)
323 if ($this->threadId == $threadId){
324 if (!empty($this->bbsName)) $bbsName = $this->bbsName; // 入力再設定用(名前)
325 if (!empty($this->bbsEmail)) $bbsEmail = $this->bbsEmail; // 入力再設定用(Eメールアドレス)
326 if (!empty($this->bbsMessage)) $bbsMessage = $this->bbsMessage; // 入力再設定用(投稿メッセージ)
329 'bbs_name' => $this->convertToDispString($bbsName), // 入力再設定用(名前)
330 'bbs_email' => $this->convertToDispString($bbsEmail), // 入力再設定用(Eメールアドレス)
331 'bbs_message' => $this->convertToDispString($bbsMessage), // 入力再設定用(投稿メッセージ)
332 'enctype' => $enctype, // ファイルアップロード領域
333 'index' => $threadIndex + 1, // スレッドインデックス番号
334 'menu_anchor' => '#' . self::DEFAULT_MENU_NAME, // スレッドメニューへのアンカーリンク
335 'fore_anchor' => $foreAnchor, // 前スレッドリンク
336 'next_anchor' => $nextAnchor, // 次スレッドリンク
337 'message_count' => $threadInfo['th_message_count'], // メッセージ総数
338 'thread_id' => $threadId, // スレッドID
339 'subject' => $this->convertToDispString($threadInfo['th_subject']), // スレッド件名
340 'subject_color' => $this->subjectColor, // 件名表示色
341 'thread_style' => $this->threadStyle, // スレッド表示スタイル
342 'thread_url' => $this->convertUrlToHtmlEntity($this->getUrl($threadUrl, true)), // スレッド全表示URL
343 'thread50_url' => $this->convertUrlToHtmlEntity($this->getUrl($thread50Url, true)), // スレッド最新50表示URL
344 'thread100_url' => $this->convertUrlToHtmlEntity($this->getUrl($thread100Url, true)), // スレッド100まで表示URL
345 'reload_url' => $this->convertUrlToHtmlEntity($this->getUrl($reloadUrl, true)), // 画面再表示
346 'post_url' => $this->_currentPageUrl, // POST先URL
347 'ticket' => $this->ticket, // POST確認用ハッシュキー
348 'spacer' => $this->_spacer // スペーサ
350 $this->tmpl->addVars('thread_list', $row);
351 $this->tmpl->parseTemplate('thread_list', 'a');
353 $this->tmpl->clearTemplate('message_list'); // メッセージを一旦クリア
357 $this->isExistsMessage = true;