OSDN Git Service

初回コミット(v2.6.17.1)
[magic3/magic3.git] / widgets / breadcrumb / include / container / breadcrumbWidgetContainer.php
1 <?php
2 /**
3  * index.php用コンテナクラス
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    パンくずリスト
10  * @author     株式会社 毎日メディアサービス
11  * @copyright  Copyright 2010-2013 株式会社 毎日メディアサービス.
12  * @license    http://www.gnu.org/copyleft/gpl.html  GPL License
13  * @version    SVN: $Id: breadcrumbWidgetContainer.php 5883 2013-03-31 12:22:13Z fishbone $
14  * @link       http://www.m-media.co.jp
15  */
16 require_once($gEnvManager->getContainerPath()           . '/baseWidgetContainer.php');
17 require_once($gEnvManager->getCurrentWidgetDbPath() . '/breadcrumbDb.php');
18
19 class breadcrumbWidgetContainer extends BaseWidgetContainer
20 {
21         private $db;    // DB接続オブジェクト
22         private $currentMacroUrl;               // 現在のマクロ表記URL
23         private $menuItems;             // メニュー項目情報
24         private $iconTag;               // パンくずリストのアイコン
25         const DEFAULT_TITLE = 'パンくずリスト';          // デフォルトのウィジェットタイトル名
26         const DEFAULT_HOME_NAME = 'ホーム';                  // デフォルトのルート階層名
27         const DEFAULT_HOME_URL = '/';                           // デフォルトのホームURL
28         const MAX_MENU_TREE_LEVEL = 5;                  // メニュー階層最大数
29         const MENU_ITEM_NONAME = '名称未設定';     // メニュー項目に名前が設定されていない場合の名前
30         const DEFAULT_ARROW_IMAGE_FILE = '/images/arrow.png';           // パンくずリスト用画像
31         
32         /**
33          * コンストラクタ
34          */
35         function __construct()
36         {
37                 // 親クラスを呼び出す
38                 parent::__construct();
39                 
40                 // DBオブジェクト作成
41                 $this->db = new breadcrumbDb();
42         }
43         /**
44          * テンプレートファイルを設定
45          *
46          * _assign()でデータを埋め込むテンプレートファイルのファイル名を返す。
47          * 読み込むディレクトリは、「自ウィジェットディレクトリ/include/template」に固定。
48          *
49          * @param RequestManager $request               HTTPリクエスト処理クラス
50          * @param object         $param                 任意使用パラメータ。そのまま_assign()に渡る
51          * @return string                                               テンプレートファイル名。テンプレートライブラリを使用しない場合は空文字列「''」を返す。
52          */
53         function _setTemplate($request, &$param)
54         {       
55                 return 'index.tmpl.html';
56         }
57         /**
58          * テンプレートにデータ埋め込む
59          *
60          * _setTemplate()で指定したテンプレートファイルにデータを埋め込む。
61          *
62          * @param RequestManager $request               HTTPリクエスト処理クラス
63          * @param object         $param                 任意使用パラメータ。_setTemplate()と共有。
64          * @param                                                               なし
65          */
66         function _assign($request, &$param)
67         {
68                 $currentUrl = $this->gEnv->getCurrentRequestUri();
69                 
70                 // このシステム外のアクセスの場合は終了
71                 if (!$this->gEnv->isSystemUrlAccess($currentUrl)) return;
72
73                 // ##### メニュー作成開始 #####
74                 // 表示設定を取得
75                 $visibleOnRoot = 1;                             // トップページでリスト表示するかどうか
76                 $useHiddenMenu = 0;             // 非表示のメニューウィジェットの定義を使用する
77                 $separatorImgPath = '';         // 区切り画像パス
78                 $paramObj = $this->getWidgetParamObj();
79                 if (!empty($paramObj)){
80                         $visibleOnRoot  = $paramObj->visibleOnRoot;
81                         if (isset($paramObj->useHiddenMenu)) $useHiddenMenu = $paramObj->useHiddenMenu;         // 非表示のメニューウィジェットの定義を使用する
82                         $separatorImgPath = $paramObj->separatorImgPath;                // 区切り画像パス
83                 }
84                 
85                 // 現在表示中のメニューID取得
86                 $ret = $this->db->getMenuId($useHiddenMenu, $this->gEnv->getCurrentPageId(), $this->gEnv->getCurrentPageSubId(), $allMenu);
87                 if (!$ret) return;
88                 
89                 // パンくずリスト用アイコンを取得
90 /*              $iconUrl = '';
91                 $iconPath = $this->gEnv->getCurrentTemplatePath() . self::TEMPLATE_ARROW_IMAGE_FILE;
92                 if (file_exists($iconPath)) $iconUrl = $this->gEnv->getCurrentTemplateUrl() . self::TEMPLATE_ARROW_IMAGE_FILE;
93                 
94                 // テンプレートのアイコンがないときは、デフォルトのアイコンを使用
95                 if (empty($iconUrl)){
96                         $iconUrl = $this->gEnv->getCurrentWidgetRootUrl() . self::TEMPLATE_ARROW_IMAGE_FILE;
97                 }*/
98                 // 区切り画像
99                 if (empty($separatorImgPath)){
100                         $separatorImgUrl = $this->gEnv->getCurrentWidgetRootUrl() . self::DEFAULT_ARROW_IMAGE_FILE;             // デフォルトの画像
101                 } else {
102                         $separatorImgUrl = $this->gEnv->getRootUrl() . $separatorImgPath;               // ユーザ指定の画像
103                 }
104                 $this->iconTag = ' <img src="' . $this->getUrl($separatorImgUrl) . '" /> ';             // 両端にスペースを入れる
105         
106                 // 重複しないメニューIDを作成
107                 $menuIdArray = array();
108                 for ($i = 0; $i < count($allMenu); $i++){
109                         $menuId = $allMenu[$i]['pd_menu_id'];
110                         if (!in_array($menuId, $menuIdArray)) $menuIdArray[] = $menuId;
111                 }
112
113                 // メニュー項目を取得
114                 $this->db->getMenuItems($menuIdArray, $menuItems);
115
116                 // ルート階層名を取得
117                 $homeName = self::DEFAULT_HOME_NAME;
118                 $homeUrl = M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END . self::DEFAULT_HOME_URL;
119                 for ($i = 0; $i < count($menuItems); $i++){
120                         $url = $menuItems[$i]['md_link_url'];                   // マクロ表記URLを取得
121                         if ($this->isRootUrl($url)){            // ルートの場合
122                                 $homeName = $this->getCurrentLangString($menuItems[$i]['md_name']);
123                                 $homeUrl = $url;
124                                 break;
125                         }
126                 }
127                 // 現在のURLがルートのときは終了
128                 $this->currentMacroUrl = $this->gEnv->getMacroPath($currentUrl);
129                 if ($this->isRootUrl($this->currentMacroUrl)){// ルート位置の場合の処理
130                         if ($visibleOnRoot){            // ルートのときリスト表示するとき
131                                 $html = '<span class="breadcrumbs pathway">' . $this->convertToDispString($homeName) . '</span>';
132                                 $this->tmpl->addVar("_widget", "link", $html);
133                         }
134                         return;
135                 }
136                 
137                 // 現在のURLパラメータを取得
138                 $this->currentQueryArray = array();
139                 list($tmp, $queryStr) = explode('?', $this->currentMacroUrl);
140                 list($queryStr, $tmp) = explode('#', $queryStr);
141                 if (!empty($queryStr)) parse_str($queryStr, $this->currentQueryArray);          // クエリーの解析
142                 
143                 // 現在のメニュー項目を取得
144                 $menuItemId = 0;
145                 for ($i = 0; $i < count($menuItems); $i++){
146                         $url = $menuItems[$i]['md_link_url'];                   // マクロ表記URLを取得
147                         if ($this->isCurrentMenuItemUrl($url)){
148                                 $menuItemId = $menuItems[$i]['md_id'];
149                                 break;
150                         }
151                 }
152                 if (empty($menuItemId)){                // メニュー上にないURLのときは現在のページから作成
153                         // 現在のページがデフォルトのページのときはトップ時と同じにする
154                         $pageSubId = $this->gEnv->getCurrentPageSubId();
155                         if (count($this->currentQueryArray) == 1 && $this->currentQueryArray[M3_REQUEST_PARAM_PAGE_SUB_ID] == $this->gEnv->getDefaultPageSubId()){
156                                 if ($visibleOnRoot){            // ルートのときリスト表示するとき
157                                         $html = '<span class="breadcrumbs pathway">' . $this->convertToDispString($homeName) . '</span>';
158                                         $this->tmpl->addVar("_widget", "link", $html);
159                                         return;
160                                 }
161                         } else {
162                                 $pageName = '';
163                                 $line = $this->gPage->getPageInfo($this->gEnv->getCurrentPageId(), $pageSubId);
164                                 if (!empty($line) && !empty($line['pn_name'])) $pageName = $line['pn_name'];
165
166                                 // ページ名が取得できないときは、ページIDの名前を取得
167                                 if (empty($pageName)){
168                                         $ret = $this->db->getPageRecord($pageSubId, $row);
169                                         if ($ret) $pageName = $row['pg_name'];
170                                 }
171
172                                 // ページサブID以外のパラメータをもつ場合のみリンクを作成
173                                 if (count($this->currentQueryArray) == 1 && isset($this->currentQueryArray[M3_REQUEST_PARAM_PAGE_SUB_ID])){             
174                                         $html = $this->convertToDispString($pageName);
175                                 } else {
176                                         $pageUrl = $this->gEnv->createCurrentPageUrl();
177                                         $linkUrl = $this->getUrl($pageUrl, true/*リンク用*/);
178                                         $html = '<a href="' . $this->convertUrlToHtmlEntity($linkUrl) . '" class="pathway">' . $this->convertToDispString($pageName) . '</a>';
179                                         
180                                         // getHeadSubTitle()はバージョン1.10.9以降利用可能
181                                         if (version_compare(M3_SYSTEM_VERSION, '1.10.9') >= 0){
182                                                 // コンテンツ名が設定されている場合は出力
183                                                 $titleArray = $this->gPage->getHeadSubTitle();
184                                                 if (count($titleArray) > 0){
185                                                         $html .= $this->createTitleLink($titleArray);
186                                                 }
187                                         }
188                                 }
189                         }
190                 } else {
191                         $menuId = $menuItems[$i]['md_menu_id'];
192                 
193                         // メニュー項目IDの連想配列に変換
194                         $this->menuItems = array();
195                         for ($i = 0; $i < count($menuItems); $i++){
196                                 $key = $menuItems[$i][md_id];
197                                 $this->menuItems[$key] = $menuItems[$i];
198                         }
199
200                         // 階層を作成
201                         $menuPathArray = array();
202                         $ret = $this->createMenuPath($menuItemId, $menuPathArray);
203                         $menuPathArray = array_reverse($menuPathArray);         // パスを反転
204
205                         // ローカルメニューの場合とグローバルメニューの場合と処理を分ける
206                         $pageSubId = '';
207                         for ($i = 0; $i < count($allMenu); $i++){
208                                 if ($menuId == $allMenu[$i]['pd_menu_id']){
209                                         $pageSubId = $allMenu[$i]['pd_sub_id'];
210                                         break;
211                                 }
212                         }
213                         if (!empty($pageSubId)){        // ローカルメニューのとき
214                                 // グローバルメニューの該当ページを取得
215                                 $globalMenuItemId = 0;
216                                 for ($i = 0; $i < count($menuItems); $i++){
217                                         $url = $menuItems[$i]['md_link_url'];                   // マクロ表記URLを取得
218                                         if ($this->isPageUrl($url, $pageSubId)){
219                                                 $globalMenuItemId = $menuItems[$i]['md_id'];
220                                                 break;
221                                         }
222                                 }
223                                 if (!empty($globalMenuItemId)){
224                                         // グローバルメニュー階層を作成
225                                         $pathArray = $menuPathArray;
226                                         $menuPathArray = array();
227                                         $ret = $this->createMenuPath($globalMenuItemId, $menuPathArray);
228                                         $menuPathArray = array_reverse($menuPathArray);         // パスを反転
229                                 
230                                         // メニューを連結
231                                         $menuPathArray = array_merge($menuPathArray, $pathArray);
232                                 }
233                         }
234                         // リンク作成
235                         $html = $this->createLink($menuPathArray);
236                 }
237                 if (!empty($html)){             // リンクが空のときは表示しない
238                         $linkUrl = $this->getUrl($homeUrl, true/*リンク用*/);
239                         $html = '<a href="' . $this->convertUrlToHtmlEntity($linkUrl) . '" class="pathway">' . $this->convertToDispString($homeName) . '</a>' . $this->iconTag . $html;// リンクの間にアイコンを挿入
240                         $html = '<span class="breadcrumbs pathway">' . $html . '</span>';
241                         $this->tmpl->addVar("_widget", "link", $html);
242                 }
243         }
244         /**
245          * ウィジェットのタイトルを設定
246          *
247          * @param RequestManager $request               HTTPリクエスト処理クラス
248          * @param object         $param                 任意使用パラメータ。そのまま_assign()に渡る
249          * @return string                                               ウィジェットのタイトル名
250          */
251         function _setTitle($request, &$param)
252         {
253                 return self::DEFAULT_TITLE;
254         }
255         /**
256          * メニューパス作成
257          *
258          * @param int   $menuItemId             メニュー項目ID
259          * @param array $menuPathArray  メニューID
260          * @param int   $level                  階層数
261          * @return bool                                 true=正常終了、false=異常終了
262          */
263         function createMenuPath($menuItemId, &$menuPathArray, $level = 0)
264         {
265                 // メニューの階層を制限
266                 if ($level >= self::MAX_MENU_TREE_LEVEL) return false;
267                 
268                 if (empty($menuItemId)) return true;            // メニューIDが0のときは終了
269                 
270                 // メニューパス追加
271                 $menuPathArray[] = $menuItemId;
272                 
273                 // メニュー項目情報を取得
274                 $menuItemInfo = $this->menuItems[$menuItemId];
275                 if (isset($menuItemInfo)){
276                         // 親メニュー項目のパスを取得
277                         $parentId = $menuItemInfo['md_parent_id'];
278                         $ret = $this->createMenuPath($parentId, $menuPathArray, $level + 1);
279                         return $ret;
280                 } else {
281                         return false;
282                 }
283         }
284         /**
285          * パンくずリスト作成
286          *
287          * @param array $menuPathArray          メニューパス
288          * @return string                                       HTML出力
289          */
290         function createLink($menuPathArray)
291         {
292                 $outputHtml = '';
293                 
294                 $linkCount = count($menuPathArray);
295                 for ($i = 0; $i < $linkCount; $i++){
296                         $menuItemId = $menuPathArray[$i];
297                         
298                         // リンク先の作成
299                         $linkUrl = $this->menuItems[$menuItemId]['md_link_url'];
300                         $linkUrl = $this->getUrl($linkUrl, true/*リンク用*/);
301                         
302                         // メニュー項目を作成
303                         $name = $this->getCurrentLangString($this->menuItems[$menuItemId]['md_name']);
304                         if (empty($name)) $name = self::MENU_ITEM_NONAME;
305                         
306                         // リンクの間にアイコンを挿入
307                         if ($i > 0) $outputHtml .= $this->iconTag;
308                         
309                         if (empty($linkUrl) || $i == $linkCount -1){            // 最後の項目はリンク作成しない
310                                 $outputHtml .= $this->convertToDispString($name) . M3_NL;
311                         } else {
312                                 $outputHtml .= '<a href="' . $this->convertUrlToHtmlEntity($linkUrl) . '" class="pathway">' . $this->convertToDispString($name) . '</a>' . M3_NL;
313                         }
314                 }
315                 return $outputHtml;
316         }
317         /**
318          * 画面タイトルからパンくずリスト作成
319          *
320          * @param array $titleArray             タイトル情報
321          * @return string                               HTML出力
322          */
323         function createTitleLink($titleArray)
324         {
325                 $outputHtml = '';
326                 
327                 $linkCount = count($titleArray);
328                 for ($i = 0; $i < $linkCount; $i++){
329                         $line = $titleArray[$i];
330                         
331                         // リンク先の作成
332                         $linkUrl = $this->getUrl($line['url'], true/*リンク用*/);
333                         
334                         // メニュー項目を作成
335                         $name = $line['title'];
336                         if (empty($name)) $name = self::MENU_ITEM_NONAME;
337                         
338                         // リンクの間にアイコンを挿入
339                         $outputHtml .= $this->iconTag;
340                         
341                         if (empty($linkUrl) || $i == $linkCount -1){            // 最後の項目はリンク作成しない
342                                 $outputHtml .= $this->convertToDispString($name) . M3_NL;
343                         } else {
344                                 $outputHtml .= '<a href="' . $this->convertUrlToHtmlEntity($linkUrl) . '" class="pathway">' . $this->convertToDispString($name) . '</a>' . M3_NL;
345                         }
346                 }
347                 return $outputHtml;
348         }
349         /**
350          * メニュー項目のURLが現在のアクセス中のURLか判断
351          *
352          * @param string $url                   チェック対象のURL
353          * @return bool                                 true=アクセス中、false=非アクセス
354          */
355         function isCurrentMenuItemUrl($url)
356         {
357                 // 同じURLのとき
358                 if ($url == $this->currentMacroUrl) return true;
359                 
360                 // URLを解析
361                 $queryArray = array();
362                 list($tmp, $queryStr) = explode('?', $url);
363                 list($queryStr, $tmp) = explode('#', $queryStr);
364                 if (!empty($queryStr)) parse_str($queryStr, $queryArray);               // クエリーの解析
365                 
366                 // URLパラメータの比較
367         //      $diffArray = array_diff($this->currentQueryArray, $queryArray);
368                 $diffArray = array_diff_assoc($this->currentQueryArray, $queryArray);
369                 if (empty($diffArray)) return true;
370                 
371                 return false;
372         }
373         /**
374          * URLがルートを指しているかどうか取得
375          *
376          * @param string $url   チェック対象のURL(マクロ表記)
377          * @return bool                 true=ルート、false=ルート以外
378          */
379         function isRootUrl($url)
380         {
381                 //$parsedUrl = parse_url($url);
382                 //if (empty($parsedUrl['query'])){              
383                 list($tmp, $query) = explode('?', $url);
384                 if (!empty($query)) list($query, $tmp) = explode('#', $query);
385                 if (empty($query)){                             // クエリ文字列がないことが条件。「#」はあっても良い。
386                         // パスを解析
387                         $relativePath = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, '', $url);               // ルートURLからの相対パスを取得
388                         if (empty($relativePath)){                      // Magic3のルートURLの場合
389                                 return true;
390                         } else if (strStartsWith($relativePath, '/') || strStartsWith($relativePath, '/' . M3_FILENAME_INDEX)){         // ルートURL配下のとき
391                                 return true;
392                         }
393                 }
394                 return false;
395         }
396         /**
397          * URLが指定のページを示すかどうか判断
398          *
399          * @param string $url                   チェック対象のURL
400          * @param string $pageSubId             ページサブID
401          * @return bool                                 true=指定のページを示す、false=指定のページ外
402          */
403         function isPageUrl($url, $pageSubId)
404         {
405                 // URLを解析
406                 $queryArray = array();
407                 list($tmp, $queryStr) = explode('?', $url);
408                 list($queryStr, $tmp) = explode('#', $queryStr);
409                 if (!empty($queryStr)) parse_str($queryStr, $queryArray);               // クエリーの解析
410
411                 // パラメータがサブページIDだけの場合はページサブIDで比較
412                 if (count($queryArray) == 1 && isset($queryArray[M3_REQUEST_PARAM_PAGE_SUB_ID])){
413                         if ($queryArray[M3_REQUEST_PARAM_PAGE_SUB_ID] == $pageSubId) return true;
414                 }
415                 return false;
416         }
417 }
418 ?>