OSDN Git Service

携帯関係のウィジェット、テンプレートを削除。
[magic3/magic3.git] / include / manager / requestManager.php
1 <?php
2 /**
3  * HTTPリクエスト、レスポンス、セッション管理マネージャー
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-2017 Magic3 Project.
12  * @license    http://www.gnu.org/copyleft/gpl.html  GPL License
13  * @version    SVN: $Id$
14  * @link       http://www.magic3.org
15  */
16 require_once(M3_SYSTEM_INCLUDE_PATH . '/common/core.php');
17
18 class RequestManager extends Core
19 {
20         private $db;                                            // DBオブジェクト
21         private $tmpCookie;             // クッキー送信前のクッキー格納データ
22         private $magicQuote;    // バックスラッシュでの文字エスケープ処理
23         private $sessionNoUpdate;               // セッションの更新を停止するかどうか(参照は可能)
24         private $sessionOpenEventCallbacks;             // セッション開始イベントコールバック関数
25         private $sessionCloseEventCallbacks;            // セッション終了イベントコールバック関数
26         
27         /**
28          * コンストラクタ
29          */
30         function __construct()
31         {
32                 // 親クラスを呼び出す
33                 parent::__construct();
34                 
35                 // システムDBオブジェクト取得
36                 $this->db = $this->gInstance->getSytemDbObject();
37                 
38                 // セッションハンドラ設定
39                 // セッションDBが使用可能な場合は、ハンドラを設定し、
40                 // 使用不可の場合は、デフォルトのセッション管理を使用する
41                 if (M3_SESSION_DB && $this->gEnv->canUseDbSession()){
42                         ini_set('session.save_handler', 'user');                // 追加(2008/7/7)
43                         session_set_save_handler(       array($this, '_sessionOpen'),
44                                                                                 array($this, '_sessionClose'),
45                                                                                 array($this, '_sessionRead'),
46                                                                                 array($this, '_sessionWrite'),
47                                                                                 array($this, '_sessionDestroy'),
48                                                                                 array($this, '_sessionGc'));
49                                                                                 
50                         // シャットダウン時の処理(2015/12/21 追加)
51                         if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
52                                 session_register_shutdown();
53                         } else {
54                                 register_shutdown_function('session_write_close');
55                         }
56                 }
57                 
58                 // その他パラメータ初期化
59                 $this->tmpCookie = array();             // クッキー送信前のクッキー格納データ
60                 $this->sessionOpenEventCallbacks = array();             // セッション開始イベントコールバック関数
61                 $this->sessionCloseEventCallbacks = array();    // セッション終了イベントコールバック関数
62                 
63                 // magic quoteが有効の場合は回避手段を取る
64                 if (get_magic_quotes_gpc() == 1) $this->magicQuote = true;
65         }
66         /**
67          * POST値が設定されているか判断
68          */
69         public function isPost($name)
70         {
71                 return isset($_POST[$name]);
72         }
73         /**
74          * GET値が設定されているか判断
75          */
76         public function isGet($name)
77         {
78                 return isset($_GET[$name]);
79         }
80         /**
81          * POST値取得
82          */
83         public function valueOfPost($name)
84         {
85                 return self::isPost($name) ? $_POST[$name] : '';
86         }
87         /**
88          * POST値取得(トリミング(前後の空白削除)あり)
89          */
90         public function trimValueOfPost($name)
91         {
92                 $value = self::isPost($name) ? $_POST[$name] : '';
93                 return $this->_trimValueOf($name, $value);
94         }
95         /**
96          * GET値取得
97          */
98         public function valueOfGet($name)
99         {
100                 return self::isGet($name) ? $_GET[$name] : '';
101         }
102         /**
103          * GET値取得(トリミング(前後の空白削除)あり)
104          */
105         public function trimValueOfGet($name)
106         {
107                 $value = self::isGet($name) ? $_GET[$name] : '';
108                 return $this->_trimValueOf($name, $value);
109         }
110         /**
111          * POST,GETから値を取得
112          *
113          * POSTまたはGETから値を取得
114          *
115          * @param string $name          キー値
116          * @param string $default       値が存在しないときのデフォルト値
117          * @return string                       取得値
118          */
119         public function valueOf($name, $default = '')
120         {
121                 //return isset($_POST[$name]) ? $_POST[$name] : (isset($_GET[$name]) ? $_GET[$name] : $default);
122                 //return self::gpc_stripslashes(isset($_POST[$name]) ? $_POST[$name] : (isset($_GET[$name]) ? $_GET[$name] : $default));
123                 return $this->gpc_stripslashes(isset($_POST[$name]) ? $_POST[$name] : (isset($_GET[$name]) ? $_GET[$name] : $default));
124         }
125         /**
126          * POST,GETから値を取得(トリミング(前後の空白削除)あり)
127          *
128          * POSTまたはGETから値を取得し、トリミング(前後の空白削除)する
129          * デフォルトでHTMLタグを取り除く
130          *
131          * @param string $name          キー値
132          * @param string $default       値が存在しないときのデフォルト値
133          * @return string                       取得値
134          */
135         public function trimValueOf($name, $default = '')
136         {
137                 $srcValue = isset($_POST[$name]) ? $_POST[$name] : (isset($_GET[$name]) ? $_GET[$name] : $default);
138                 return $this->_trimValueOf($name, $srcValue, $default);
139         }
140         /**
141          * POST,GETから値をint値を取得(トリミング(前後の空白削除)あり)
142          *
143          * POSTまたはGETから値を取得し、トリミング(前後の空白削除)する
144          * デフォルトでHTMLタグを取り除く
145          *
146          * @param string $name          キー値
147          * @param string $default       値が存在しないとき、値が空文字列のときのデフォルト値
148          * @return string                       取得値
149          */
150         //public function trimIntValueOf($name, $default = '')
151         public function trimIntValueOf($name, $default)                 // デフォルト値必須(2015/2/13)
152         {
153                 $srcValue = isset($_POST[$name]) ? $_POST[$name] : (isset($_GET[$name]) ? $_GET[$name] : $default);
154                 return $this->_trimValueOf($name, $srcValue, $default, 1/* int型チェック */);
155         }
156         /**
157          * POST,GETから値をチェックボックスの値を取得(トリミング(前後の空白削除)あり)
158          *
159          * POSTまたはGETから値を取得し、トリミング(前後の空白削除)する
160          * デフォルトでHTMLタグを取り除く
161          *
162          * @param string $name          キー値
163          * @param string $default       値が存在しないときのデフォルト値
164          * @return string                       取得値(0または1)
165          */
166         public function trimCheckedValueOf($name, $default = '')
167         {
168                 $srcValue = isset($_POST[$name]) ? $_POST[$name] : (isset($_GET[$name]) ? $_GET[$name] : $default);
169                 $checked = $this->_trimValueOf($name, $srcValue, $default);
170                 return ($checked == 'on') ? '1' : '0';
171         }
172         /**
173          * トリミング(前後の空白削除)処理
174          *
175          * デフォルトで不正な文字(HTMLタグ等)を取り除く
176          *
177          * @param string $name          キー値
178          * @param string $value         値
179          * @param string $default       値が存在しないときのデフォルト値
180          * @param int $ckeckType        値の型のチェックタイプ(0=型チェックなし、1=int型)
181          * @return string                       取得値
182          */
183         public function _trimValueOf($name, $value, $default='', $ckeckType=0)
184         {
185                 // トリムをかける
186                 if (is_array($value)){
187                         $trimValue = array_map('trim', $value);
188                         $destValue = array();
189                         foreach (array_keys($trimValue) as $key){
190                                 $stripValue = $this->gpc_stripslashes($trimValue[$key]);
191                                 $stripValue = strip_tags($stripValue);
192
193                                 // 危険性の高いその他変換。問題がある場合は文字列をクリアする
194                                 $saveValue = $stripValue;
195                                 $stripValue = $this->_convSafeText($stripValue);
196                                 if ($stripValue != $saveValue) $stripValue = '';
197
198                                 $isValid = false;
199                                 if (strlen($stripValue) == strlen($trimValue[$key])){           // 文字列長が同じとき
200                                         if ($ckeckType == 1){           // int型チェック
201                                                 if ($stripValue == ''){                         // 空文字列の場合はエラーと見なさない(2015/2/19 追加)
202                                                         $isValid = true;
203                                                 } else if (is_numeric($stripValue) && !strstr($stripValue, '.')){
204                                                         $isValid = true;
205                                                 } else {        // エラーの場合は値を修正
206                                                         $stripValue = '';
207                                                 }
208                                         } else {
209                                                 $isValid = true;
210                                         }
211                                 }
212                                 
213                                 // エラーがある場合はログを残す
214                                 if (!$isValid){
215                                         // ウィジェット内での処理の場合はウィジェットIDも出力
216                                         $widgetId = $this->gEnv->getCurrentWidgetId();// ウィジェットID
217                                         if (empty($widgetId)){
218                                                 $this->gOpeLog->writeUserData(__METHOD__, 'POSTまたはGET値の異常データを検出しました。', 2010, 'name=' . $name . ', value=[' . $value[$key] . ']');
219                                         } else {                // ウィジェットIDが設定されているとき
220                                                 $this->gOpeLog->writeUserData(__METHOD__, 'POSTまたはGET値の異常データを検出しました。', 2011, 'name=' . $name . ', value=[' . $value[$key] . '], widgetid=' . $widgetId);
221                                         }
222                                 }
223                                 // 空のときはデフォルト値の設定
224                                 if ($stripValue == '') $stripValue = $default;
225                                 $destValue[] = $stripValue;
226                         }
227                 } else {
228                         $trimValue = trim($value);
229                         
230                         // HTMLタグが含まれていた場合は、ログを残す
231                         $destValue = $this->gpc_stripslashes($trimValue);
232                         $destValue = strip_tags($destValue);
233                         
234                         // 危険性の高いその他変換。問題がある場合は文字列をクリアする
235                         $saveValue = $destValue;
236                         $destValue = $this->_convSafeText($destValue);
237                         if ($destValue != $saveValue) $destValue = '';
238
239                         $isValid = false;
240                         if (strlen($destValue) == strlen($trimValue)){          // 文字列長が同じとき
241                                 if ($ckeckType == 1){           // int型チェック
242                                         if ($destValue == ''){                          // 空文字列の場合はエラーと見なさない(2015/2/19 追加)
243                                                 $isValid = true;
244                                         } else if (is_numeric($destValue) && !strstr($destValue, '.')){
245                                                 $isValid = true;
246                                         } else {        // エラーの場合は値を修正
247                                                 $destValue = '';
248                                         }
249                                 } else {
250                                         $isValid = true;
251                                 }
252                         }
253                                 
254                         // エラーがある場合はログを残す
255                         if (!$isValid){
256                                 // ウィジェット内での処理の場合はウィジェットIDも出力
257                                 $widgetId = $this->gEnv->getCurrentWidgetId();// ウィジェットID
258                                 if (empty($widgetId)){
259                                         $this->gOpeLog->writeUserData(__METHOD__, 'POSTまたはGET値の異常データを検出しました。', 2012, 'name=' . $name . ', value=[' . $value . ']');
260                                 } else {                // ウィジェットIDが設定されているとき
261                                         $this->gOpeLog->writeUserData(__METHOD__, 'POSTまたはGET値の異常データを検出しました。', 2013, 'name=' . $name . ', value=[' . $value . '], widgetid=' . $widgetId);
262                                 }
263                         }
264                         // 空のときはデフォルト値の設定
265                         if ($destValue == '') $destValue = $default;
266                 }
267                 return $destValue;
268         }
269         /**
270          * 安全なテキストに変換
271          *
272          * @param string $src           変換するデータ
273          * @return string                       変換後データ
274          */
275         function _convSafeText($src)
276         {
277                 // マッチさせる文字列
278                 $search = array("':[\s]*?expression\('si",      // Javascriptが実行されないための対応「:expression(」「:url(」を削除(IE6,7用対応) 2009/1/15
279                                                 "':[\s]*?url\('si");
280
281                 // 変換文字列
282                 $replace = array("", "");
283
284                 return preg_replace($search, $replace, $src);
285         }
286         /**
287          * 取得メソッドがGETかどうか
288          *
289          * @return bool                 true=GETメソッド、false=GET以外
290          */
291         function isGetMethod()
292         {
293                 $method = strtoupper($this->trimServerValueOf('REQUEST_METHOD'));       // アクセスメソッド
294                 if ($method == 'GET'){
295                         return true;
296                 } else {
297                         return false;
298                 }
299         }
300         /**
301          * 取得メソッドがPOSTかどうか
302          *
303          * @return bool                 true=POSTメソッド、false=POST以外
304          */
305         function isPostMethod()
306         {
307                 $method = strtoupper($this->trimServerValueOf('REQUEST_METHOD'));       // アクセスメソッド
308                 if ($method == 'POST'){
309                         return true;
310                 } else {
311                         return false;
312                 }
313         }
314         /**
315          * cmdパラメータ付きのアクセスかどうか
316          *
317          * @return bool                 true=cmd付きアクセス、false=cmdなし
318          */
319         function isCmdAccess()
320         {
321                 $cmd = $this->trimValueOf(M3_REQUEST_PARAM_OPERATION_COMMAND);  // 実行コマンド
322                 $isCmd = !empty($cmd);                  // コマンド実行かどうか
323                 return $isCmd;
324         }
325         /**
326          * $_SERVERから値を取得(トリミング(前後の空白削除)あり)
327          *
328          * $_SERVERから値を取得し、トリミング(前後の空白削除)する
329          *
330          * @param string $name          キー値
331          * @param string $default       値が存在しないときのデフォルト値
332          * @return string                       取得値
333          */
334         public function trimServerValueOf($name, $default = '')
335         {
336                 $value = isset($_SERVER[$name]) ? $_SERVER[$name] : $default;
337                 
338                 // トリムをかける
339                 if (is_array($value)){
340                         $value = array_map('trim', $value);
341                 } else {
342                         $value = trim($value);
343                 }
344                 return $value;
345         }
346         /**
347          * セッションから値を取得
348          *
349          * $_SESSIONから値を取得する。
350          *
351          * @param string $name          キー値
352          * @param string $default       値が存在しないときのデフォルト値
353          * @return string                       取得値
354          */
355         public function getSessionValue($name, $default = '')
356         {
357                 $value = isset($_SESSION[$name]) ? $_SESSION[$name] : $default;
358                 return $value;
359         }
360         /**
361          * セッションに値を格納
362          *
363          * $_SESSIONに値を格納する。
364          *
365          * @param string $name          キー値
366          * @param string $value         格納値
367          * @return bool                         true=更新、false=更新なし
368          */
369         public function setSessionValue($name, $value = '')
370         {
371                 // セッション更新が停止されている場合は終了
372                 if ($this->sessionNoUpdate) return false;
373                 
374                 $_SESSION[$name] = $value;
375                 return true;
376         }
377         /**
378          * セッション格納値を開放
379          *
380          * $_SESSIONの指定値を開放する
381          *
382          * @param string $name          キー値
383          * @return bool                         true=更新、false=更新なし
384          */
385         public function unsetSessionValue($name)
386         {
387                 // セッション更新が停止されている場合は終了
388                 if ($this->sessionNoUpdate) return false;
389                 
390                 unset($_SESSION[$name]);
391                 return true;
392         }
393         /**
394          * セッションからシリアライズされた値を取得
395          *
396          * @param string $name          キー値
397          * @return object                       取得したオブジェクト、なしの場合はnull
398          */
399         public function getSessionValueWithSerialize($name)
400         {
401                 $value = isset($_SESSION[$name]) ? unserialize($_SESSION[$name]) : null;
402                 return $value;
403         }
404         /**
405          * セッションに値をシリアライズして格納
406          *
407          * @param string $name          キー値
408          * @param object $value         格納するオブジェクト、nullをセットした場合はセッション値を削除
409          * @return bool                         true=更新、false=更新なし
410          */
411         public function setSessionValueWithSerialize($name, $value = null)
412         {
413                 // セッション更新が停止されている場合は終了
414                 if ($this->sessionNoUpdate) return false;
415                 
416                 if ($value == null){
417                         unset($_SESSION[$name]);
418                 } else {
419                         $_SESSION[$name] = serialize($value);
420                 }
421                 return true;
422         }
423         /**
424          * セッションの値の更新を停止する
425          *
426          * @return                                      なし
427          */
428         public function stopSessionUpdate()
429         {
430                 $this->sessionNoUpdate = true;          // セッションの更新を停止するかどうか(参照は可能)
431         }
432         /**
433          * クッキーから値を取得
434          *
435          * @param string $name          キー値
436          * @param string $default       値が存在しないときのデフォルト値
437          * @return string                       取得値
438          */
439         public function getCookieValue($name, $default = '')
440         {
441                 // 設定したクッキー値があれば取得
442                 $value = isset($this->tmpCookie[$name]) ? $this->tmpCookie[$name] : '';         // クッキー送信前のクッキー格納データ
443
444                 if ($value == '') $value = isset($_COOKIE[$name]) ? $_COOKIE[$name] : $default;
445                 return $value;
446         }
447         /**
448          * クッキーに値を格納
449          *
450          * @param string $name          キー値
451          * @param string $value         格納値
452          * @param int $expireDay        クッキーの生存期間(日)。0を設定した場合はブラウザ閉じるまで生存。
453          * @return                                      なし
454          */
455         public function setCookieValue($name, $value = '', $expireDay = 30)
456         {
457                 if (floatval($expireDay) == 0){
458                         $cookExpire = 0;                // ブラウザ閉じるまで
459                 } else {
460                         $cookExpire = time() + 60 * 60 * 24 * $expireDay;
461                 }
462                 //setcookie($name, $value, $cookExpire);
463                 setcookie($name, $value, $cookExpire, '/');
464                 
465                 // 設定したクッキー値を保存
466                 $this->tmpCookie[$name] = $value;               // クッキー送信前のクッキー格納データ
467         }
468         /**
469          * クッキーの値を削除
470          *
471          * @param string $name          キー値
472          * @return                                      なし
473          */
474         public function removeCookieValue($name)
475         {
476                 setcookie($name, '', time() - 3600, '/');
477         }
478         /**
479          * URLクエリー配列を取得
480          *
481          * @return array                        URLクエリー文字列を解析した配列
482          */
483         public function getQueryArray()
484         {
485                 static $queryArray;
486                 
487                 if (!isset($queryArray)){
488                         $queryArray = array();
489                         $queryStr = self::trimServerValueOf('QUERY_STRING');
490                         if (!empty($queryStr)){
491                                 parse_str($queryStr, $queryArray);
492                                 // パラメータのエラーチェック
493                         }
494                 }
495                 return $queryArray;
496         }
497         /**
498          * クエリー文字列中のWikiページ名を取得
499          *
500          * @return string                       Wikiページ名、空の時はWikiページ名なし
501          */
502         public function getWikiPageFromQuery()
503         {
504                 $wikiPage = '';
505                 $args = explode('&', $_SERVER['QUERY_STRING']);// 「&」で分割
506                 for ($i = 0; $i < count($args); $i++){
507                         $line = $args[$i];
508                         $pos = strpos($line, '=');
509                         if ($pos){              // 「=」が存在するとき
510                                 //list($key, $value) = explode('=', $line);
511                         } else {
512                                 $wikiPage = $line;              // 「=」なしのパラメータはwikiパラメータとする
513                                 break;
514                         }
515                 }
516                 return $wikiPage;
517         }
518         /**
519          * 文字のエスケープ処理
520          *
521          * '(シングルクオート)、" (ダブルクオート)、\(バックスラッシュ) 、NULLにバックスラッシュでエスケープ処理を行う
522          *
523          * @param string $str           変換元文字列
524          * @return string                       変換後文字列
525          */
526 /*      function gpc_addslashes($str){
527                 if ($this->magicQuote){
528                         return $str;
529                 } else {
530                         return addslashes($str);
531                 }
532         }*/
533         /**
534          * 文字のエスケープ処理をはずす
535          *
536          * '(シングルクオート)、" (ダブルクオート)、\(バックスラッシュ) 、NULLのバックスラッシュでのエスケープ処理を削除
537          *
538          * @param string $str           変換元文字列
539          * @return string                       変換後文字列
540          */
541         function gpc_stripslashes($str){
542                 if ($this->magicQuote){  
543                         return stripslashes($str);
544                 } else {  
545                         return $str;  
546                 }  
547         }
548         //******************************************************
549         // patTemplateのテンプレートに値を埋め込む。値を省略した場合は、POST,GETデータから取得したデータを再設定する。
550         // $name: patTemplateのテンプレート名
551         // $valueName: HTMLタグに設定した名前。patTemplateの値埋め込み用キーワードも同じものを使用する。
552         // $default: 値埋め込み用キーワードに埋め込む値。省略の場合はPOST,GETデータから$valueNameの値を取得する。
553         function addValueToTemplate($name, $valueName, $default = null)
554         {
555                 if ($default == null){
556                         $this->tmpl->addVar($name, $valueName, $this->valueOf($valueName));
557                 } else {
558                         $this->tmpl->addVar($name, $valueName, $default);
559                 }
560         }
561         /**
562          * セッションを開く
563          */
564         function _sessionOpen($save_path, $session_name)
565         {
566                 return true;
567         }
568         /**
569          * セッションを閉じる
570          */
571         function _sessionClose()
572         {
573                 return true;
574         }
575         /**
576          * セッションデータを読み込む
577          */
578         function _sessionRead($id)
579         {
580                 return $this->db->readSession($id);
581         }
582         /**
583          * セッションデータを書き込む
584          *
585          * @param string $id                    セッションID
586          * @param string $sessData      セッションデータ
587          */
588         function _sessionWrite($id, $sessData)
589         {
590                 return $this->db->writeSession($id, $sessData);
591         }
592         /**
593          * セッションを破棄する
594          *
595          * @param string $id                    セッションID
596          */
597         function _sessionDestroy($id)
598         {
599                 return $this->db->destroySession($id);
600         }
601         /**
602          * 時間経過したセッションを破棄する
603          *
604          * @param int $maxlifetime      セッションの生存時間(秒)
605          */
606         function _sessionGc($maxlifetime)
607         {
608                 return $this->db->gcSession($maxlifetime);
609         }
610         
611         
612         /**
613          * セッション開始イベント時のコールバック関数追加
614          *
615          * @param  callable  $callback          コールバック関数
616          * @return bool                                         true=正常終了,false=異常終了
617          */
618         function addSessionOpenEventCallback($callback)
619         {
620                 if (!is_callable($callback)) return false;
621                 
622                 // コールバックス関数追加
623                 $this->sessionOpenEventCallbacks[] = $callback;
624                 
625                 return true;
626         }
627         /**
628          * セッション終了イベント時のコールバック関数追加
629          *
630          * @param  callable  $callback          コールバック関数
631          * @return bool                                         true=正常終了,false=異常終了
632          */
633         function addSessionCloseEventCallback($callback)
634         {
635                 if (!is_callable($callback)) return false;
636                 
637                 // コールバックス関数追加
638                 $this->sessionCloseEventCallbacks[] = $callback;
639                 
640                 return true;
641         }
642         /**
643          * セッション開始イベント時のコールバック関数を実行
644          *
645          * @return bool                                         true=正常終了,false=異常終了
646          */
647         function _doSessionOpenEventCallback()
648         {
649                 $callbackCount = count($this->sessionOpenEventCallbacks);
650                 if ($callbackCount == 0) return true;
651                 
652                 $retStatus = true;
653                 for ($i = 0; $i < $callbackCount; $i++){
654                         $callback = $this->sessionOpenEventCallbacks[$i];
655                         if (is_callable($callback)){
656                                 // コールバック関数を実行
657                                 $result = call_user_func($callback);
658                                 if (!$result) $retStatus = false;
659                         }
660                 }
661                 return $retStatus;
662         }
663         /**
664          * セッション終了イベント時のコールバック関数を実行
665          *
666          * @return bool                                         true=正常終了,false=異常終了
667          */
668         function _doSessionCloseEventCallback()
669         {
670                 $callbackCount = count($this->sessionCloseEventCallbacks);
671                 if ($callbackCount == 0) return true;
672                 
673                 $retStatus = true;
674                 for ($i = 0; $i < $callbackCount; $i++){
675                         $callback = $this->sessionCloseEventCallbacks[$i];
676                         if (is_callable($callback)){
677                                 // コールバック関数を実行
678                                 $result = call_user_func($callback);
679                                 if (!$result) $retStatus = false;
680                         }
681                 }
682                 return $retStatus;
683         }
684 }
685 ?>