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-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
16 require_once(M3_SYSTEM_INCLUDE_PATH . '/common/core.php');
18 class CacheManager extends Core
20 private $db; // DBオブジェクト
21 private $usePageCache; // ページキャッシュを使用するかどうか
22 private $useWidgetCache; // ウィジェットキャッシュを使用するかどうか
23 private $isCacheOff; // 強制キャッシュオフフラグ
28 function __construct()
30 global $gInstanceManager;
33 $this->db = $gInstanceManager->getSytemDbObject();
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(略式)
78 $this->usePageCache = false; // ページキャッシュを使用するかどうか
79 $this->useWidgetCache = false; // ウィジェットキャッシュを使用するかどうか
80 $this->isCacheOff = true; // 強制キャッシュオフフラグ
85 * @param RequestManager $request HTTPリクエスト処理クラス
88 function initCache($request)
93 if ($this->isCacheOff) return;
95 $this->usePageCache = false; // ページキャッシュを使用するかどうか
96 $this->useWidgetCache = false; // ウィジェットキャッシュを使用するかどうか
98 // ログイン時は、ページキャッシュを使用しない。ウィジェットキャッシュのみ使用。
99 if ($this->canUseCache($request)){ // キャッシュ機能が使用可能
101 if (!$gEnvManager->isCurrentUserLogined()) $this->usePageCache = true;
103 // ウィジェットキャッシュ機能をオンにする
104 $this->useWidgetCache = true;
110 * @param RequestManager $request HTTPリクエスト処理クラス
111 * @return string キャッシュデータ。キャッシュデータがないときは空文字列。
113 function getPageCache($request)
116 global $gSystemManager;
120 // ページキャッシュ機能が使用できるかどうか
121 if (!$this->usePageCache) return $cacheData;
123 $pageId = $gEnvManager->getCurrentPageId();
124 $pageSubId = $gEnvManager->getCurrentPageSubId();
127 $url = $gEnvManager->getCurrentRequestUri();
128 $ret = $this->db->getCacheData('', $url, $row);
130 // ページIDをチェック。ページIDがマッチしないときは、キャッシュを削除
131 if ($row['ca_page_id'] == $pageId && $row['ca_page_sub_id'] == $pageSubId){
132 // キャッシュの更新時間が0のときはキャッシュデータを更新しない
133 $lifetime = $gSystemManager->pageCacheLifetime(); // 単位分
135 if (time() - strtotime($row['ca_update_dt']) <= $lifetime * 60){ // キャッシュ保持時間内のとき
136 $cacheData = $row['ca_html'];
139 $cacheData = $row['ca_html'];
148 * @param RequestManager $request HTTPリクエスト処理クラス
149 * @param string $cacheData キャッシュデータ
150 * @return bool true=成功、false=失敗
152 function setPageCache($request, $cacheData)
156 // ページキャッシュ機能が使用できるかどうか
157 if (!$this->usePageCache) return false;
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;
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; // キャッシュ不可の場合は終了
181 $ret = $this->db->updateCacheData('', $url, $pageId, $pageSubId, $cacheData);
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 キャッシュデータ。キャッシュデータがないときは空文字列。
194 function getWidgetCache($request, $infoRow, &$metaTitle, &$metaDesc, &$metaKeyword)
197 global $gSystemManager;
201 // ウィジェットキャッシュ機能が使用できるかどうか
202 if (!$this->useWidgetCache) return $cacheData;
204 $url = $gEnvManager->getCurrentRequestUri();
205 $pageId = $gEnvManager->getCurrentPageId();
206 $pageSubId = $gEnvManager->getCurrentPageSubId();
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'];// キャッシュ保存時間(単位分)
214 switch ($infoRow['wd_view_control_type']){
216 $configId = 0; // インスタンス定義を使用しないときはパラメータID=0のパラメータを使用
217 case 1: // ウィジェットパラメータで表示制御されるとき
219 $ret = $this->db->getWidgetCache($widgetId, $configId, $row);
221 if ($row['wp_cache_update_dt'] != $gEnvManager->getInitValueOfTimestamp()){ // キャッシュデータがあるとき
222 // キャッシュの更新時間が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'];
231 $cacheData = $row['wp_cache_html'];
232 $metaTitle = $row['wp_meta_title'];
233 $metaDesc = $row['wp_meta_description'];
234 $metaKeyword = $row['wp_meta_keywords'];
239 case 2: // URLパラメータで表示制御されるとき
240 $ret = $this->db->getCacheData($widgetId, $url, $row);
242 // ページIDをチェック。ページIDがマッチしないときは、キャッシュを削除
243 if ($row['ca_page_id'] == $pageId && $row['ca_page_sub_id'] == $pageSubId){
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'];
252 $cacheData = $row['ca_html'];
253 $metaTitle = $row['ca_meta_title'];
254 $metaDesc = $row['ca_meta_description'];
255 $metaKeyword = $row['ca_meta_keywords'];
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=失敗
275 function setWidgetCache($request, $infoRow, $cacheData, $metaTitle = '', $metaDesc = '', $metaKeyword = '')
279 // ウィジェットキャッシュ機能が使用できるかどうか
280 if (!$this->useWidgetCache) return false;
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'];// キャッシュ保存時間(単位分)
288 switch ($infoRow['wd_view_control_type']){
294 $configId = 0; // インスタンス定義を使用しないときはパラメータID=0のパラメータを使用
295 case 1: // ウィジェットパラメータで表示制御されるとき
297 $ret = $this->db->updateWidgetCache($widgetId, $configId, $cacheData, $metaTitle, $metaDesc, $metaKeyword);
299 case 2: // URLパラメータで表示制御されるとき
301 $url = $gEnvManager->getCurrentRequestUri();
302 if (!$this->isProperCacheUrl($request)) return false;
304 $pageId = $gEnvManager->getCurrentPageId();
305 $pageSubId = $gEnvManager->getCurrentPageSubId();
306 $ret = $this->db->updateCacheData($widgetId, $url, $pageId, $pageSubId, $cacheData, $metaTitle, $metaDesc, $metaKeyword);
315 * @param RequestManager $request HTTPリクエスト処理クラス
316 * @return bool true=可能、false=不可
318 function canUseCache($request)
321 global $gSystemManager;
324 if (!$gSystemManager->usePageCache()) return false;
327 if ($gEnvManager->isSystemManageUser()) return false;
329 // 管理画面はキャッシュ機能は使用できない
330 if ($gEnvManager->isAdminDirAccess()) return false;
333 if ($gEnvManager->getIsMobileSite()) return false;
336 $method = strtoupper($request->trimServerValueOf('REQUEST_METHOD')); // アクセスメソッド
337 if ($method != 'GET') return false;
342 * ウィジェットキャッシュ機能が使用できるかどうか
344 * @param RequestManager $request HTTPリクエスト処理クラス
345 * @param Array $infoRow ウィジェット情報
346 * @return bool true=可能、false=不可
348 function canUseWidgetCache($request, $infoRow)
352 // 遅延実行ウィジェットはキャッシュできない
353 if ($infoRow['wd_launch_index'] > 0) return false;
357 switch ($infoRow['wd_cache_type']){
358 case 0: // キャッシュ不可のとき
359 case 3: // ページキャッシュのみ可のとき(ウィジェットからHTMLヘッダ部にCSS,JavaScript等を追加している場合)
362 case 1: // キャッシュ可能なとき
365 case 2: // 非ログイン時のみキャッシュ可能なとき
367 if (!$gEnvManager->isCurrentUserLogined()) $retStatus = true;
375 * @param RequestManager $request HTTPリクエスト処理クラス
376 * @return bool true=可能、false=不可
378 function isProperCacheUrl($request)
382 $url = $gEnvManager->getCurrentRequestUri();
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;
397 * @param string $pageId ページID
398 * @param string $pageSubId ページサブID
399 * @return bool true=完了、false=不可
401 function clearPageCache($pageId, $pageSubId)
403 $ret = $this->db->deletePageCacheData($pageId, $pageSubId);
409 * @return bool true=完了、false=不可
411 function clearAllCache()
414 $ret = $this->db->deletePageCacheData('', '');
417 $ret = $this->db->deleteWidgetCache();
421 * ウィジェットタイプ指定でキャッシュデータを削除
423 * @param string $widgetType ウィジェットタイプ
424 * @return bool true=完了、false=不可
426 function clearCacheByWidgetType($widgetType)
428 // ウィジェットタイプに該当するウィジェットIDを取得
429 $ret = $this->db->getWidgetListByType($widgetType, $rows);
432 for ($i = 0; $i < count($rows); $i++){
433 $this->clearCacheByWidgetId($rows[$i]['wd_id']);
439 * ウィジェットIDとURLパラメータ指定でキャッシュデータを削除
441 * @param string $widgetId ウィジェットID
442 * @param array $param URLパラメータ(空のときはウィジェット定義ID=0を対象とする)
443 * @return bool true=完了、false=不可
445 function clearCacheByWidgetId($widgetId, $param = array())
448 // ##### ページキャッシュ、ウィジェットキャッシュを削除 #####
449 // 定義ID=0が配置されているページのキャッシュを削除
450 $this->clearCacheByWidgetConfigId($widgetId, 0);
452 // ##### ページキャッシュを削除 #####
453 // ウィジェットを指定してキャッシュを削除
454 $ret = $this->db->getCacheDataByWidgetId($widgetId, $rows);
456 // URLパラメータがマッチしたレコードを削除
457 $serialArray = array();
458 /*if (empty($param)){
459 for ($i = 0; $i < count($rows); $i++){
460 $serialArray[] = $rows[$i]['ca_serial'];
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;
472 if ($j < count($lines)) $serialArray[] = $rows[$i]['ca_serial'];
476 $ret = $this->db->deletePageCacheDataBySerial($serialArray);
480 $ret = $this->db->getCacheDataByWidgetId('', $rows);
482 // URLパラメータがマッチしたレコードを削除
483 $serialArray = array();
484 /*if (empty($param)){
485 for ($i = 0; $i < count($rows); $i++){
486 $serialArray[] = $rows[$i]['ca_serial'];
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;
498 if ($j < count($lines)) $serialArray[] = $rows[$i]['ca_serial'];
502 $ret = $this->db->deletePageCacheDataBySerial($serialArray);
508 * ウィジェットIDとウィジェット定義ID指定でキャッシュデータを削除
510 * @param string $widgetId ウィジェットID
511 * @param string $configId ウィジェット定義ID
512 * @return bool true=完了、false=不可
514 function clearCacheByWidgetConfigId($widgetId, $configId)
516 // ##### ページキャッシュを削除 #####
518 $ret = $this->db->getPageDefByWidgetConfigId($widgetId, $configId, $rows);
520 for ($i = 0; $i < count($rows); $i++){
521 $pageId = $rows[$i]['pd_id'];
522 $pageSubId = $rows[$i]['pd_sub_id'];
525 $this->clearPageCache($pageId, $pageSubId);
529 // ##### ウィジェットキャッシュを削除 #####
530 $ret = $this->db->deleteWidgetCache($widgetId, $configId);