OSDN Git Service

初回コミット(v2.6.17.1)
[magic3/magic3.git] / include / manager / cacheManager.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-2009 Magic3 Project.
12  * @license    http://www.gnu.org/copyleft/gpl.html  GPL License
13  * @version    SVN: $Id: cacheManager.php 3456 2010-08-06 04:55:15Z fishbone $
14  * @link       http://www.magic3.org
15  */
16 require_once(M3_SYSTEM_INCLUDE_PATH . '/common/core.php');
17
18 class CacheManager extends Core
19 {
20         private $db;                                            // DBオブジェクト
21         private $usePageCache;                          // ページキャッシュを使用するかどうか
22         private $useWidgetCache;                                // ウィジェットキャッシュを使用するかどうか
23         private $isCacheOff;                                    // 強制キャッシュオフフラグ
24         
25         /**
26          * コンストラクタ
27          */
28         function __construct()
29         {
30                 global $gInstanceManager;
31                 
32                 // システムDBオブジェクト取得
33                 $this->db = $gInstanceManager->getSytemDbObject();
34                 
35                 // キャッシュ可能な画面の条件
36                 // ・単純なURLで表現でき、GETで取得可能な画面
37                 // ・task付きのURLでは、トップ画面(taskなし)のみ表示可能とする
38                 $this->safeParam = array(
39                         M3_REQUEST_PARAM_PAGE_SUB_ID,                   // ページサブID
40                         //M3_REQUEST_PARAM_PAGE_CONTENT_ID,                             // ページコンテンツID
41                         //M3_REQUEST_PARAM_WIDGET_ID,                   // ウィジェットID
42                         //M3_REQUEST_PARAM_TEMPLATE_ID,         // テンプレートID
43                         //M3_REQUEST_PARAM_URL,                         // リンク先等のURL
44                         //M3_REQUEST_PARAM_STAMP,                       // 公開発行ID
45                         //M3_REQUEST_PARAM_OPTION,                              // 通信オプション
46                         //M3_REQUEST_PARAM_OPERATION_COMMAND,                           // 実行処理
47                         //M3_REQUEST_PARAM_OPERATION_WIKI_COMMAND,                      // Wikiコマンド実行
48                         //M3_REQUEST_PARAM_OPERATION_TASK,                      // ウィジェット間共通処理
49                         //M3_REQUEST_PARAM_OPERATION_ACT,                               // クライアントからの実行処理
50                         //M3_REQUEST_PARAM_OPERATION_LANG,                      // 言語指定表示
51                         //M3_REQUEST_PARAM_OPERATION_TODO,                      // 指定ウィジェットに実行させる処理
52                         //M3_REQUEST_PARAM_FROM,                        // メッセージの送信元ウィジェットID
53                         //M3_REQUEST_PARAM_VIEW_STYLE,                  // 表示スタイル
54                         //M3_REQUEST_PARAM_FORWARD,                     // 画面遷移用パラメータ
55                         //M3_REQUEST_PARAM_ADMIN_KEY,           // 管理者一時キー
56                         //M3_REQUEST_PARAM_OPEN_BY,                     // ウィンドウの開き方
57                         //M3_REQUEST_PARAM_SHOW_HEADER,                 // ヘッダ部表示制御
58                         //M3_REQUEST_PARAM_SHOW_FOOTER,                 // フッタ部表示制御
59                         //M3_REQUEST_PARAM_PAGE_DEF_SERIAL,             // ページ定義のレコードシリアル番号(設定画面起動時)
60                         //M3_REQUEST_PARAM_PAGE_DEF_CONFIG_ID,          // ページ定義のウィジェット定義ID(設定画面起動時)
61                         M3_REQUEST_PARAM_CONTENT_ID,            // コンテンツID
62                         M3_REQUEST_PARAM_CONTENT_ID_SHORT,                              // コンテンツID(略式)
63                         M3_REQUEST_PARAM_PRODUCT_ID,            // 製品ID
64                         M3_REQUEST_PARAM_PRODUCT_ID_SHORT,                              // 製品ID(略式)
65                         M3_REQUEST_PARAM_BLOG_ENTRY_ID,                 // ブログ記事ID
66                         M3_REQUEST_PARAM_BLOG_ENTRY_ID_SHORT,                           // ブログ記事ID(略式)
67                         M3_REQUEST_PARAM_BBS_ID,                // 掲示板投稿記事ID
68                         M3_REQUEST_PARAM_BBS_ID_SHORT                           // 掲示板投稿記事ID(略式)
69                 );
70         }
71         /**
72          * キャッシュ機能を強制的にオフにする
73          *
74          * @return                              なし
75          */
76         function cacheOff()
77         {
78                 $this->usePageCache = false;                            // ページキャッシュを使用するかどうか
79                 $this->useWidgetCache = false;                          // ウィジェットキャッシュを使用するかどうか
80                 $this->isCacheOff = true;                                       // 強制キャッシュオフフラグ
81         }
82         /**
83          * キャッシュ機能を初期化
84          *
85          * @param RequestManager $request               HTTPリクエスト処理クラス
86          * @return 
87          */
88         function initCache($request)
89         {
90                 global $gEnvManager;
91                 
92                 // 強制キャッシュオフのときは終了
93                 if ($this->isCacheOff) return;
94                                 
95                 $this->usePageCache = false;                            // ページキャッシュを使用するかどうか
96                 $this->useWidgetCache = false;                          // ウィジェットキャッシュを使用するかどうか
97
98                 // ログイン時は、ページキャッシュを使用しない。ウィジェットキャッシュのみ使用。
99                 if ($this->canUseCache($request)){              // キャッシュ機能が使用可能
100                         // ログインをチェック
101                         if (!$gEnvManager->isCurrentUserLogined()) $this->usePageCache = true;
102                         
103                         // ウィジェットキャッシュ機能をオンにする
104                         $this->useWidgetCache = true;
105                 }
106         }
107         /**
108          * 画面のキャッシュデータを取得
109          *
110          * @param RequestManager $request               HTTPリクエスト処理クラス
111          * @return string                                       キャッシュデータ。キャッシュデータがないときは空文字列。
112          */
113         function getPageCache($request)
114         {
115                 global $gEnvManager;
116                 global $gSystemManager;
117                 
118                 $cacheData = '';
119
120                 // ページキャッシュ機能が使用できるかどうか
121                 if (!$this->usePageCache) return $cacheData;
122                 
123                 $pageId = $gEnvManager->getCurrentPageId();
124                 $pageSubId = $gEnvManager->getCurrentPageSubId();
125                 
126                 // キャッシュデータを取得
127                 $url = $gEnvManager->getCurrentRequestUri();
128                 $ret = $this->db->getCacheData('', $url, $row);
129                 if ($ret){
130                         // ページIDをチェック。ページIDがマッチしないときは、キャッシュを削除
131                         if ($row['ca_page_id'] == $pageId && $row['ca_page_sub_id'] == $pageSubId){
132                                 // キャッシュの更新時間が0のときはキャッシュデータを更新しない
133                                 $lifetime = $gSystemManager->pageCacheLifetime();       // 単位分
134                                 if ($lifetime > 0){
135                                         if (time() - strtotime($row['ca_update_dt']) <= $lifetime * 60){                // キャッシュ保持時間内のとき
136                                                 $cacheData = $row['ca_html'];
137                                         }
138                                 } else {
139                                         $cacheData = $row['ca_html'];
140                                 }
141                         }
142                 }
143                 return $cacheData;
144         }
145         /**
146          * 画面キャッシュデータを設定
147          *
148          * @param RequestManager $request               HTTPリクエスト処理クラス
149          * @param string $cacheData                             キャッシュデータ
150          * @return bool                                                 true=成功、false=失敗
151          */
152         function setPageCache($request, $cacheData)
153         {
154                 global $gEnvManager;
155
156                 // ページキャッシュ機能が使用できるかどうか
157                 if (!$this->usePageCache) return false;
158                 
159                 // URLのチェック
160                 $url = $gEnvManager->getCurrentRequestUri();
161                 if (!$this->isProperCacheUrl($request)) return false;
162                 /*$queryArray = $request->getQueryArray();
163                 if (count($queryArray) > 0){
164                         $keys = array_keys($queryArray);
165                         for ($i = 0; $i < count($keys); $i++){
166                                 // 受け付け可能なパラメータでないときは終了
167                                 if (!in_array($keys[$i], $this->safeParam)) return false;
168                         }
169                 }*/
170                 
171                 // キャッシュ可能なページかチェック
172                 $pageId = $gEnvManager->getCurrentPageId();
173                 $pageSubId = $gEnvManager->getCurrentPageSubId();
174                 $ret = $this->db->getPageDefOnPage($pageId, $pageSubId, $rows);
175                 $defCount = count($rows);
176                 for ($i = 0; $i < $defCount; $i++){
177                         if ($rows[$i]['wd_launch_index'] > 0) return false;             // 遅延実行ウィジェットはキャッシュできない
178                         if ($rows[$i]['wd_cache_type'] <= 0) return false;              // キャッシュ不可の場合は終了
179                 }
180                 
181                 $ret = $this->db->updateCacheData('', $url, $pageId, $pageSubId, $cacheData);
182                 return $ret;
183         }
184         /**
185          * ウィジェットのキャッシュデータを取得
186          *
187          * @param RequestManager $request               HTTPリクエスト処理クラス
188          * @param Array $infoRow                                ウィジェット情報
189          * @param string  $metaTitle            METAタグ、タイトル
190          * @param string  $metaDesc                     METAタグ、ページ要約
191          * @param string  $metaKeyword          METAタグ、検索用キーワード
192          * @return string                                       キャッシュデータ。キャッシュデータがないときは空文字列。
193          */
194         function getWidgetCache($request, $infoRow, &$metaTitle, &$metaDesc, &$metaKeyword)
195         {
196                 global $gEnvManager;
197                 global $gSystemManager;
198                 
199                 $cacheData = '';
200
201                 // ウィジェットキャッシュ機能が使用できるかどうか
202                 if (!$this->useWidgetCache) return $cacheData;
203
204                 $url = $gEnvManager->getCurrentRequestUri();
205                 $pageId = $gEnvManager->getCurrentPageId();
206                 $pageSubId = $gEnvManager->getCurrentPageSubId();
207                 
208                 $ret = $this->canUseWidgetCache($request, $infoRow);
209                 if ($ret){              // キャッシュ使用可能なとき
210                         $widgetId = $infoRow['wd_id'];
211                         $configId = $infoRow['pd_config_id'];
212                         $lifetime = $infoRow['wd_cache_lifetime'];// キャッシュ保存時間(単位分)
213                                 
214                         switch ($infoRow['wd_view_control_type']){
215                                 case -1:                        // 表示が固定のとき
216                                         $configId = 0;          // インスタンス定義を使用しないときはパラメータID=0のパラメータを使用
217                                 case 1:                 // ウィジェットパラメータで表示制御されるとき
218                                         // ウィジェットパラメータを取得
219                                         $ret = $this->db->getWidgetCache($widgetId, $configId, $row);
220                                         if ($ret){
221                                                 if ($row['wp_cache_update_dt'] != $gEnvManager->getInitValueOfTimestamp()){             // キャッシュデータがあるとき
222                                                         // キャッシュの更新時間が0のときはキャッシュデータを更新しない
223                                                         if ($lifetime > 0){
224                                                                 if (time() - strtotime($row['wp_cache_update_dt']) <= $lifetime * 60){          // キャッシュ保持時間内のとき
225                                                                         $cacheData              = $row['wp_cache_html'];
226                                                                         $metaTitle              = $row['wp_meta_title'];
227                                                                         $metaDesc               = $row['wp_meta_description'];
228                                                                         $metaKeyword    = $row['wp_meta_keywords'];
229                                                                 }
230                                                         } else {
231                                                                 $cacheData              = $row['wp_cache_html'];
232                                                                 $metaTitle              = $row['wp_meta_title'];
233                                                                 $metaDesc               = $row['wp_meta_description'];
234                                                                 $metaKeyword    = $row['wp_meta_keywords'];
235                                                         }
236                                                 }
237                                         }
238                                         break;
239                                 case 2:                 // URLパラメータで表示制御されるとき
240                                         $ret = $this->db->getCacheData($widgetId, $url, $row);
241                                         if ($ret){
242                                                 // ページIDをチェック。ページIDがマッチしないときは、キャッシュを削除
243                                                 if ($row['ca_page_id'] == $pageId && $row['ca_page_sub_id'] == $pageSubId){
244                                                         if ($lifetime > 0){
245                                                                 if (time() - strtotime($row['ca_update_dt']) <= $lifetime * 60){                // キャッシュ保持時間内のとき
246                                                                         $cacheData              = $row['ca_html'];
247                                                                         $metaTitle              = $row['ca_meta_title'];
248                                                                         $metaDesc               = $row['ca_meta_description'];
249                                                                         $metaKeyword    = $row['ca_meta_keywords'];
250                                                                 }
251                                                         } else {
252                                                                 $cacheData = $row['ca_html'];
253                                                                 $metaTitle              = $row['ca_meta_title'];
254                                                                 $metaDesc               = $row['ca_meta_description'];
255                                                                 $metaKeyword    = $row['ca_meta_keywords'];
256                                                         }
257                                                 }
258                                         }
259                                         break;
260                         }
261                 }
262                 return $cacheData;
263         }
264         /**
265          * ウィジェットのキャッシュデータを設定
266          *
267          * @param RequestManager $request               HTTPリクエスト処理クラス
268          * @param Array   $infoRow                              ウィジェット情報
269          * @param string  $cacheData                    キャッシュデータ
270          * @param string  $metaTitle                    METAタグ、タイトル
271          * @param string  $metaDesc                             METAタグ、ページ要約
272          * @param string  $metaKeyword                  METAタグ、検索用キーワード
273          * @return bool                                                 true=成功、false=失敗
274          */
275         function setWidgetCache($request, $infoRow, $cacheData, $metaTitle = '', $metaDesc = '', $metaKeyword = '')
276         {
277                 global $gEnvManager;
278
279                 // ウィジェットキャッシュ機能が使用できるかどうか
280                 if (!$this->useWidgetCache) return false;
281                 
282                 $ret = $this->canUseWidgetCache($request, $infoRow);
283                 if ($ret){              // キャッシュ使用可能なとき
284                         $widgetId = $infoRow['wd_id'];
285                         $configId = $infoRow['pd_config_id'];
286                         $lifetime = $infoRow['wd_cache_lifetime'];// キャッシュ保存時間(単位分)
287                                 
288                         switch ($infoRow['wd_view_control_type']){
289                                 case 0:                         // 表示が可変のとき
290                                 default:
291                                         $ret = false;
292                                         break;
293                                 case -1:                        // 表示が固定のとき
294                                         $configId = 0;          // インスタンス定義を使用しないときはパラメータID=0のパラメータを使用
295                                 case 1:                 // ウィジェットパラメータで表示制御されるとき
296                                         // ウィジェットキャッシュを更新
297                                         $ret = $this->db->updateWidgetCache($widgetId, $configId, $cacheData, $metaTitle, $metaDesc, $metaKeyword);
298                                         break;
299                                 case 2:                 // URLパラメータで表示制御されるとき
300                                         // URLのチェック
301                                         $url = $gEnvManager->getCurrentRequestUri();
302                                         if (!$this->isProperCacheUrl($request)) return false;
303                                         
304                                         $pageId = $gEnvManager->getCurrentPageId();
305                                         $pageSubId = $gEnvManager->getCurrentPageSubId();
306                                         $ret = $this->db->updateCacheData($widgetId, $url, $pageId, $pageSubId, $cacheData, $metaTitle, $metaDesc, $metaKeyword);
307                                         break;
308                         }
309                 }
310                 return $ret;
311         }
312         /**
313          * キャッシュ機能が使用できるかどうか
314          *
315          * @param RequestManager $request               HTTPリクエスト処理クラス
316          * @return bool                                                 true=可能、false=不可
317          */
318         function canUseCache($request)
319         {
320                 global $gEnvManager;
321                 global $gSystemManager;
322                 
323                 // キャッシュ処理を行わないときは終了
324                 if (!$gSystemManager->usePageCache()) return false;
325                 
326                 // システム運用者はキャッシュできない
327                 if ($gEnvManager->isSystemManageUser()) return false;
328                 
329                 // 管理画面はキャッシュ機能は使用できない
330                 if ($gEnvManager->isAdminDirAccess()) return false;
331                 
332                 // 携帯はSJIS出力なので非対応
333                 if ($gEnvManager->getIsMobileSite()) return false;
334                 
335                 // GET以外はキャッシュしない
336                 $method = strtoupper($request->trimServerValueOf('REQUEST_METHOD'));    // アクセスメソッド
337                 if ($method != 'GET') return false;
338                 
339                 return true;
340         }
341         /**
342          * ウィジェットキャッシュ機能が使用できるかどうか
343          *
344          * @param RequestManager $request               HTTPリクエスト処理クラス
345          * @param Array $infoRow                                ウィジェット情報
346          * @return bool                                                 true=可能、false=不可
347          */
348         function canUseWidgetCache($request, $infoRow)
349         {
350                 global $gEnvManager;
351                 
352                 // 遅延実行ウィジェットはキャッシュできない
353                 if ($infoRow['wd_launch_index'] > 0) return false;
354                 
355                 // キャッシュタイプをチェック
356                 $retStatus = false;
357                 switch ($infoRow['wd_cache_type']){
358                         case 0:                 // キャッシュ不可のとき
359                         case 3:                 // ページキャッシュのみ可のとき(ウィジェットからHTMLヘッダ部にCSS,JavaScript等を追加している場合)
360                         default:
361                                 break;
362                         case 1:                 // キャッシュ可能なとき
363                                 $retStatus = true;
364                                 break;
365                         case 2:                 // 非ログイン時のみキャッシュ可能なとき
366                                 // ログインをチェック
367                                 if (!$gEnvManager->isCurrentUserLogined()) $retStatus = true;
368                                 break;
369                 }
370                 return $retStatus;
371         }
372         /**
373          * キャッシュ可能なURLかどうか
374          *
375          * @param RequestManager $request               HTTPリクエスト処理クラス
376          * @return bool                                                 true=可能、false=不可
377          */
378         function isProperCacheUrl($request)
379         {
380                 global $gEnvManager;
381                 
382                 $url = $gEnvManager->getCurrentRequestUri();
383                 
384                 $queryArray = $request->getQueryArray();
385                 if (count($queryArray) > 0){
386                         $keys = array_keys($queryArray);
387                         for ($i = 0; $i < count($keys); $i++){
388                                 // 受け付け可能なパラメータでないときは終了
389                                 if (!in_array($keys[$i], $this->safeParam)) return false;
390                         }
391                 }
392                 return true;
393         }
394         /**
395          * キャッシュデータを削除
396          *
397          * @param string $pageId                ページID
398          * @param string $pageSubId             ページサブID
399          * @return bool                                                 true=完了、false=不可
400          */
401         function clearPageCache($pageId, $pageSubId)
402         {
403                 $ret = $this->db->deletePageCacheData($pageId, $pageSubId);
404                 return $ret;
405         }
406         /**
407          * すべてのキャッシュデータを削除
408          *
409          * @return bool                                                 true=完了、false=不可
410          */
411         function clearAllCache()
412         {
413                 // ページキャッシュを削除
414                 $ret = $this->db->deletePageCacheData('', '');
415                 
416                 // ウィジェットキャッシュを削除
417                 $ret = $this->db->deleteWidgetCache();
418                 return true;
419         }
420         /**
421          * ウィジェットタイプ指定でキャッシュデータを削除
422          *
423          * @param string $widgetType    ウィジェットタイプ
424          * @return bool                                 true=完了、false=不可
425          */
426         function clearCacheByWidgetType($widgetType)
427         {
428                 // ウィジェットタイプに該当するウィジェットIDを取得
429                 $ret = $this->db->getWidgetListByType($widgetType, $rows);
430                 if ($ret){
431                         // ウィジェットごとにキャッシュを削除
432                         for ($i = 0; $i < count($rows); $i++){
433                                 $this->clearCacheByWidgetId($rows[$i]['wd_id']);
434                         }
435                 }
436                 return true;
437         }
438         /**
439          * ウィジェットIDとURLパラメータ指定でキャッシュデータを削除
440          *
441          * @param string $widgetId              ウィジェットID
442          * @param array $param                  URLパラメータ(空のときはウィジェット定義ID=0を対象とする)
443          * @return bool                                 true=完了、false=不可
444          */
445         function clearCacheByWidgetId($widgetId, $param = array())
446         {
447                 if (empty($param)){
448                         // ##### ページキャッシュ、ウィジェットキャッシュを削除 #####
449                         // 定義ID=0が配置されているページのキャッシュを削除
450                         $this->clearCacheByWidgetConfigId($widgetId, 0);
451                 } else {
452                         // ##### ページキャッシュを削除 #####
453                         // ウィジェットを指定してキャッシュを削除
454                         $ret = $this->db->getCacheDataByWidgetId($widgetId, $rows);
455                         if ($ret){
456                                 // URLパラメータがマッチしたレコードを削除
457                                 $serialArray = array();
458                                 /*if (empty($param)){
459                                         for ($i = 0; $i < count($rows); $i++){
460                                                 $serialArray[] = $rows[$i]['ca_serial'];
461                                         }
462                                 } else {*/
463                                         for ($i = 0; $i < count($rows); $i++){
464                                                 $url = $rows[$i]['ca_url'];
465                                                 $parsedUrl = parse_url($url);
466                                                 if (!empty($parsedUrl['query'])){
467                                                         // パラメータがマッチしたレコードは削除対象とする
468                                                         $lines = explode('&', $parsedUrl['query']);
469                                                         for ($j = 0; $j < count($lines); $j++){
470                                                                 if (in_array($lines[$j], $param)) break;
471                                                         }
472                                                         if ($j < count($lines)) $serialArray[] = $rows[$i]['ca_serial'];
473                                                 }
474                                         }
475                                 //}
476                                 $ret = $this->db->deletePageCacheDataBySerial($serialArray);
477                         }
478                 
479                         // ページキャッシュを削除
480                         $ret = $this->db->getCacheDataByWidgetId('', $rows);
481                         if ($ret){
482                                 // URLパラメータがマッチしたレコードを削除
483                                 $serialArray = array();
484                                 /*if (empty($param)){
485                                         for ($i = 0; $i < count($rows); $i++){
486                                                 $serialArray[] = $rows[$i]['ca_serial'];
487                                         }
488                                 } else {*/
489                                         for ($i = 0; $i < count($rows); $i++){
490                                                 $url = $rows[$i]['ca_url'];
491                                                 $parsedUrl = parse_url($url);
492                                                 if (!empty($parsedUrl['query'])){
493                                                         // パラメータがマッチしたレコードは削除対象とする
494                                                         $lines = explode('&', $parsedUrl['query']);
495                                                         for ($j = 0; $j < count($lines); $j++){
496                                                                 if (in_array($lines[$j], $param)) break;
497                                                         }
498                                                         if ($j < count($lines)) $serialArray[] = $rows[$i]['ca_serial'];
499                                                 }
500                                         }
501                                 //}
502                                 $ret = $this->db->deletePageCacheDataBySerial($serialArray);
503                         }
504                 }
505                 return $ret;
506         }
507         /**
508          * ウィジェットIDとウィジェット定義ID指定でキャッシュデータを削除
509          *
510          * @param string $widgetId              ウィジェットID
511          * @param string $configId              ウィジェット定義ID
512          * @return bool                                 true=完了、false=不可
513          */
514         function clearCacheByWidgetConfigId($widgetId, $configId)
515         {
516                 // ##### ページキャッシュを削除 #####
517                 // ページID,ページサブIDを取得
518                 $ret = $this->db->getPageDefByWidgetConfigId($widgetId, $configId, $rows);
519                 if ($ret){
520                         for ($i = 0; $i < count($rows); $i++){
521                                 $pageId = $rows[$i]['pd_id'];
522                                 $pageSubId = $rows[$i]['pd_sub_id'];
523                                 
524                                 // キャッシュをクリア
525                                 $this->clearPageCache($pageId, $pageSubId);
526                         }
527                 }
528                 
529                 // ##### ウィジェットキャッシュを削除 #####
530                 $ret = $this->db->deleteWidgetCache($widgetId, $configId);
531                 return $ret;
532         }
533 }
534 ?>