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-2013 Magic3 Project.
12 * @license http://www.gnu.org/copyleft/gpl.html GPL License
13 * @version SVN: $Id: admin_mainMenudefWidgetContainer.php 5812 2013-03-09 13:07:25Z fishbone $
14 * @link http://www.magic3.org
16 require_once($gEnvManager->getCurrentWidgetContainerPath() . '/admin_mainBaseWidgetContainer.php');
17 require_once($gEnvManager->getCurrentWidgetDbPath() . '/admin_mainDb.php');
19 class admin_mainMenudefWidgetContainer extends admin_mainBaseWidgetContainer
21 private $db; // DB接続オブジェクト
22 private $serialNo; // 選択中の項目のシリアル番号(メニュー項目IDを使用)
23 private $serialArray = array(); // 表示中のシリアル番号
24 private $currentPageSubId; // 現在のページサブID
25 private $contentId; // 現在のコンテンツID
26 private $isExistsMenuItem; // メニュー項目が存在するかどうか
27 private $menuId; // 現在選択中のメニューID
28 private $menuItemType; // メニュー項目タイプ
29 private $menuDeviceType; // メニューの端末タイプ
30 private $itemTypeArray; // メニュー項目の種類
31 private $menuHtml; // コンテンツメニュー
32 private $isMultiLang; // 多言語対応画面かどうか
33 private $availableLangRows; // 利用可能な言語
34 private $availableLangArray; // 利用可能な言語
35 private $parentId; // メニュー親項目
36 private $parentIdArray = array(); // メニュー項目パス
37 private $parentNameArray = array(); // メニュー項目名
38 const MAIN_MENU_ID = 'main_menu'; // メインメニューID
39 // const CONTENT_WIDGET_ID = 'default_content'; // コンテンツ編集ウィジェット
40 const MAX_MENU_TREE_LEVEL = 5; // メニュー階層最大数
41 const FILE_ICON_FILE = '/images/system/file.png'; // ファイルアイコン
42 const FOLDER_ICON_FILE = '/images/system/folder.png'; // フォルダアイコン
43 const ICON_SIZE = 16; // アイコンのサイズ
44 const WIDGET_TYPE_MENU = 'menu'; // メニュー型のウィジェット(キャッシュクリア用)
45 const CONTENT_TYPE_PC = ''; // 汎用コンテンツのコンテンツタイプ(PC用)
46 const CONTENT_TYPE_MOBILE = 'mobile'; // 汎用コンテンツのコンテンツタイプ(携帯用)
47 const CONTENT_TYPE_SMARTPHONE = 'smartphone'; // 汎用コンテンツのコンテンツタイプ(スマートフォン用)
48 const CONTENT_WIDGET_ID_PC = 'default_content'; // コンテンツ編集ウィジェット(PC用)
49 const CONTENT_WIDGET_ID_MOBILE = 'm/content'; // コンテンツ編集ウィジェット(携帯用)
50 const CONTENT_WIDGET_ID_SMARTPHONE = 's/content'; // コンテンツ編集ウィジェット(スマートフォン用)
51 const LANG_ICON_PATH = '/images/system/flag/'; // 言語アイコンパス
52 const ITEM_NAME_HEAD = 'item_name_'; // 多言語対応名前ヘッダ
53 const TREE_ITEM_HEAD = 'treeitem_'; // ツリー項目IDヘッダ
58 function __construct()
61 parent::__construct();
64 $this->db = new admin_mainDb();
67 $this->itemTypeArray = array( array( 'name' => $this->_('Link'), 'value' => '0'), // リンク
68 array( 'name' => $this->_('Folder'), 'value' => '1'), // フォルダ
69 array( 'name' => $this->_('Text'), 'value' => '2'), // テキスト
70 array( 'name' => $this->_('Separator'), 'value' => '3')); // セパレータ
72 // ##### 多言語対応用データ作成 #####
73 $this->isMultiLang = $this->gEnv->isMultiLanguageSite(); // 多言語対応画面かどうか
74 $this->availableLangRows = array();
75 $this->availableLangArray = array();
76 $ret = $this->db->getAvailableLang($rows); // 利用可能な言語を取得
78 for ($i = 0; $i < count($rows); $i++){
79 $langId = $rows[$i]['ln_id'];
80 $this->availableLangArray[$langId] = $rows[$i];
82 $this->availableLangRows = $rows;
88 * _assign()でデータを埋め込むテンプレートファイルのファイル名を返す。
89 * 読み込むディレクトリは、「自ウィジェットディレクトリ/include/template」に固定。
91 * @param RequestManager $request HTTPリクエスト処理クラス
92 * @param object $param 任意使用パラメータ。そのまま_assign()に渡る
93 * @return string テンプレートファイル名。テンプレートライブラリを使用しない場合は空文字列「''」を返す。
95 function _setTemplate($request, &$param)
97 $task = $request->trimValueOf('task');
98 if ($task == 'menudef_detail'){ // 詳細画面
99 return 'menudef_detail.tmpl.html';
101 return 'menudef.tmpl.html';
107 * ヘルプの設定を行う場合はヘルプIDを返す。
108 * ヘルプデータの読み込むディレクトリは「自ウィジェットディレクトリ/include/help」に固定。
110 * @param RequestManager $request HTTPリクエスト処理クラス
111 * @param object $param 任意使用パラメータ。そのまま_assign()に渡る
112 * @return string ヘルプID。ヘルプデータはファイル名「help_[ヘルプID].php」で作成。ヘルプを使用しない場合は空文字列「''」を返す。
114 function _setHelp($request, &$param)
121 * _setTemplate()で指定したテンプレートファイルにデータを埋め込む。
123 * @param RequestManager $request HTTPリクエスト処理クラス
124 * @param object $param 任意使用パラメータ。_setTemplate()と共有。
127 function _assign($request, &$param)
129 $localeText = array();
130 $task = $request->trimValueOf('task');
132 if ($task == 'menudef_detail'){ // 詳細画面
133 $this->createDetail($request);
136 $localeText['msg_add'] = $this->_('Add menu item?'); // 項目を新規追加しますか?
137 $localeText['msg_update'] = $this->_('Update menu item?'); // 項目を更新しますか?
138 $localeText['msg_delete'] = $this->_('Delete menu item?'); // 項目を削除しますか?
139 $localeText['label_menu_item_detail'] = $this->_('Menu Item Detail'); // メニュー項目詳細
140 $localeText['label_go_back'] = $this->_('Go back'); // 戻る
141 $localeText['label_name'] = $this->_('Name'); // 名前
142 $localeText['label_lang'] = $this->_('Language'); // 言語
143 $localeText['label_new'] = $this->_('New'); // 新規
144 $localeText['label_item_type'] = $this->_('Item Type'); // 項目タイプ
145 $localeText['label_link_type'] = $this->_('Link Type'); // 表示方法
146 $localeText['label_link_self'] = $this->_('Open page in the same window'); // 同ウィンドウで表示
147 $localeText['label_link_other'] = $this->_('Open page in the other window'); // 別ウィンドウで表示
148 $localeText['label_select_link'] = $this->_('Select Link Type'); // リンク先を選択
149 $localeText['label_unselected'] = $this->_('Unselected'); // 未選択
150 $localeText['label_link_top'] = $this->_('Top'); // トップ
151 $localeText['label_input'] = $this->_('Input URL'); // URL任意設定
152 $localeText['label_page_id'] = $this->_('Page ID:'); // ページID:
153 $localeText['label_content'] = $this->_('General Contents:'); // 汎用コンテンツ:
154 $localeText['label_url'] = $this->_('URL'); // リンク先URL
155 $localeText['label_item_visible'] = $this->_('Item Control'); // 表示制御
156 $localeText['label_visible'] = $this->_('Visible'); // 公開
157 $localeText['msg_user_limited'] = $this->_('Limit user'); // ユーザ制限
158 $localeText['msg_link_to_content'] = $this->_('Cotrol visible status linked to contents.'); // リンク先のコンテンツに連動
159 $localeText['label_desc'] = $this->_('Description'); // 説明
160 $localeText['label_delete'] = $this->_('Delete'); // 削除
161 $localeText['label_update'] = $this->_('Update'); // 更新
162 $localeText['label_add'] = $this->_('Add'); // 新規追加
164 $this->createList($request);
167 $localeText['msg_select_item'] = $this->_('Select menu item to edit.'); // 編集する項目を選択してください
168 $localeText['msg_select_del_item'] = $this->_('Select menu item to delete.'); // 削除する項目を選択してください
169 $localeText['msg_delete_item'] = $this->_('Delete selected item?');// 選択項目を削除しますか?
170 $localeText['label_menu_item_list'] = $this->_('Menu Item List'); // メニュー項目一覧
171 $localeText['label_path'] = $this->_('Path:'); // 階層パス
172 $localeText['label_new'] = $this->_('New'); // 新規
173 $localeText['label_edit'] = $this->_('Edit'); // 編集
174 $localeText['label_delete'] = $this->_('Delete'); // 削除
175 $localeText['label_check'] = $this->_('Select'); // 選択
176 $localeText['label_name'] = $this->_('Name'); // 名前
177 $localeText['label_lang'] = $this->_('Language'); // 言語
178 $localeText['label_url'] = $this->_('URL'); // リンク先URL
179 $localeText['label_link_type'] = $this->_('Link Type'); // 表示方法
180 $localeText['label_visible'] = $this->_('Visible'); // 公開
181 $localeText['label_operation'] = $this->_('Operation'); // 操作
182 $localeText['label_menu_layout'] = $this->_('Menu Layout'); // メニューレイアウト
183 $localeText['msg_change_item_order'] = $this->_('Menu items can be sorted by mouse drag and drop.'); // マウスドラッグで項目の表示順を変更できます
184 $localeText['label_menu_top'] = $this->_('Menu Top'); // メニュートップ
185 $localeText['label_open_all'] = $this->_('Open All'); // すべて開く
186 $localeText['label_close_all'] = $this->_('Close All'); // すべて閉じる
188 $this->setLocaleText($localeText);
193 * @param RequestManager $request HTTPリクエスト処理クラス
196 function createList($request)
198 $userId = $this->gEnv->getCurrentUserId();
199 $langId = $this->gEnv->getCurrentLanguage(); // 表示言語を取得
201 $fixedMode = $request->trimValueOf('fixed_mode'); // メニュー定義IDが固定かどうか
202 if ($fixedMode == ''){ // 値が設定されていないときは設定
203 if ($request->trimValueOf('menuid') == ''){
206 $fixedMode = '1'; // 固定
209 $this->menuId = $request->trimValueOf('menuid'); // 現在選択中のメニュータイプ
210 if ($this->menuId == '') $this->menuId = self::MAIN_MENU_ID; // デフォルトは通常のメニュー
213 $this->menuDeviceType = 0; // メニューの端末タイプ
214 $ret = $this->db->getMenuId($this->menuId, $row);
215 if ($ret) $this->menuDeviceType = $row['mn_device_type'];
218 switch ($this->menuDeviceType){
221 $contType = self::CONTENT_TYPE_PC; // 汎用コンテンツのコンテンツタイプ
224 $contType = self::CONTENT_TYPE_MOBILE; // 汎用コンテンツのコンテンツタイプ
227 $contType = self::CONTENT_TYPE_SMARTPHONE; // 汎用コンテンツのコンテンツタイプ
231 $act = $request->trimValueOf('act');
232 $this->parentId = $request->trimValueOf('parentid'); // 親メニューID取得
233 if ($this->parentId == '') $this->parentId = '0';
235 if ($act == 'delete'){ // メニュー項目の削除
236 $listedItem = explode(',', $request->trimValueOf('seriallist'));
238 for ($i = 0; $i < count($listedItem); $i++){
240 $itemName = 'item' . $i . '_selected';
241 $itemValue = ($request->trimValueOf($itemName) == 'on') ? 1 : 0;
243 if ($itemValue){ // チェック項目
244 $delItems[] = $listedItem[$i];
247 $ret = $this->db->getChildMenuItems($this->menuId, $listedItem[$i], $rows);
249 $this->setAppErrorMsg($this->_('You are not allowed to delete menu item with child item.')); // 子項目を持つメニュー項目は削除できません。
255 if ($this->getMsgCount() == 0){
256 if (count($delItems) > 0){
257 $ret = $this->db->delMenuItems(implode($delItems, ','));
258 if ($ret){ // データ削除成功のとき
259 //$this->setGuidanceMsg('データを削除しました');
260 $this->setGuidanceMsg($this->_('Menu item deleted.')); // データを削除しました
262 //$this->setAppErrorMsg('データ削除に失敗しました');
263 $this->setAppErrorMsg($this->_('Failed in deleting menu item.')); // データ削除に失敗しました
266 $this->gCache->clearCacheByWidgetType(self::WIDGET_TYPE_MENU); // キャッシュをクリア
267 $this->gPage->updateParentWindow();// 親ウィンドウを更新
269 } else if ($act == 'selecttree'){ // メニューツリーから選択
270 $this->parentId = str_replace(self::TREE_ITEM_HEAD, '', $request->trimValueOf('treedest'));
271 } else if ($act == 'updatetree'){ // メニューツリーからの更新
272 $treeId = str_replace(self::TREE_ITEM_HEAD, '', $request->trimValueOf('treesrc'));
273 $treeParentId = str_replace(self::TREE_ITEM_HEAD, '', $request->trimValueOf('treedest'));
274 $treePos = $request->trimValueOf('treepos');
275 $this->db->reorderMenuItem($this->menuId, $treeParentId, $treeId, $treePos);
277 $this->gCache->clearCacheByWidgetType(self::WIDGET_TYPE_MENU); // キャッシュをクリア
278 $this->gPage->updateParentWindow();// 親ウィンドウを更新
281 if (!empty($this->parentId)){
283 $this->parentIdArray = $this->getPath($this->menuId, $this->parentId);
286 $this->tmpl->setAttribute('select_tree_area', 'visibility', 'visible');
287 $this->tmpl->addVar("select_tree_area", "select_id", self::TREE_ITEM_HEAD . $this->parentId); // 選択中のメニュー項目
291 if ($this->isMultiLang){ // 多言語対応の場合
292 $this->tmpl->setAttribute('show_multilang', 'visibility', 'visible');
294 $this->tmpl->setAttribute('show_singlelang', 'visibility', 'visible');
298 $this->db->getMenuIdList(array($this, 'menuIdListLoop'));
301 $treeMenu = $this->createTreeMenu($this->menuId, 0);
303 // メニュー項目が存在しないときはメニューのプレビューを表示しない
304 if (!$this->isExistsMenuItem) $this->tmpl->setAttribute('itemlist', 'visibility', 'hidden'); // メニュー項目一覧
305 if ($fixedMode == '1') $this->tmpl->addVar("_widget", "sel_menu_id_disabled", 'disabled'); // メニューIDの選択可否
308 if (empty($this->parentIdArray)){
311 $path = '<a href="#" onclick="selectTree(0);">[ルート]</a>';
313 for ($i = 0; $i < count($this->parentIdArray); $i++){
314 $path .= ' / ';
315 $path .= '<a href="#" onclick="selectTree(' . $this->parentIdArray[$i] . ');">' . $this->convertToDispString($this->parentNameArray[$i]) . '</a>';
320 case self::CONTENT_TYPE_PC: // PC用
322 $contentEditWidget = self::CONTENT_WIDGET_ID_PC;
324 case self::CONTENT_TYPE_MOBILE: // 携帯用
325 $contentEditWidget = self::CONTENT_WIDGET_ID_MOBILE;
327 case self::CONTENT_TYPE_SMARTPHONE: // スマートフォン用
328 $contentEditWidget = self::CONTENT_WIDGET_ID_SMARTPHONE;
332 if (!empty($this->parentId)){
334 $ret = $this->db->getMenuItem($this->parentId, $row);
336 if ($row['md_type'] != 1){ // フォルダ以外のとき
337 $this->tmpl->addVar("_widget", "new_disabled", 'disabled'); // 「新規」ボタン
338 $this->tmpl->addVar("_widget", "edit_disabled", 'disabled'); // 「編集」ボタン
339 $this->tmpl->addVar("_widget", "del_disabled", 'disabled'); // 「削除」ボタン
344 $this->tmpl->addVar("_widget", "tree", $treeMenu); // メニューツリー
345 $this->tmpl->addVar("_widget", "parent_id", $this->parentId); // メニュー項目親ID
346 $this->tmpl->addVar("_widget", "serial_list", implode($this->serialArray, ','));// 表示項目のシリアル番号を設定
347 $this->tmpl->addVar('_widget', 'content_widget_id', $contentEditWidget);// コンテンツ表示ウィジェット
348 $this->tmpl->addVar('_widget', 'admin_url', $this->getUrl($this->gEnv->getDefaultAdminUrl()));// 管理者URL
349 $this->tmpl->addVar("_widget", "fixed_mode", $fixedMode); // メニュー定義IDが固定かどうか
350 $this->tmpl->addVar("_widget", "path", $path); // メニュー階層パス
353 $this->tmpl->addVar("_widget", "script_url", $this->getUrl($this->gEnv->getScriptsUrl()));
358 * @param RequestManager $request HTTPリクエスト処理クラス
361 function createDetail($request)
363 $userId = $this->gEnv->getCurrentUserId();
364 $langId = $this->gEnv->getCurrentLanguage(); // 表示言語を取得
366 $fixedMode = $request->trimValueOf('fixed_mode'); // メニュー定義IDが固定かどうか
367 $act = $request->trimValueOf('act');
368 $this->serialNo = $request->trimValueOf('serial'); // 選択項目のシリアル番号
369 $value = $request->trimValueOf('item_sel_menuid');
370 if ($value != '') $this->serialNo = $value; // メニュー項目が選択されている場合はシリアル番号を更新
371 $this->menuId = $request->trimValueOf('menuid'); // 現在選択中のメニューID
372 $parentId = $request->trimValueOf('parentid'); // 親メニューID取得
373 if ($parentId == '') $parentId = '0';
375 $name = $request->trimValueOf('item_name');
376 $desc = $request->trimValueOf('item_desc');
377 $this->menuItemType = $request->trimValueOf('item_type');
378 if ($this->menuItemType == '') $this->menuItemType = '0'; // デフォルトの項目タイプは通常リンク
379 $linkType = $request->trimValueOf('item_link_type');
380 $visible = ($request->trimValueOf('item_visible') == 'on') ? 1 : 0; // チェックボックス
381 $userLimited = ($request->trimValueOf('item_user_limited') == 'on') ? 1 : 0; // ユーザ制限するかどうか
382 $linkContent = ($request->trimValueOf('item_link_content') == 'on') ? 1 : 0; // コンテンツにリンクしてメニュー項目を表示制御するかどうか
383 $this->currentPageSubId = $request->trimValueOf('item_sub_id'); // ページサブID
384 $this->contentId = $request->trimValueOf('item_content_id'); // コンテンツID
385 $url = $request->trimValueOf('item_url'); // 決定したURL
386 $url = str_replace($this->gEnv->getRootUrl(), M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, $url);// マクロ変換
389 if ($this->isMultiLang){ // 多言語対応の場合
390 $nameLangArray = array(); // 多言語対応文字列
391 for ($i = 0; $i < count($this->availableLangRows); $i++){
392 $inputLangId = $this->availableLangRows[$i]['ln_id'];
394 $itemName = self::ITEM_NAME_HEAD . $inputLangId;
395 $itemValue = $request->trimValueOf($itemName);
396 if (!empty($itemValue)) $nameLangArray[$inputLangId] = $itemValue;
399 if (!empty($name)) $nameLangArray[$this->gEnv->getDefaultLanguage()] = $name;
402 $this->menuDeviceType = 0; // メニューの端末タイプ
403 $ret = $this->db->getMenuId($this->menuId, $row);
404 if ($ret) $this->menuDeviceType = $row['mn_device_type'];
407 switch ($this->menuDeviceType){
410 $contType = self::CONTENT_TYPE_PC; // 汎用コンテンツのコンテンツタイプ
413 $contType = self::CONTENT_TYPE_MOBILE; // 汎用コンテンツのコンテンツタイプ
416 $contType = self::CONTENT_TYPE_SMARTPHONE; // 汎用コンテンツのコンテンツタイプ
420 $reloadData = false; // データの再読み込み
421 if ($act == 'add'){// 新規追加
423 $this->checkInput($name, $this->_('Name')); // 名前
424 $this->checkInput($this->menuId, $this->_('Menu ID')); // メニューID
427 if ($this->getMsgCount() == 0){
428 // リンク先でメニューの表示制御を行う場合は、リンク先コンテンツタイプ、IDを取得
429 $linkContentType = ''; // コンテンツタイプ
430 $linkContentId = ''; // コンテンツID
431 if (!empty($linkContent)){
432 list($tmp, $queryStr) = explode('?', $url, 2);
433 if (!empty($queryStr)){
434 parse_str($queryStr, $params);
435 if (isset($params[M3_REQUEST_PARAM_CONTENT_ID]) || isset($params[M3_REQUEST_PARAM_CONTENT_ID_SHORT])){
436 $linkContentType = M3_VIEW_TYPE_CONTENT; // 汎用コンテンツ
437 $linkContentId = isset($params[M3_REQUEST_PARAM_CONTENT_ID]) ? $params[M3_REQUEST_PARAM_CONTENT_ID] : $params[M3_REQUEST_PARAM_CONTENT_ID_SHORT];
442 // ##### 格納用の名前を作成 #####
443 if ($this->isMultiLang){ // 多言語対応の場合
444 $nameLangStr = $this->serializeLangArray($nameLangArray);
446 $nameLangStr = $name;
448 $ret = $this->db->addMenuItem($this->menuId, $parentId, $nameLangStr, $desc, 0/*項目順は自動設定*/, $this->menuItemType, $linkType, $url,
449 $visible, $userLimited, $newId, $linkContentType, $linkContentId);
451 //$this->setGuidanceMsg('データを追加しました');
452 $this->setGuidanceMsg($this->_('Menu item added.')); // データを追加しました
453 $this->serialNo = $newId; // メニュー項目IDを更新
454 $reloadData = true; // データの再読み込み
456 //$this->setAppErrorMsg('データ追加に失敗しました');
457 $this->setAppErrorMsg($this->_('Failed in adding menu item.')); // データ追加に失敗しました
459 $this->gCache->clearCacheByWidgetType(self::WIDGET_TYPE_MENU); // キャッシュをクリア
460 $this->gPage->updateParentWindow();// 親ウィンドウを更新
462 } else if ($act == 'update'){ // 項目更新の場合
464 $this->checkInput($name, $this->_('Name')); // 名前
467 if ($this->getMsgCount() == 0){
468 // リンク先でメニューの表示制御を行う場合は、リンク先コンテンツタイプ、IDを取得
469 $linkContentType = ''; // コンテンツタイプ
470 $linkContentId = ''; // コンテンツID
471 if (!empty($linkContent)){
472 list($tmp, $queryStr) = explode('?', $url, 2);
473 if (!empty($queryStr)){
474 parse_str($queryStr, $params);
475 if (isset($params[M3_REQUEST_PARAM_CONTENT_ID]) || isset($params[M3_REQUEST_PARAM_CONTENT_ID_SHORT])){
476 $linkContentType = M3_VIEW_TYPE_CONTENT; // 汎用コンテンツ
477 $linkContentId = isset($params[M3_REQUEST_PARAM_CONTENT_ID]) ? $params[M3_REQUEST_PARAM_CONTENT_ID] : $params[M3_REQUEST_PARAM_CONTENT_ID_SHORT];
482 // ##### 格納用の名前を作成 #####
483 if ($this->isMultiLang){ // 多言語対応の場合
484 $nameLangStr = $this->serializeLangArray($nameLangArray);
486 $nameLangStr = $name;
488 $ret = $this->db->updateMenuItem($this->serialNo, $nameLangStr, $desc, $this->menuItemType, $linkType, $url,
489 $visible, $userLimited, $linkContentType, $linkContentId);
491 //$this->setGuidanceMsg('データを更新しました');
492 $this->setGuidanceMsg($this->_('Menu item updated.')); // データを更新しました
494 $reloadData = true; // データの再読み込み
496 //$this->setAppErrorMsg('データ更新に失敗しました');
497 $this->setAppErrorMsg($this->_('Failed in updating menu item.')); // データ更新に失敗しました
499 $this->gCache->clearCacheByWidgetType(self::WIDGET_TYPE_MENU); // キャッシュをクリア
500 $this->gPage->updateParentWindow();// 親ウィンドウを更新
502 } else if ($act == 'delete'){ // 項目削除の場合
503 $ret = $this->db->delMenuItems($this->serialNo);
504 if ($ret){ // データ削除成功のとき
505 //$this->setGuidanceMsg('データを削除しました');
506 $this->setGuidanceMsg($this->_('Menu item deleted.')); // データを削除しました
508 //$this->setAppErrorMsg('データ削除に失敗しました');
509 $this->setAppErrorMsg($this->_('Failed in deleting menu item.')); // データ削除に失敗しました
511 $this->gCache->clearCacheByWidgetType(self::WIDGET_TYPE_MENU); // キャッシュをクリア
512 $this->gPage->updateParentWindow();// 親ウィンドウを更新
513 } else if ($act == 'select'){ // ページサブIDを変更
514 if ($this->currentPageSubId == '_root'){
515 $url = M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END . '/';
516 } else if ($this->currentPageSubId == '_other'){ // 任意設定以外のとき
519 $url = $this->gEnv->getDefaultUrl() . '?' . M3_REQUEST_PARAM_PAGE_SUB_ID . '=' . $this->currentPageSubId;
520 if (!empty($this->contentId)) $url .= '&' . M3_REQUEST_PARAM_CONTENT_ID . '=' . $this->contentId;
522 } else if ($act == 'getmenu'){ // コンテンツ選択メニュー取得
524 $contentSerial = $request->trimValueOf('content_serial');
525 $ret = $this->db->getContentBySerial($contentSerial, $row);
526 if ($ret) $this->contentId = $row['cn_id'];
529 $this->menuHtml = '<select name="item_content_id" onchange="selectPage();">';
530 $this->menuHtml .= '<option value="">-- 未選択 --</option>';
531 $this->db->getAllContents($langId, $contType, array($this, 'contentListLoop'));
532 $this->menuHtml .= '</select>';
533 $this->gInstance->getAjaxManager()->addData('menu_html', $this->menuHtml);
535 $reloadData = true; // データの再読み込み
538 if ($reloadData){ // データの再読み込み
539 if (empty($this->serialNo)){ // 新規項目追加のとき
541 $linkType = 0; // リンクタイプ
543 $userLimited = 0;// ユーザ制限するかどうか
544 $linkContent = 0; // コンテンツにリンクしてメニュー項目を表示制御するかどうか
547 $ret = $this->db->getMenuItem($this->serialNo, $row);
550 $this->serialNo = $row['md_id']; // ID
551 $name = $this->getDefaultLangString($row['md_name']); // 名前
552 $desc = $row['md_description']; // 説明
553 $this->menuItemType = $row['md_type']; // 項目タイプ
554 $linkType = $row['md_link_type']; // リンクタイプ
555 $visible = $row['md_visible'];
556 $userLimited = $row['md_user_limited'];// ユーザ制限するかどうか
557 $url = $row['md_link_url']; // リンク先
560 if ($url == M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END . '/'){ // トップのとき
561 $this->currentPageSubId = '_root';
564 $testUrl = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, $this->gEnv->getRootUrl(), $url); // マクロ展開
565 $ret = $this->gEnv->parseUrl($testUrl, $pageId, $pageSubId, $paramArray);
566 if (!$ret) $this->currentPageSubId = '_other'; // 他サイトへのリンクのとき
568 // コンテンツにリンクしてメニュー項目を表示制御するかどうか
570 if (!empty($row['md_content_type'])) $linkContent = 1; // リンクコンテンツが設定されている場合はメニューの表示制御を行う
572 // ##### 多言語対応用データ作成 #####
573 if ($this->isMultiLang){ // 多言語対応の場合
574 $nameLangArray = $this->unserializeLangArray($row['md_name']);
580 $url = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, $this->gEnv->getRootUrl(), $url); // マクロ展開
582 $contentType = ''; // コンテンツタイプ(ページ属性)
583 if ($this->currentPageSubId == '_root'){
584 $this->tmpl->setAttribute('input_no_url', 'visibility', 'visible');// URL非表示データ
585 $this->tmpl->addVar('_widget', 'root_selected', 'selected'); // ページサブID選択
586 } else if ($this->currentPageSubId == '_other'){
587 $this->tmpl->setAttribute('input_url', 'visibility', 'visible');// URL入力エリア表示
588 $this->tmpl->addVar('_widget', 'other_selected', 'selected'); // ページサブID選択
589 } else { // ルート、任意設定以外のとき
590 $this->tmpl->setAttribute('input_no_url', 'visibility', 'visible');// URL非表示データ
593 $ret = $this->gEnv->parseUrl($url, $pageId, $pageSubId, $paramArray);
595 $this->currentPageSubId = $pageSubId;
598 $ret = $this->db->getPageInfo($this->gEnv->getDefaultPageId(), $this->currentPageSubId, $row);
600 $contentType = $row['pn_content_type'];
602 // メニューの端末タイプごとのアクセスポイントを取得
603 // 汎用コンテンツのコンテンツタイプを取得
604 switch ($this->menuDeviceType){
607 $url = $this->gEnv->getDefaultUrl();
610 $url = $this->gEnv->getDefaultMobileUrl();
613 $url = $this->gEnv->getDefaultSmartphoneUrl();
618 switch ($contentType){
619 case M3_VIEW_TYPE_CONTENT: // 汎用コンテンツ
620 $this->contentId = $paramArray[M3_REQUEST_PARAM_CONTENT_ID];
621 $url .= '?' . M3_REQUEST_PARAM_CONTENT_ID . '=' . $this->contentId;
623 case M3_VIEW_TYPE_PRODUCT: // 製品
624 case M3_VIEW_TYPE_BBS: // BBS
625 case M3_VIEW_TYPE_BLOG: // ブログ
626 case M3_VIEW_TYPE_WIKI: // wiki
627 case M3_VIEW_TYPE_USER: // ユーザ作成コンテンツ
629 $url .= '?' . M3_REQUEST_PARAM_PAGE_SUB_ID . '=' . $this->currentPageSubId;
636 switch ($contentType){
637 case M3_VIEW_TYPE_CONTENT: // 汎用コンテンツ
638 $this->tmpl->setAttribute('sel_content', 'visibility', 'visible');// コンテンツ選択メニュー表示
639 $this->db->getAllContents($langId, $contType, array($this, 'contentListLoop'));
641 case M3_VIEW_TYPE_PRODUCT: // 製品
643 case M3_VIEW_TYPE_BBS: // BBS
645 case M3_VIEW_TYPE_BLOG: // ブログ
647 case M3_VIEW_TYPE_WIKI: // wiki
649 case M3_VIEW_TYPE_USER: // ユーザ作成コンテンツ
656 //$this->db->getPageIdList(array($this, 'pageSubIdLoop'), 1);// ウィジェットサブIDメニュー作成
657 switch ($this->menuDeviceType){
660 $defaultPageId = $this->gEnv->getDefaultPageId();
663 $defaultPageId = $this->gEnv->getDefaultMobilePageId();
666 $defaultPageId = $this->gEnv->getDefaultSmartphonePageId();
669 $this->db->getPageSubIdList($defaultPageId, ''/*言語なし*/, array($this, 'pageSubIdLoop'));
672 $this->createItemTypeMenu();
675 $this->db->getAllMenuItems($this->menuId, array($this, 'menuIdLoop'));
679 case self::CONTENT_TYPE_PC: // PC用
681 $contentEditWidget = self::CONTENT_WIDGET_ID_PC;
683 case self::CONTENT_TYPE_MOBILE: // 携帯用
684 $contentEditWidget = self::CONTENT_WIDGET_ID_MOBILE;
686 case self::CONTENT_TYPE_SMARTPHONE: // スマートフォン用
687 $contentEditWidget = self::CONTENT_WIDGET_ID_SMARTPHONE;
692 if ($this->isMultiLang){ // 多言語対応の場合
694 $this->tmpl->addVar("_widget", "lang", $this->createLangImage($this->gEnv->getDefaultLanguage()));
697 $this->tmpl->setAttribute('input_lang', 'visibility', 'visible');
698 $this->createInputLangText($nameLangArray);
702 $this->tmpl->addVar("_widget", "sel_item_name", $name); // 名前
703 $this->tmpl->addVar("_widget", "desc", $desc); // 説明
704 $this->tmpl->addVar("_widget", "sel_url", $url); // 表示するURL
705 $this->tmpl->addVar("input_url", "sel_url", $url); // 表示するURL
706 $this->tmpl->addVar("input_no_url", "sel_url", $url); // 表示するURL
708 if (!empty($contentType)) $attrStr = $this->_('Page Attribute:') . ' ' . $contentType; // ページ属性:
709 $this->tmpl->addVar("_widget", "attr", $attrStr); // ページ属性
710 $this->tmpl->addVar('_widget', 'content_widget_id', $contentEditWidget);// コンテンツ表示ウィジェット
713 case 0: // 同ウィンドウで開くリンク
714 $this->tmpl->addVar("_widget", "link_type_0", 'selected');
716 case 1: // 別ウィンドウで開くリンク
717 $this->tmpl->addVar("_widget", "link_type_1", 'selected');
720 // 項目表示、項目利用可否チェックボックス
722 if ($visible) $visibleStr = 'checked';
723 $this->tmpl->addVar("_widget", "sel_item_visible", $visibleStr);
725 if (!empty($userLimited)) $checked = 'checked';
726 $this->tmpl->addVar("_widget", "user_limited_checked", $checked); // ユーザ制限するかどうか
728 if (!empty($linkContent)) $checked = 'checked';
729 $this->tmpl->addVar("_widget", "link_content", $checked);
732 $this->tmpl->addVar("_widget", "serial", $this->serialNo);
733 $this->tmpl->addVar("_widget", "menu_id", $this->menuId); // メニューID
734 $this->tmpl->addVar("_widget", "parent_id", $parentId); // メニュー項目親ID
735 $this->tmpl->addVar("_widget", "fixed_mode", $fixedMode); // メニュー定義IDが固定かどうか
738 if (empty($this->serialNo)){ // 新規追加項目を選択しているとき
739 $this->tmpl->setAttribute('add_button', 'visibility', 'visible');// 「新規追加」ボタン
741 $this->tmpl->setAttribute('del_button', 'visibility', 'visible');// 「削除」ボタン
744 $ret = $this->db->getChildMenuItems($this->menuId, $this->serialNo, $rows);
745 if ($ret) $this->tmpl->addVar('del_button', 'del_button_disabled', 'disabled');
749 * ページID、取得したデータをテンプレートに設定する
751 * @param int $index 行番号(0~)
752 * @param array $fetchedRow フェッチ取得した行
753 * @param object $param 未使用
754 * @return bool true=処理続行の場合、false=処理終了の場合
756 function pageIdLoop($index, $fetchedRow, $param)
760 'value' => $this->convertToDispString($fetchedRow['pg_id']), // ページID
761 'name' => $this->convertToDispString($fetchedRow['pg_name']), // ページ名
762 'selected' => $selected // 選択中かどうか
764 $this->tmpl->addVars('main_id_list', $row);
765 $this->tmpl->parseTemplate('main_id_list', 'a');
769 * ページサブID、取得したデータをテンプレートに設定する
771 * @param int $index 行番号(0~)
772 * @param array $fetchedRow フェッチ取得した行
773 * @param object $param 未使用
774 * @return bool true=処理続行の場合、false=処理終了の場合
776 function pageSubIdLoop($index, $fetchedRow, $param)
779 if ($fetchedRow['pg_id'] == $this->currentPageSubId) $selected = 'selected'; // 現在のページサブID
781 $contentType = $fetchedRow['pn_content_type'];
782 $name = $fetchedRow['pg_id'];
783 if (!empty($contentType)) $name .= '[' . $contentType . ']';
784 $name .= ' - ' . $fetchedRow['pg_name'];
787 'value' => $this->convertToDispString($fetchedRow['pg_id']), // ページID
788 'name' => $this->convertToDispString($name), // ページ名
789 'selected' => $selected // 選択中かどうか
791 $this->tmpl->addVars('sub_id_list', $row);
792 $this->tmpl->parseTemplate('sub_id_list', 'a');
796 * 取得したデータをテンプレートに設定する
798 * @param int $index 行番号(0~)
799 * @param array $fetchedRow フェッチ取得した行
800 * @param object $param 未使用
801 * @return bool true=処理続行の場合、false=処理終了の場合
803 function contentListLoop($index, $fetchedRow, $param)
805 $id = $fetchedRow['cn_id'];
807 if ($id == $this->contentId) $selected = 'selected'; // 現在のコンテンツID
809 'value' => $this->convertToDispString($id), // ページID
810 'name' => $this->convertToDispString($fetchedRow['cn_name']), // ページ名
811 'selected' => $selected // 選択中かどうか
813 $this->tmpl->addVars('content_list', $row);
814 $this->tmpl->parseTemplate('content_list', 'a');
817 $this->menuHtml .= '<option value="' . $id . '" ' . $selected . '>' . $this->convertToDispString($fetchedRow['cn_name']) . '</option>';
821 * 取得したデータをテンプレートに設定する
823 * @param int $index 行番号(0~)
824 * @param array $fetchedRow フェッチ取得した行
825 * @param object $param 未使用
826 * @return bool true=処理続行の場合、false=処理終了の場合
828 function menuIdListLoop($index, $fetchedRow, $param)
830 $value = $fetchedRow['mn_id'];
831 $name = $value . ' - ' . $fetchedRow['mn_name'];
834 if ($value == $this->menuId) $selected = 'selected';
837 'value' => $this->convertToDispString($value), // ページID
838 'name' => $this->convertToDispString($name), // ページ名
839 'selected' => $selected // 選択中かどうか
841 $this->tmpl->addVars('menu_id_list', $row);
842 $this->tmpl->parseTemplate('menu_id_list', 'a');
850 function createItemTypeMenu()
852 for ($i = 0; $i < count($this->itemTypeArray); $i++){
853 $value = $this->itemTypeArray[$i]['value'];
854 $name = $this->itemTypeArray[$i]['name'];
857 if ($value == $this->menuItemType) $selected = 'selected';
860 'value' => $value, // ページID
861 'name' => $name, // ページ名
862 'selected' => $selected // 選択中かどうか
864 $this->tmpl->addVars('item_type_list', $row);
865 $this->tmpl->parseTemplate('item_type_list', 'a');
871 * @param int $index 行番号(0~)
872 * @param array $fetchedRow フェッチ取得した行
873 * @param object $param 未使用
874 * @return bool true=処理続行の場合、false=処理終了の場合
876 function menuIdLoop($index, $fetchedRow, $param)
878 $value = $this->convertToDispString($fetchedRow['md_id']);
879 $name = $this->getDefaultLangString($fetchedRow['md_name']);
882 if ($value == $this->serialNo) $selected = 'selected';
885 'value' => $value, // メニュー項目ID
886 'name' => $this->convertToDispString($name), // メニュー項目名
887 'selected' => $selected // 選択中かどうか
889 $this->tmpl->addVars('menuid_list', $row);
890 $this->tmpl->parseTemplate('menuid_list', 'a');
896 * @param string $menuId メニューID
897 * @param int $parantId 親メニュー項目ID
898 * @param int $level 階層数
899 * @return string ツリーメニュータグ
901 function createTreeMenu($menuId, $parantId, $level = 0)
903 static $index = 0; // インデックス番号
906 if ($level >= self::MAX_MENU_TREE_LEVEL) return '';
909 if ($this->db->getChildMenuItems($menuId, $parantId, $rows)){
910 $itemCount = count($rows);
911 for ($i = 0; $i < $itemCount; $i++){
914 $name = $this->getDefaultLangString($row['md_name']);// デフォルト言語で名前を取得
918 if ($this->isMultiLang){ // 多言語対応の場合
919 $lang = $this->createLangImageList($row['md_name']);
922 // ##### ツリーメニュー作成 #####
923 if ($row['md_type'] == 0){ // リンク項目のとき
924 $treeHtml .= '<li id="' . self::TREE_ITEM_HEAD . $id . '"><a href="#">' . $this->convertToDispString($name) . '</a></li>' . M3_NL;
925 } else if ($row['md_type'] == 1){ // フォルダのとき
927 if (in_array($id, $this->parentIdArray)){ // メニュー階層パス上にある場合はフォルダを開く
928 $itemClass = 'jstree-open';
930 $this->parentNameArray[] = $name;
932 $itemClass = 'jstree-closed';
934 $treeHtml .= '<li id="' . self::TREE_ITEM_HEAD . $id . '" rel="folder" class="' . $itemClass . '"><a href="#">' . $this->convertToDispString($name) . '</a>' . M3_NL;
935 $treeHtml .= '<ul>' . M3_NL;
936 $treeHtml .= $this->createTreeMenu($menuId, $id, $level + 1);
937 $treeHtml .= '</ul>' . M3_NL;
938 $treeHtml .= '</li>' . M3_NL;
939 } else if ($row['md_type'] == 2){ // テキストのとき
940 $treeHtml .= '<li id="' . self::TREE_ITEM_HEAD . $id . '"><a href="#">' . $this->convertToDispString($name) . '</a></li>' . M3_NL;
941 } else if ($row['md_type'] == 3){ // セパレータのとき
942 $treeHtml .= '<li id="' . self::TREE_ITEM_HEAD . $id . '"><a href="#">' . '-----' . '</a></li>' . M3_NL;
946 if ($parantId != $this->parentId) continue;
950 switch ($row['md_type']){
952 $iconTitle = $this->_('Link'); // リンク
953 $iconUrl = $this->gEnv->getRootUrl() . self::FILE_ICON_FILE;
956 $iconTitle = $this->_('Folder'); // フォルダ
957 $iconUrl = $this->gEnv->getRootUrl() . self::FOLDER_ICON_FILE;
960 $iconTitle = $this->_('Text'); // テキスト
961 $iconUrl = $this->gEnv->getRootUrl() . self::FILE_ICON_FILE;
964 $iconTitle = $this->_('Separator'); // セパレータ
965 $iconUrl = $this->gEnv->getRootUrl() . self::FILE_ICON_FILE;
970 $iconTag = '<img src="' . $this->getUrl($iconUrl) . '" width="' . self::ICON_SIZE . '" height="' . self::ICON_SIZE . '" border="0" alt="' . $iconTitle . '" title="' . $iconTitle . '" />';
973 if ($row['md_visible']){
974 $visible = 'checked';
978 switch ($row['md_link_type']){
979 case 0: // 同ウィンドウで開くリンク
980 $linkString = $this->_('Self'); // 同
982 case 1: // 別ウィンドウで開くリンク
983 $linkString = $this->_('Other'); // 別
989 // リンクURLからコンテンツIDを取得
990 $linkUrl = $row['md_link_url'];
993 $pos = strpos($linkUrl, M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END);
994 if ($pos === false){ // 見つからない場合
997 list($path, $param) = explode("?", $linkUrl);
998 $params = explode("&", $param);
999 $count = count($params);
1000 for ($j = 0; $j < $count; $j++){
1001 list($key, $value) = explode('=', $params[$j]);
1002 if ($key == M3_REQUEST_PARAM_CONTENT_ID){
1003 $contentId = $value;
1009 $linkUrlStr = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, '...', $linkUrl); // 表示テキスト
1010 $linkUrl = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, $this->gEnv->getRootUrl(), $linkUrl); // マクロ展開
1011 $linkUrlStr = '<a href="#" onclick="previewInOtherWindow(\'' . $linkUrl . '\');">' . $this->convertToDispString($linkUrlStr) . '</a>';
1014 $enableContentLink = '';
1015 if (empty($contentId)) $enableContentLink = 'disabled';
1018 'index' => $index, // 行番号
1019 'serial' => $this->convertToDispString($serial), // シリアル番号
1020 'id' => $this->convertToDispString($id), // ID
1021 'name' => $this->convertToDispString($name), // 名前
1022 'lang' => $lang, // 言語
1023 'item_type' => $iconTag, // メニュー項目タイプアイコン
1024 'link_type' => $linkString, // リンクタイプ
1025 'link_str' => $linkUrlStr, // リンクURL
1026 'content_id' => $contentId, // コンテンツID
1027 'enable_content' => $enableContentLink, // コンテンツの編集ボタンの有効状態
1028 'visible' => $visible, // メニュー項目表示制御
1029 'label_edit_content' => $this->_('Edit Content') // コンテンツを編集
1032 if ($this->isMultiLang){ // 多言語対応のとき
1033 $this->tmpl->addVars('itemlist2', $itemRow);
1034 $this->tmpl->parseTemplate('itemlist2', 'a');
1036 $this->tmpl->addVars('itemlist', $itemRow);
1037 $this->tmpl->parseTemplate('itemlist', 'a');
1040 $index++; // インデックス番号更新
1041 $this->isExistsMenuItem = true; // メニュー項目が存在するかどうか
1044 $this->serialArray[] = $serial;
1052 * @param string $menuId メニューID
1053 * @param int $parantId 親メニュー項目ID
1054 * @param int $level 階層数
1055 * @return array メニュー項目IDの配列
1057 function getPath($menuId, $parantId, $level = 0)
1059 static $pathArray = array();
1062 if ($level >= self::MAX_MENU_TREE_LEVEL) return $pathArray;
1064 if (empty($parantId)) return $pathArray; // メニューIDが0のときは終了
1067 $pathArray[] = $parantId;
1070 $ret = $this->db->getMenuItem($parantId, $row);
1073 $this->getPath($menuId, $row['md_parent_id'], $level + 1);
1075 if ($level == 0) $pathArray = array_reverse($pathArray); // パスを反転
1084 * @param string $src 多言語対応文字列
1085 * @return string 言語アイコンタグ
1087 function createLangImageList($src)
1090 $langArray = $this->unserializeLangArray($src);
1091 $keys = array_keys($langArray);
1093 for ($i = 0; $i < count($this->availableLangRows); $i++){
1094 $langId = $this->availableLangRows[$i]['ln_id'];
1095 if (in_array($langId, $keys)) $imageTag .= $this->createLangImage($langId);
1102 * @param string $id 言語ID
1103 * @return string 言語アイコンタグ
1105 function createLangImage($id)
1107 $langInfo = $this->availableLangArray[$id];
1108 if (!isset($langInfo)) return '';
1110 if ($this->gEnv->getCurrentLanguage() == 'ja'){ // 日本語の場合
1111 $langName = $langInfo['ln_name'];
1113 $langName = $langInfo['ln_name_en'];
1116 $iconTitle = $langName;
1117 $iconUrl = $this->gEnv->getRootUrl() . self::LANG_ICON_PATH . $langInfo['ln_image_filename']; // 画像ファイル
1118 $iconTag = '<img src="' . $this->getUrl($iconUrl) . '" border="0" alt="' . $iconTitle . '" title="' . $iconTitle . '" />';
1119 $imageTag .= $iconTag;
1125 * @param array $nameArray 多言語対応文字列
1128 function createInputLangText($nameArray)
1130 for ($i = 0; $i < count($this->availableLangRows); $i++){
1131 $langId = $this->availableLangRows[$i]['ln_id'];
1132 if ($langId == $this->gEnv->getDefaultLanguage()) continue; // デフォルト言語は除く
1133 $langImage = $this->createLangImage($langId);
1135 $value = $nameArray[$langId];
1137 'id' => $langId, // 言語ID
1138 'value' => $this->convertToDispString($value), // 入力値
1139 'lang' => $langImage // 言語画像
1141 $this->tmpl->addVars('input_lang', $row);
1142 $this->tmpl->parseTemplate('input_lang', 'a');