OSDN Git Service

初回コミット(v2.6.17.1)
[magic3/magic3.git] / widgets / reserve_main / include / container / reserve_mainReserveWidgetContainer.php
1 <?php
2 /**
3  * コンテナクラス
4  *
5  * PHP versions 5
6  *
7  * LICENSE: This source file is licensed under the terms of the GNU General Public License.
8  *
9  * @package    Magic3 Framework
10  * @author     平田直毅(Naoki Hirata) <naoki@aplo.co.jp>
11  * @copyright  Copyright 2006-2008 Magic3 Project.
12  * @license    http://www.gnu.org/copyleft/gpl.html  GPL License
13  * @version    SVN: $Id: reserve_mainReserveWidgetContainer.php 5056 2012-07-23 02:50:32Z fishbone $
14  * @link       http://www.magic3.org
15  */
16 require_once($gEnvManager->getContainerPath() .                 '/baseWidgetContainer.php');
17 require_once($gEnvManager->getCurrentWidgetDbPath() .   '/reserve_mainDb.php');
18 require_once(CALENDAR_ROOT                      . 'Month/Weekdays.php');
19
20 class reserve_mainReserveWidgetContainer extends BaseWidgetContainer
21 {
22         private $db;    // DB接続オブジェクト
23         private $sysDb;         // システムDBオブジェクト
24         private $langId;        // 表示言語
25         private $serialNo;                      // シリアル番号
26         private $hour;          // 予約時間
27         private $minute;                // 予約時間(分)
28         private $reserveDateArray = array();            // 予約日
29         private $viewMinHour;                   // 最小時間
30         private $viewMaxHour;                   // 最大時間
31         private $availableTime = array();       // 選択可能時間
32         private $unitIntervalMinute;            // 単位時間(分)
33         private $maxUserReserveCount;                   // 1ユーザの予約可能数
34         private $maxCountPerUnit;                               // 1単位あたりの予約可能数
35         private $defaultResouceId;                              // デフォルトのリソースID
36         private $cancelAvailableDay;                    // 予約キャンセル可能な日数
37         const DEFAULT_CONFIG_ID = 0;            // デフォルト定義ID
38         const UNIT_INTERVAL_MINUTE = 'unit_interval_minute';    // 単位時間(分)
39         const MAX_USER_RESERVE_COUNT = 'max_user_reserve_count';        // 最大ユーザ予約可能数
40         const MAX_COUNT_PER_UNIT = 'max_count_per_unit';                        // 1単位あたりの登録可能数
41         const DEFAULT_RESOURCE_ID = 'default_resource_id';                      // デフォルトのリソースID
42         const CANCEL_AVAILABLE_DAY = 'cancel_available_day';            // 予約キャンセル可能な日数
43         
44         /**
45          * コンストラクタ
46          */
47         function __construct()
48         {
49                 global $gInstanceManager;
50                         
51                 // 親クラスを呼び出す
52                 parent::__construct();
53                 
54                 // DBオブジェクト作成
55                 $this->db = new reserve_mainDb();
56                 $this->sysDb = $gInstanceManager->getSytemDbObject();
57                 
58                 $this->unitIntervalMinute       = $this->db->getReserveConfig(self::DEFAULT_CONFIG_ID, self::UNIT_INTERVAL_MINUTE);             // 1単位あたりの時間
59                 $this->maxUserReserveCount      = $this->db->getReserveConfig(self::DEFAULT_CONFIG_ID, self::MAX_USER_RESERVE_COUNT);           // 1ユーザ登録可能な予約数
60                 $this->maxCountPerUnit          = $this->db->getReserveConfig(self::DEFAULT_CONFIG_ID, self::MAX_COUNT_PER_UNIT);               // 1単位あたりの予約可能数
61                 $this->defaultResouceId = $this->db->getReserveConfig(self::DEFAULT_CONFIG_ID, self::DEFAULT_RESOURCE_ID);              // デフォルトのリソースID
62                 $this->cancelAvailableDay       = $this->db->getReserveConfig(self::DEFAULT_CONFIG_ID, self::CANCEL_AVAILABLE_DAY);             // 予約キャンセル可能な日数
63         }
64         /**
65          * テンプレートファイルを設定
66          *
67          * _assign()でデータを埋め込むテンプレートファイルのファイル名を返す。
68          * 読み込むディレクトリは、「自ウィジェットディレクトリ/include/template」に固定。
69          *
70          * @param RequestManager $request               HTTPリクエスト処理クラス
71          * @param object         $param                 任意使用パラメータ。そのまま_assign()に渡る
72          * @return string                                               テンプレートファイル名。テンプレートライブラリを使用しない場合は空文字列「''」を返す。
73          */
74         function _setTemplate($request, &$param)
75         {
76                 return 'reserve.tmpl.html';
77         }
78         /**
79          * テンプレートにデータ埋め込む
80          *
81          * _setTemplate()で指定したテンプレートファイルにデータを埋め込む。
82          *
83          * @param RequestManager $request               HTTPリクエスト処理クラス
84          * @param object         $param                 任意使用パラメータ。_setTemplate()と共有。
85          * @param                                                               なし
86          */
87         function _assign($request, &$param)
88         {
89                 global $gEnvManager;
90                 global $gAccessManager;
91                 global $gPageManager;
92                 
93                 // デフォルト値取得
94                 $now = date("Y/m/d H:i:s");     // 現在日時
95                 $today = date("Y/m/d"); // 現在日付
96                 $this->langId   = $gEnvManager->getCurrentLanguage();           // 表示言語を取得
97                 $userId = $gEnvManager->getCurrentUserId();
98                 
99                 // 予約可能時間範囲を取得
100                 $this->getAvailableTime();
101                 
102                 $act = $request->trimValueOf('act');
103                 $this->serialNo = $request->trimValueOf('serial');              // 選択項目のシリアル番号
104                                 
105                 // 年月を取得
106                 // 空の場合は、予約日があれば予約日の月のカレンダーを表示
107                 $showReservedDate = false;              // 予約日のあるカレンダーを表示するかどうか
108                 $year = $request->trimValueOf('year');          // 年指定
109                 if (!(is_numeric($year) && 1 <= $year)){                        // エラー値のとき
110                         $year = date('Y');
111                         $showReservedDate = true;               // 予約日のあるカレンダーを表示するかどうか
112                 }
113                 $month = $request->trimValueOf('month');        // 月指定
114                 if (!(is_numeric($month) && 1 <= $month && $month <= 12)){                      // エラー値のとき
115                         $month = date('n');
116                         $showReservedDate = true;               // 予約日のあるカレンダーを表示するかどうか
117                 }
118                 
119                 // 入力値を取得
120                 $reserveDate                    = $request->trimValueOf('reserve_date');
121                 if (!empty($reserveDate)) $reserveDate = $this->convertToProperDate($reserveDate);                      // 予約日時
122                 $this->hour = $request->trimValueOf('time_hour');
123                 if ($this->hour == '') $this->hour = -1;
124                 $this->minute = $request->trimValueOf('time_minute');
125                 if ($this->minute == '') $this->minute = -1;
126                 
127                 if ($act == 'new'){             // 新規予約
128                         // 入力チェック
129                         $this->checkDate($reserveDate, '予約日付');
130                         if ($this->hour == -1) $this->setUserErrorMsg('予約時間(時)が選択されていません');
131                         if ($this->minute == -1) $this->setUserErrorMsg('予約時間(分)が選択されていません');
132                         
133                         // 予約日時
134                         $reserveDateTime = $reserveDate . ' ' . $this->hour . ':' . $this->minute;
135                         $reserveHourMinute = $this->hour * 100 + $this->minute;
136                         
137                         // 予約可能かチェック
138                         // 本日以降
139                         if ($this->getMsgCount() == 0){
140                                 if (strtotime(date("Y/m/d")) >= strtotime($reserveDate)) $this->setUserErrorMsg('明日以降を選択してください');
141                         }
142                         
143                         // 営業時間範囲
144                         if ($this->getMsgCount() == 0){
145                                 // 曜日を取得
146                                 $week = date("w", strtotime($reserveDate));
147                                 $hourMinute             = $this->availableTime[$week];                  // 設定時分を取得
148                                 $startHour              = $hourMinute[0][0];
149                                 $startMinute    = $hourMinute[0][1];
150                                 $endHour                = $hourMinute[0][2];
151                                 $endMinute              = $hourMinute[0][3];
152                                 $startHour2             = $hourMinute[1][0];
153                                 $startMinute2   = $hourMinute[1][1];
154                                 $endHour2               = $hourMinute[1][2];
155                                 $endMinute2             = $hourMinute[1][3];
156
157                                 switch ($week){
158                                         case 0: $weekName = '日曜日'; break;
159                                         case 1: $weekName = '月曜日'; break;
160                                         case 2: $weekName = '火曜日'; break;
161                                         case 3: $weekName = '水曜日'; break;
162                                         case 4: $weekName = '木曜日'; break;
163                                         case 5: $weekName = '金曜日'; break;
164                                         case 6: $weekName = '土曜日'; break;
165                                 }
166                                 $msg = $weekName;
167                                 if ($startHour == -1 && $startHour2 == -1){
168                                         // 休日をチェック
169                                         $msg .= 'はお休みです';
170                                         $this->setUserErrorMsg($msg);
171                                 } else if (!($startHour != -1 && ($startHour * 100 + $startMinute <= $reserveHourMinute && $reserveHourMinute < $endHour * 100 + $endMinute)) &&
172                                         !($startHour2 != -1 && ($startHour2 * 100 + $startMinute2 <= $reserveHourMinute && $reserveHourMinute < $endHour2 * 100 + $endMinute2))){
173                                         // 営業時間をチェック
174                                         $msg .= 'の時間の指定可能範囲は&nbsp;';
175                                         if ($startHour != -1) $msg .= $startHour . '時' . $startMinute . '分~' . $endHour . '時' . $endMinute . '分';
176                                         if ($startHour2 != -1) $msg .= '<br>または&nbsp;' . $startHour2 . '時' . $startMinute2 . '分~' . $endHour2 . '時' . $endMinute2 . '分';
177                                         $msg .= 'です';
178                                         $this->setUserErrorMsg($msg);
179                                 }
180                         }
181                         
182                         // 同じ日時の予約可能最大数
183                         if ($this->getMsgCount() == 0){
184                                 $reserveCount = $this->db->getReserveStatusCountByDateTime($this->defaultResouceId, 0, $reserveDateTime, 1/*予約状態*/);
185                                 if ($reserveCount >= $this->maxCountPerUnit) $this->setUserErrorMsg('この時間は予約がいっぱいです');
186                         }
187                         // 同ユーザがすでに登録済みかどうかチェック
188                         if ($this->getMsgCount() == 0){
189                                 $reserveCount = $this->db->getReserveStatusCountByDateTime($this->defaultResouceId, $userId, $reserveDateTime, 1/*予約状態*/);
190                                 if ($reserveCount >= 1) $this->setUserErrorMsg('この時間にすでに予約があります');
191                         }
192                         // 1ユーザの最大登録可能数
193                         //if ($this->getMsgCount() == 0){
194                         //      $reserveCount = $this->db->getReserveStatusCountByDateTime($this->defaultResouceId, $userId, $reserveDateTime, 1/*予約状態*/);
195                         //      if ($reserveCount >= $this->maxUserReserveCount) $this->setUserErrorMsg('予約可能最大数を超えています');
196                         //}
197                                 
198                         // エラーなしの場合
199                         if ($this->getMsgCount() == 0){
200                                 $date = $reserveDate . ' ' . $this->hour . ':' . $this->minute . ':0';
201                                 $note = '';             // 備考
202                                 $ret = $this->db->addReserveStatus($this->defaultResouceId, $userId, $date, 1/*予約*/, $note, $newSerial);
203                                 if ($ret){
204                                         $this->setGuidanceMsg('予約が完了しました');
205                                         
206                                         // 入力値初期化
207                                         $reserveDate = '';
208                                         $this->hour = -1;
209                                         $this->minute = -1;
210                                 } else {
211                                         $this->setAppErrorMsg('予約に失敗しました');
212                                 }
213                         }
214                 } else if ($act == 'cancel'){                   // 予約キャンセルのとき
215                         $note = '';
216                         $ret = $this->db->updateReserveStatus($this->serialNo, $this->defaultResouceId, $userId, 2/*キャンセル*/, $note);
217                         if ($ret){
218                                 $this->setGuidanceMsg('予約をキャンセルしました');
219                         } else {
220                                 $this->setAppErrorMsg('予約キャンセルに失敗しました');
221                         }
222                 } else if ($act == 'logout'){                   // ログアウトのとき
223                         $gAccessManager->userLogout();
224                         
225                         // 画面を全体を再表示する
226                         $gPageManager->redirect($gEnvManager->createCurrentPageUrl());
227                         return;
228                 } else {
229                 }
230                 // 予約状況を取得
231                 $canCancelReserve = false;              // 予約キャンセルできるかどうか
232                 $canNewReserve = false;                         // 新規予約できるかどうか
233                 $reservedDate = '予約はありません';
234                 $ret = $this->db->getReserveStatus($this->defaultResouceId, $userId, $today, 1/*予約中*/, $rows);
235                 if ($ret){      // データが取得できたとき
236                         // シリアル番号
237                         $this->serialNo = $rows[0]['rs_serial'];
238                         
239                         // 最近の予約を取得
240                         $this->timestampToYearMonthDay($rows[0]['rs_start_dt'], $reserveYear, $reserveMonth, $reserveDay);
241                         $this->timestampToHourMinuteSecond($rows[0]['rs_start_dt'], $reserveHour, $reserveMinute, $reserveSecond);
242                         $reservedDate = $reserveYear . '年 ' . $reserveMonth . '月 ' . $reserveDay . '日 ' . $reserveHour. '時 ' . $reserveMinute . '分';
243                         
244                         // 予約日を保存
245                         $this->reserveDateArray[] = $reserveYear . '/' . $reserveMonth . '/' . $reserveDay;
246                         
247                         // 明日以降の予約はキャンセル可能
248                         if (strtotime(date("Y/m/d")) < strtotime($reserveYear . '/' . $reserveMonth . '/' . $reserveDay)) $canCancelReserve = true;
249                 } else {
250                         // 予約がない場合は新規予約可能
251                         $canNewReserve = true;                          // 新規予約できるかどうか
252                         $showReservedDate = false;              // 予約日のあるカレンダーを表示するかどうか
253                 }
254                 
255                 // カレンダーの表示を修正
256                 if ($showReservedDate){         // 予約日のあるカレンダーを表示するかどうか
257                         if (count($this->reserveDateArray) > 0){
258                                 $year = $reserveYear;
259                                 $month = $reserveMonth;
260                         }
261                 }
262
263                 // カレンダーを作成
264                 $calendarData = $this->createCalendar($year, $month);
265                 $this->tmpl->addVar("_widget", "calendar", $calendarData);
266                 
267                 // ログインユーザの表示
268                 $userName = $gEnvManager->getCurrentUserName();
269                 $this->tmpl->addVar("_widget", "login_status", $userName . ' 様');
270                 
271                 // 新規登録用
272                 $this->createTimeMenu();                // 時間メニュー
273
274                 // ボタンの設定
275                 // 新規予約できないとき
276                 if (!$canNewReserve) $this->tmpl->addVar("_widget", "new_button_disabled", 'disabled');         // ボタン使用不可
277                 // 予約キャンセル可能なとき
278                 if ($canCancelReserve) $this->tmpl->setAttribute('cancel_button', 'visibility', 'visible');
279                 
280                 // データを埋め込む
281                 $todayDate = intval(date("Y")) . '年 ' . intval(date("m")) . '月 ' . intval(date("d")) . '日';
282                 $this->tmpl->addVar("_widget", "reserved_date", $reservedDate);                 // 予約月日登録済み
283                 $this->tmpl->addVar("_widget", "reserve_date", $reserveDate);                   // 予約月日登録用
284                 $this->tmpl->addVar("_widget", "today_date", $todayDate);                       // 本日
285                 $this->tmpl->addVar("_widget", "serial", $this->serialNo);
286                 
287                 // ディレクトリを設定
288                 $this->tmpl->addVar("_widget", "script_url", $gEnvManager->getScriptsUrl());
289         }
290         /**
291          * カレンダーを作成
292          *
293          * @param int         $year                     年
294          * @param int         $month            月
295          * @param string                                        生成したカレンダー
296          */
297         function createCalendar($year, $month)
298         {       
299                 global $gPageManager;
300                 global $gEnvManager;
301                 
302                 // 今日を取得
303                 $nowYear = date("Y");
304                 $nowMonth = date("m");
305                 $nowDay = date("d");
306                                 
307                 $calendar = new Calendar_Month_Weekdays($year, $month, 0);              // 日曜日を先頭にする
308                 $calendar->build();
309                 $prevMonth = $calendar->prevMonth();
310                 $nextMonth = $calendar->nextMonth();
311                 if ($prevMonth == 12){
312                         $prevYear = $year -1;
313                 } else {
314                         $prevYear = $year;
315                 }
316                 if ($nextMonth == 1){
317                         $nextYear = $year +1;
318                 } else {
319                         $nextYear = $year;
320                 }
321                 // データの存在する日を取得
322                 $startDt = $this->convertToProperDate($year . '/' . $month . '/1');
323                 $endDt = $this->convertToProperDate($nextYear . '/' . $nextMonth . '/1');
324
325                 // 前月、次月リンク作成
326                 $prevUrl = $gEnvManager->createCurrentPageUrl() . '&task=reserve&year=' . $prevYear . '&month=' . $prevMonth;
327                 $nextUrl = $gEnvManager->createCurrentPageUrl() . '&task=reserve&year=' . $nextYear . '&month=' . $nextMonth;
328
329                 $calendarData = '';
330                 $calendarData .= '<table class="reserve_calendar">' . M3_NL;
331                 $calendarData .= '<div align="center">' . M3_NL;
332                 $calendarData .= '<a href="' . $prevUrl . '">' . $prevMonth. '</a>' . M3_NL;
333                 $calendarData .= ' | ' . $year . '/' . $month . ' | ' . M3_NL;
334                 $calendarData .= '<a href="' . $nextUrl . '">' . $nextMonth . '</a>' . M3_NL;
335                 $calendarData .= '</div>' . M3_NL;
336                 $calendarData .= '<tr>' . M3_NL;
337                 $calendarData .= '<th class="sun">日</th>' . M3_NL;
338                 $calendarData .= '<th class="*">月</th>' . M3_NL;
339                 $calendarData .= '<th>火</th>' . M3_NL;
340                 $calendarData .= '<th>水</th>' . M3_NL;
341                 $calendarData .= '<th>木</th>' . M3_NL;
342                 $calendarData .= '<th>金</th>' . M3_NL;
343                 $calendarData .= '<th class="sat">土</th>' . M3_NL;
344                 $calendarData .= '</tr>' . M3_NL;
345                 
346                 $week = 0;              // 曜日
347                 while ($Day = $calendar->fetch()) {
348                     if ($Day->isFirst()) {
349                         $calendarData .= '<tr>' . M3_NL;
350                                 $week = 0;              // 曜日を初期化
351                     }
352
353                     if ($Day->isEmpty()) {
354                         $calendarData .= '<td>&nbsp;</td>' . M3_NL;
355                     } else {
356                                 $date = intval($year) . '/' . intval($month) . '/' . $Day->thisDay();
357                                 if (in_array($date, $this->reserveDateArray)){                  // 予約ありのとき
358                                         $weekStr = ' class="select"';
359                                 $calendarData .= '<td' . $weekStr . '>' . $Day->thisDay() . '</td>' . M3_NL;
360                                 } else if ($nowYear == $year && $nowMonth == $month && $nowDay == $Day->thisDay()){
361                                         $weekStr = ' class="today"';
362                                 $calendarData .= '<td' . $weekStr . '>' . $Day->thisDay() . '</td>' . M3_NL;
363                                 } else {
364                                         $weekStr = '';
365                                         if ($week == 0){                // 日曜日のとき
366                                                 $weekStr = ' class="sun"';
367                                         } else if ($week == 6){         // 土曜日のとき
368                                                 $weekStr = ' class="sat"';
369                                         }
370                                 $calendarData .= '<td' . $weekStr . '>' . $Day->thisDay() . '</td>' . M3_NL;
371                                 }
372                     }
373                         $week++;                // 曜日を更新
374                         
375                     if ($Day->isLast()) {
376                         $calendarData .= '</tr>' . M3_NL;
377                     }
378                 }
379                 $calendarData .= '</table></div>' . M3_NL;
380                 return $calendarData;
381         }
382         /**
383          * 時間メニューを作成
384          *
385          * @return なし
386          */
387         function createTimeMenu()
388         {
389                 // 1時間あたりの分割数
390                 $unitCount = 60 / $this->unitIntervalMinute;
391                 
392                 // 時メニュー作成
393                 for ($j = $this->viewMinHour; $j < $this->viewMaxHour; $j++){
394                         $selected = '';
395                         if ($j == $this->hour) $selected = 'selected';
396                         $row = array(
397                                 'value'    => $j,                       // 値
398                                 'name'     => $j,                       // 表示名
399                                 'selected' => $selected         // 選択中かどうか
400                         );
401                         $this->tmpl->addVars('time_hour', $row);
402                         $this->tmpl->parseTemplate('time_hour', 'a');
403                 }
404                 // 分メニュー作成
405                 for ($j = 0; $j < $unitCount; $j++){
406                         $minute = $this->unitIntervalMinute * $j;
407                         $selected = '';
408                         if ($minute == $this->minute) $selected = 'selected';
409                         $row = array(
410                                 'value'    => $minute,                  // 値
411                                 'name'     => $minute,                  // 表示名
412                                 'selected' => $selected         // 選択中かどうか
413                         );
414                         $this->tmpl->addVars('time_minute', $row);
415                         $this->tmpl->parseTemplate('time_minute', 'a');
416                 }
417         }
418         /**
419          * 予約可能範囲を取得
420          *
421          * @return なし
422          */
423         function getAvailableTime()
424         {
425                 // 設定値を取得
426                 $ret = $this->db->getCalendarByWeek(self::DEFAULT_CONFIG_ID, $rows);
427                 if ($ret){
428                         // データ初期化
429                         $newAvailableTime = array();
430                         for ($i = 0; $i < 7; $i++){
431                                 $newAvailableTime[] = array(array(-1, -1, -1, -1), array(-1, -1, -1, -1));
432                         }
433                         // 最小、最大表示時間
434                         $this->viewMinHour = 24;                        // 最小時間
435                         $viewMaxHourMinute = 0;                 // 最大時間
436                         for ($i = 0; $i < count($rows); $i++){
437                                 // 時間を解析
438                                 $startHour              = intval($rows[$i]['ra_start_time'] / 100);
439                                 $startMinute    = $rows[$i]['ra_start_time'] - $startHour * 100;
440                                 $endHour                = intval($rows[$i]['ra_end_time'] / 100);
441                                 $endMinute              = $rows[$i]['ra_end_time'] - $endHour * 100;
442
443                                 // 最小、最大表示時間更新
444                                 if ($this->viewMinHour > $startHour) $this->viewMinHour = $startHour;
445                                 if ($viewMaxHourMinute < $endHour * 100 + $endMinute) $viewMaxHourMinute = $endHour * 100 + $endMinute;
446                                 
447                                 if ($rows[$i]['ra_specify_type'] == 1){         // 曜日指定のとき
448                                         $attr = $rows[$i]['ra_day_attribute'] -1;               // 曜日取得
449                                         if ($newAvailableTime[$attr][0][0] == -1){      // 前半データ
450                                                 $newAvailableTime[$attr][0][0] = $startHour;
451                                                 $newAvailableTime[$attr][0][1] = $startMinute;
452                                                 $newAvailableTime[$attr][0][2] = $endHour;
453                                                 $newAvailableTime[$attr][0][3] = $endMinute;
454                                         } else {                // 後半データ
455                                                 $newAvailableTime[$attr][1][0] = $startHour;
456                                                 $newAvailableTime[$attr][1][1] = $startMinute;
457                                                 $newAvailableTime[$attr][1][2] = $endHour;
458                                                 $newAvailableTime[$attr][1][3] = $endMinute;
459                                         }
460                                 }
461                         }
462                         // 最小、最大表示時間更新
463                         if ($viewMaxHourMinute > (int)($viewMaxHourMinute / 100) * 100){
464                                 $this->viewMaxHour = (int)($viewMaxHourMinute / 100) + 1;
465                         } else {
466                                 $this->viewMaxHour = (int)($viewMaxHourMinute / 100);
467                         }
468                         if ($this->viewMaxHour > 24) $this->viewMaxHour = 24;
469                         
470                         // 取得値を更新
471                         $this->availableTime = $newAvailableTime;
472                 }
473         }
474 }
475 ?>