BxBaseStudioNavigationItems.php 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup UnaView UNA Studio Representation classes
  7. * @ingroup UnaStudio
  8. * @{
  9. */
  10. bx_import('BxDolStudioUtils');
  11. class BxBaseStudioNavigationItems extends BxDolStudioNavigationItems
  12. {
  13. protected $sUrlPage;
  14. protected $sUrlViewItems;
  15. function __construct($aOptions, $oTemplate = false)
  16. {
  17. parent::__construct($aOptions, $oTemplate);
  18. $this->_aOptions['actions_single']['edit']['attr']['title'] = _t('_adm_nav_btn_items_edit');
  19. $this->_aOptions['actions_single']['delete']['attr']['title'] = _t('_adm_nav_btn_items_delete');
  20. $this->sUrlPage = BX_DOL_URL_STUDIO . 'builder_menu.php?page=items';
  21. $this->sUrlViewItems = $this->sUrlPage . '&module=%s&set=%s';
  22. }
  23. public function performActionImport()
  24. {
  25. $oGrid = BxDolGrid::getObjectInstance('sys_studio_nav_import');
  26. if(!$oGrid)
  27. return '';
  28. $sContent = BxTemplStudioFunctions::getInstance()->popupBox('adm-nav-item-import-popup', _t('_adm_nav_txt_items_import_popup'), $this->_oTemplate->parseHtmlByName('nav_import_item.html', array(
  29. 'grid' => $oGrid->getCode()
  30. )));
  31. echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false))));
  32. }
  33. public function performActionAdd()
  34. {
  35. $sAction = 'add';
  36. $oForm = $this->_getFormObject($sAction);
  37. $oForm->initChecker();
  38. if($oForm->isSubmittedAndValid()) {
  39. if(!empty($_FILES['icon_image']['tmp_name'])) {
  40. $oStorage = BxDolStorage::getObjectInstance(BX_DOL_STORAGE_OBJ_IMAGES);
  41. $mixedIcon = $oStorage->storeFileFromForm($_FILES['icon_image'], false, 0);
  42. if($mixedIcon === false) {
  43. echoJson(array('msg' => _t('_adm_nav_err_items_icon_image') . $oStorage->getErrorString()));
  44. return;
  45. }
  46. $oStorage->afterUploadCleanup($mixedIcon, 0);
  47. BxDolForm::setSubmittedValue('icon', $mixedIcon, $oForm->aFormAttrs['method']);
  48. }
  49. $oPermalinks = BxDolPermalinks::getInstance();
  50. $sLink = $oForm->getCleanValue('link');
  51. $sLink = $oPermalinks->unpermalink($sLink);
  52. BxDolForm::setSubmittedValue('link', $sLink, $oForm->aFormAttrs['method']);
  53. $sName = $oPermalinks->getPageNameFromLink($sLink);
  54. if($sName == '') {
  55. $sLanguage = BxDolStudioLanguagesUtils::getInstance()->getCurrentLangName(false);
  56. $sName = BxDolForm::getSubmittedValue('title-' . $sLanguage, $oForm->aFormAttrs['method']);
  57. if(empty($sName))
  58. $sName = BxDolForm::getSubmittedValue('title_system-' . $sLanguage, $oForm->aFormAttrs['method']);
  59. $sName = uriGenerate($sName, 'sys_menu_items', 'name', ['empty' => 'item']);
  60. }
  61. bx_import('BxDolStudioUtils');
  62. $iId = (int)$oForm->insert(array('module' => BX_DOL_STUDIO_MODULE_CUSTOM, 'name' => $sName, 'active' => 1, 'order' => $this->oDb->getItemOrderMax($this->sSet) + 1));
  63. if($iId != 0) {
  64. $this->onMenuItemsChanged();
  65. $aRes = array('grid' => $this->getCode(false), 'blink' => $iId);
  66. } else {
  67. $aRes = array('msg' => _t('_adm_nav_err_items_create'));
  68. }
  69. echoJson($aRes);
  70. }
  71. else {
  72. $sContent = BxTemplStudioFunctions::getInstance()->popupBox('adm-nav-item-create-popup', _t('_adm_nav_txt_items_create_popup'), $this->_oTemplate->parseHtmlByName('nav_add_item.html', array(
  73. 'form_id' => $oForm->aFormAttrs['id'],
  74. 'form' => $oForm->getCode(true),
  75. 'object' => $this->_sObject,
  76. 'action' => $sAction
  77. )));
  78. echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false))));
  79. }
  80. }
  81. public function performActionEdit($bUpdateGrid = false)
  82. {
  83. $sAction = 'edit';
  84. $aItem = $this->_getItem('getItems');
  85. if($aItem === false) {
  86. echoJson(array());
  87. exit;
  88. }
  89. $oForm = $this->_getFormObject($sAction, $aItem);
  90. $oForm->initChecker();
  91. if($oForm->isSubmittedAndValid()) {
  92. $bIconImageCur = is_numeric($aItem['icon']) && (int)$aItem['icon'] != 0;
  93. $bIconImageNew = !empty($_FILES['icon_image']['tmp_name']);
  94. $sIconFont = $oForm->getCleanValue('icon');
  95. $bIconFont = !empty($sIconFont);
  96. if($bIconImageCur && ($bIconImageNew || $bIconFont)) {
  97. $oStorage = BxDolStorage::getObjectInstance(BX_DOL_STORAGE_OBJ_IMAGES);
  98. if(!$oStorage->deleteFile((int)$aItem['icon'], 0)) {
  99. echoJson(array('msg' => _t('_adm_nav_err_items_icon_image_remove')));
  100. return;
  101. }
  102. }
  103. $sIcon = $sIconFont;
  104. if($bIconImageNew) {
  105. $oStorage = BxDolStorage::getObjectInstance(BX_DOL_STORAGE_OBJ_IMAGES);
  106. $sIcon = $oStorage->storeFileFromForm($_FILES['icon_image'], false, 0);
  107. if($sIcon === false) {
  108. echoJson(array('msg' => _t('_adm_nav_err_items_icon_image') . $oStorage->getErrorString()));
  109. return;
  110. }
  111. $oStorage->afterUploadCleanup($sIcon, 0);
  112. } else if($bIconImageCur && !$bIconFont)
  113. $sIcon = $aItem['icon'];
  114. BxDolForm::setSubmittedValue('icon', $sIcon, $oForm->aFormAttrs['method']);
  115. $sLink = $oForm->getCleanValue('link');
  116. $sLink = BxDolPermalinks::getInstance()->unpermalink($sLink);
  117. BxDolForm::setSubmittedValue('link', $sLink, $oForm->aFormAttrs['method']);
  118. $sSubmenu = $oForm->getCleanValue('submenu_object');
  119. if(empty($sSubmenu))
  120. BxDolForm::setSubmittedValue('submenu_popup', 0, $oForm->aFormAttrs['method']);
  121. $sTarget = $oForm->getCleanValue('target');
  122. if($sTarget === false && !in_array($aItem['target'], array('', '_blank')))
  123. unset($oForm->aInputs['target']);
  124. if($oForm->update($aItem['id']) !== false) {
  125. $this->onMenuItemsChanged();
  126. $aRes = array('grid' => $this->getCode(false), 'blink' => $aItem['id']);
  127. } else {
  128. $aRes = array('msg' => _t('_adm_nav_err_items_edit'));
  129. }
  130. echoJson($aRes);
  131. }
  132. else {
  133. $sTitle = _t($aItem['title']);
  134. $sContent = BxTemplStudioFunctions::getInstance()->popupBox('adm-nav-item-edit-popup', _t('_adm_nav_txt_items_edit_popup', ($sTitle != "" ? '"' . $sTitle . '"' : '')), $this->_oTemplate->parseHtmlByName('nav_add_item.html', array(
  135. 'form_id' => $oForm->aFormAttrs['id'],
  136. 'form' => $oForm->getCode(true),
  137. 'object' => $this->_sObject,
  138. 'action' => $sAction
  139. )));
  140. $aRes = array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false)));
  141. if($bUpdateGrid)
  142. $aRes = array_merge($aRes, array('grid' => $this->getCode(false), 'blink' => $aItem['id']));
  143. echoJson($aRes);
  144. }
  145. }
  146. public function performActionDelete()
  147. {
  148. $iAffected = 0;
  149. $aIds = bx_get('ids');
  150. if(!$aIds || !is_array($aIds))
  151. return echoJson([]);
  152. $aIdsAffected = [];
  153. foreach($aIds as $iId) {
  154. $aItem = [];
  155. $iItem = $this->oDb->getItems(['type' => 'by_id', 'value' => $iId], $aItem);
  156. if($iItem != 1 || empty($aItem) || !$this->_isDeletable($aItem))
  157. continue;
  158. if(!$this->deleteById($iId))
  159. continue;
  160. $aIdsAffected[] = $iId;
  161. $iAffected++;
  162. }
  163. if ($iAffected)
  164. $this->onMenuItemsChanged();
  165. echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t('_adm_nav_err_items_delete')));
  166. }
  167. public function performActionReorder()
  168. {
  169. $mixed = parent::performActionReorder();
  170. $this->onMenuItemsChanged();
  171. return $mixed;
  172. }
  173. public function performActionShowTo()
  174. {
  175. $sAction = 'show_to';
  176. $aItem = $this->_getItem('getItems');
  177. if($aItem === false) {
  178. echoJson(array());
  179. exit;
  180. }
  181. bx_import('BxDolStudioUtils');
  182. $aForm = array(
  183. 'form_attrs' => array(
  184. 'id' => 'adm-nav-item-show-to',
  185. 'action' => BX_DOL_URL_ROOT . 'grid.php?o=' . $this->_sObject . '&a=' . $sAction . '&set=' . $this->sSet,
  186. 'method' => 'post'
  187. ),
  188. 'params' => array (
  189. 'db' => array(
  190. 'table' => 'sys_menu_items',
  191. 'key' => 'id',
  192. 'uri' => '',
  193. 'uri_title' => '',
  194. 'submit_name' => 'do_submit'
  195. ),
  196. ),
  197. 'inputs' => array (
  198. 'id' => array(
  199. 'type' => 'hidden',
  200. 'name' => 'id',
  201. 'value' => $aItem['id'],
  202. 'db' => array (
  203. 'pass' => 'Int',
  204. ),
  205. ),
  206. 'visible_for' => array(
  207. 'type' => 'select',
  208. 'name' => 'visible_for',
  209. 'caption' => _t('_adm_nav_txt_items_visible_for'),
  210. 'info' => '',
  211. 'value' => $aItem['visible_for_levels'] == BX_DOL_INT_MAX ? BX_DOL_STUDIO_VISIBLE_ALL : BX_DOL_STUDIO_VISIBLE_SELECTED,
  212. 'values' => array(
  213. array('key' => BX_DOL_STUDIO_VISIBLE_ALL, 'value' => _t('_adm_nav_txt_items_visible_for_all')),
  214. array('key' => BX_DOL_STUDIO_VISIBLE_SELECTED, 'value' => _t('_adm_nav_txt_items_visible_for_selected')),
  215. ),
  216. 'required' => '0',
  217. 'attrs' => array(
  218. 'onchange' => $this->getJsObject() . '.onChangeVisibleFor(this)'
  219. ),
  220. 'db' => array (
  221. 'pass' => 'Xss',
  222. )
  223. ),
  224. 'visible_for_levels' => array(
  225. 'type' => 'checkbox_set',
  226. 'name' => 'visible_for_levels',
  227. 'caption' => _t('_adm_nav_txt_items_visible_for_levels'),
  228. 'info' => _t('_adm_nav_dsc_items_visible_for_levels'),
  229. 'value' => '',
  230. 'values' => array(),
  231. 'tr_attrs' => array(
  232. 'style' => $aItem['visible_for_levels'] == BX_DOL_INT_MAX ? 'display:none' : ''
  233. ),
  234. 'db' => array (
  235. 'pass' => 'Int',
  236. ),
  237. ),
  238. 'controls' => array(
  239. 'name' => 'controls',
  240. 'type' => 'input_set',
  241. array(
  242. 'type' => 'submit',
  243. 'name' => 'do_submit',
  244. 'value' => _t('_adm_nav_btn_items_save'),
  245. ),
  246. array (
  247. 'type' => 'reset',
  248. 'name' => 'close',
  249. 'value' => _t('_adm_nav_btn_items_cancel'),
  250. 'attrs' => array(
  251. 'onclick' => "$('.bx-popup-applied:visible').dolPopupHide()",
  252. 'class' => 'bx-def-margin-sec-left',
  253. ),
  254. )
  255. )
  256. )
  257. );
  258. BxDolStudioUtils::getVisibilityValues($aItem['visible_for_levels'], $aForm['inputs']['visible_for_levels']['values'], $aForm['inputs']['visible_for_levels']['value']);
  259. $oForm = new BxTemplStudioFormView($aForm);
  260. $oForm->initChecker();
  261. if($oForm->isSubmittedAndValid()) {
  262. if($oForm->updateWithVisibility($aItem['id']) !== false) {
  263. $this->onMenuItemsChanged();
  264. $aRes = array('grid' => $this->getCode(false), 'blink' => $aItem['id']);
  265. } else {
  266. $aRes = array('msg' => _t('_adm_nav_err_items_show_to'));
  267. }
  268. echoJson($aRes);
  269. }
  270. else {
  271. $sContent = BxTemplStudioFunctions::getInstance()->popupBox('adm-nav-item-hide-from-popup', _t('_adm_nav_txt_items_show_to_popup', _t($aItem['title'])), $this->_oTemplate->parseHtmlByName('nav_add_item.html', array(
  272. 'form_id' => $aForm['form_attrs']['id'],
  273. 'form' => $oForm->getCode(true),
  274. 'object' => $this->_sObject,
  275. 'action' => $sAction
  276. )));
  277. echoJson(array('popup' => $sContent));
  278. }
  279. }
  280. public function performActionDeleteIcon()
  281. {
  282. $sAction = 'delete_icon';
  283. $aIds = bx_get('ids');
  284. if(empty($aIds[0])) {
  285. echoJson(array());
  286. exit;
  287. }
  288. $iId = (int)$aIds[0];
  289. $aItem = array();
  290. $iItem = $this->oDb->getItems(array('type' => 'by_id', 'value' => $iId), $aItem);
  291. if($iItem != 1 || empty($aItem)){
  292. echoJson(array());
  293. exit;
  294. }
  295. if(is_numeric($aItem['icon']) && (int)$aItem['icon'] != 0)
  296. if(!BxDolStorage::getObjectInstance(BX_DOL_STORAGE_OBJ_IMAGES)->deleteFile((int)$aItem['icon'], 0)) {
  297. echoJson(array());
  298. exit;
  299. }
  300. if($this->oDb->updateItem($aItem['id'], array('icon' => '')) !== false) {
  301. $this->onMenuItemsChanged();
  302. echoJson(array('grid' => $this->getCode(false), 'blink' => $iId, 'preview' => $this->_getIconPreview($aItem['id']), 'eval' => $this->getJsObject() . ".onDeleteIcon(oData)"));
  303. }
  304. }
  305. public function getJsObject()
  306. {
  307. return 'oBxDolStudioNavigationItems';
  308. }
  309. public function getSetsSelector($sModule = '')
  310. {
  311. $oForm = new BxTemplStudioFormView(array());
  312. $aInputSets = array(
  313. 'type' => 'select',
  314. 'name' => 'set',
  315. 'attrs' => array(
  316. 'id' => 'bx-grid-set-' . $this->_sObject,
  317. 'onChange' => 'javascript:' . $this->getJsObject() . '.onChangeSet()'
  318. ),
  319. 'value' => $this->sSet,
  320. 'values' => array()
  321. );
  322. $aSets = array();
  323. if(!empty($sModule))
  324. $this->oDb->getSets(array('type' => 'by_module', 'value' => $sModule), $aSets, false);
  325. else
  326. $aInputSets['attrs']['disabled'] = 'disabled';
  327. if(!empty($aSets)) {
  328. $aCounter = array();
  329. $this->oDb->getItems(array('type' => 'counter_by_sets'), $aCounter, false);
  330. foreach($aSets as $aSet)
  331. $aInputSets['values'][$aSet['name']] = _t($aSet['title']) . " (" . (isset($aCounter[$aSet['name']]) ? $aCounter[$aSet['name']] : "0") . ")";
  332. asort($aInputSets['values']);
  333. }
  334. $aInputSets['values'] = array_merge(array('' => _t('_adm_nav_txt_select_set')), $aInputSets['values']);
  335. return $oForm->genRow($aInputSets);
  336. }
  337. public function getCode($isDisplayHeader = true)
  338. {
  339. return $this->_oTemplate->parseHtmlByName('nav_items.html', array(
  340. 'content' => parent::getCode($isDisplayHeader),
  341. 'js_object' => $this->getJsObject(),
  342. 'page_url' => $this->sUrlPage,
  343. 'grid_object' => $this->_sObject,
  344. 'params_divider' => $this->sParamsDivider
  345. ));
  346. }
  347. protected function _addJsCss()
  348. {
  349. parent::_addJsCss();
  350. $this->_oTemplate->addJs(array('jquery.form.min.js', 'navigation_items.js', 'navigation_import.js'));
  351. $oForm = new BxTemplStudioFormView(array());
  352. $oForm->addCssJs();
  353. }
  354. protected function _getCellSwitcher ($mixedValue, $sKey, $aField, $aRow)
  355. {
  356. if(!$this->_isEditable($aRow))
  357. return parent::_getCellDefault('', $sKey, $aField, $aRow);
  358. return parent::_getCellSwitcher($mixedValue, $sKey, $aField, $aRow);
  359. }
  360. protected function _getCellIcon ($mixedValue, $sKey, $aField, $aRow)
  361. {
  362. $mixedValue = $this->_oTemplate->getIcon($mixedValue, array('class' => 'bx-item-icon'));
  363. return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
  364. }
  365. protected function _getCellTitleSystem ($mixedValue, $sKey, $aField, $aRow)
  366. {
  367. if(empty($mixedValue))
  368. $mixedValue = _t($aRow['title']);
  369. if((int)$aRow['active_api'] != 0)
  370. $mixedValue .= ' ' . $this->_oTemplate->parseImage($this->_oTemplate->getIconUrl('api.svg'), [
  371. 'class' => 'bx-std-api',
  372. 'title' => bx_html_attribute(_t('_adm_txt_active_api'))
  373. ]);
  374. return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
  375. }
  376. protected function _getCellLink ($mixedValue, $sKey, $aField, $aRow)
  377. {
  378. $aSubitems = array();
  379. $this->oDb->getItems(array('type' => 'by_parent_id', 'value' => $aRow['id']), $aSubitems, false);
  380. if(!empty($aSubitems) && is_array($aSubitems)) {
  381. $sPrefix = _t('_adm_nav_txt_items_gl_link_subitems');
  382. $aField['chars_limit'] -= strlen($sPrefix);
  383. $aTitles = array();
  384. foreach($aSubitems as $aSubitem)
  385. $aTitles[] = _t(!empty($aSubitem['title_system']) ? $aSubitem['title_system'] : $aSubitem['title']);
  386. $aValue = $this->_limitMaxLength(implode(', ', $aTitles), $sKey, $aField, $aRow, $this->_isDisplayPopupOnTextOverflow, false);
  387. $mixedValue = $sPrefix . ' ' . $aValue[0] . (isset($aValue[1]) ? $aValue[1] : '');
  388. }
  389. else if($aRow['submenu_object'] != "") {
  390. $aMenu = array();
  391. $this->oDb->getMenus(array('type' => 'by_object', 'value' => $aRow['submenu_object']), $aMenu, false);
  392. $sPrefix = _t('_adm_nav_txt_items_gl_link_menu');
  393. if(!empty($aMenu) && is_array($aMenu)) {
  394. $aField['chars_limit'] -= strlen($sPrefix);
  395. $aValue = $this->_limitMaxLength(_t($aMenu['title']), $sKey, $aField, $aRow, $this->_isDisplayPopupOnTextOverflow, false);
  396. $sLink = sprintf($this->sUrlViewItems, $aMenu['module'], $aMenu['set_name']);
  397. $mixedValue = $sPrefix . ' ' . $this->_oTemplate->parseLink($sLink, $aValue[0], array(
  398. 'title' => _t('_adm_nav_txt_manage_items')
  399. )) . (isset($aValue[1]) ? $aValue[1] : '');
  400. }
  401. else
  402. $mixedValue = $sPrefix . ' ' . _t('_undefined');
  403. }
  404. else if($aRow['submenu_object'] == "" && $aRow['onclick'] != "")
  405. $mixedValue = $this->_limitMaxLength(_t('_adm_nav_txt_items_gl_link_custom'), $sKey, $aField, $aRow, $this->_isDisplayPopupOnTextOverflow);
  406. else
  407. $mixedValue = $this->_limitMaxLength(BxDolPermalinks::getInstance()->permalink($aRow['link']), $sKey, $aField, $aRow, $this->_isDisplayPopupOnTextOverflow);
  408. return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
  409. }
  410. protected function _getCellModule($mixedValue, $sKey, $aField, $aRow)
  411. {
  412. $mixedValue = $this->_limitMaxLength($this->getModuleTitle($aRow['module']), $sKey, $aField, $aRow, $this->_isDisplayPopupOnTextOverflow);
  413. return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
  414. }
  415. protected function _getCellVisibleForLevels ($mixedValue, $sKey, $aField, $aRow)
  416. {
  417. if(!$this->_isEditable($aRow))
  418. return parent::_getCellDefault('', $sKey, $aField, $aRow);
  419. $mixedValue = $this->_oTemplate->parseLink('javascript:void(0)', BxDolStudioUtils::getVisibilityTitle($aRow['visible_for_levels']), array(
  420. 'title' => _t('_adm_nav_txt_manage_visibility'),
  421. 'bx_grid_action_single' => 'show_to',
  422. 'bx_grid_action_data' => $aRow['id']
  423. ));
  424. return parent::_getCellDefault ($mixedValue, $sKey, $aField, $aRow);
  425. }
  426. protected function _getActionImport ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
  427. {
  428. if($this->sSet == '')
  429. $isDisabled = true;
  430. return parent::_getActionDefault($sType, $sKey, $a, false, $isDisabled, $aRow);
  431. }
  432. protected function _getActionAdd ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
  433. {
  434. if($this->sSet == '')
  435. $isDisabled = true;
  436. return parent::_getActionDefault($sType, $sKey, $a, false, $isDisabled, $aRow);
  437. }
  438. protected function _getActionEdit ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
  439. {
  440. if($sType == 'single' && !$this->_isEditable($aRow))
  441. return '';
  442. return parent::_getActionDefault($sType, $sKey, $a, false, $isDisabled, $aRow);
  443. }
  444. protected function _getActionDelete ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
  445. {
  446. if ($sType == 'single' && !$this->_isDeletable($aRow))
  447. return '';
  448. return parent::_getActionDefault($sType, $sKey, $a, false, $isDisabled, $aRow);
  449. }
  450. protected function _getActionShowTo ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
  451. {
  452. return '';
  453. }
  454. protected function _getActionDeleteIcon ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
  455. {
  456. return '';
  457. }
  458. protected function _getActionsDisabledBehavior($aRow)
  459. {
  460. return false;
  461. }
  462. protected function _getFilterControls ()
  463. {
  464. parent::_getFilterControls();
  465. $sContent = $this->getModulesSelectOne('getItems') . $this->getSetsSelector($this->sModule);
  466. $oForm = new BxTemplStudioFormView(array());
  467. $aInputSearch = array(
  468. 'type' => 'text',
  469. 'name' => 'keyword',
  470. 'attrs' => array(
  471. 'id' => 'bx-grid-search-' . $this->_sObject,
  472. ),
  473. 'tr_attrs' => array(
  474. 'style' => 'display:none;'
  475. )
  476. );
  477. $sContent .= $oForm->genRow($aInputSearch);
  478. return $sContent;
  479. }
  480. protected function _getFormObject($sAction, $aItem = array())
  481. {
  482. bx_import('BxTemplStudioFormView');
  483. $aForm = array(
  484. 'form_attrs' => array(
  485. 'id' => 'adm-nav-item-',
  486. 'action' => BX_DOL_URL_ROOT . 'grid.php?o=' . $this->_sObject . '&a=' . $sAction . '&set=' . $this->sSet,
  487. 'method' => BX_DOL_STUDIO_METHOD_DEFAULT,
  488. 'enctype' => 'multipart/form-data',
  489. ),
  490. 'params' => array (
  491. 'db' => array(
  492. 'table' => 'sys_menu_items',
  493. 'key' => 'id',
  494. 'uri' => '',
  495. 'uri_title' => '',
  496. 'submit_name' => 'do_submit'
  497. ),
  498. ),
  499. 'inputs' => array (
  500. 'id' => array(
  501. 'type' => 'hidden',
  502. 'name' => 'id',
  503. 'value' => isset($aItem['id']) ? (int)$aItem['id'] : 0,
  504. 'db' => array (
  505. 'pass' => 'Int',
  506. ),
  507. ),
  508. 'set_name' => array(
  509. 'type' => 'hidden',
  510. 'name' => 'set_name',
  511. 'value' => $this->sSet,
  512. 'db' => array (
  513. 'pass' => 'Xss',
  514. ),
  515. ),
  516. 'title_system' => array(
  517. 'type' => 'text_translatable',
  518. 'name' => 'title_system',
  519. 'caption' => _t('_adm_nav_txt_items_title_system'),
  520. 'info' => _t('_adm_nav_dsc_items_title_system'),
  521. 'value' => isset($aItem['title_system']) ? $aItem['title_system'] : '_adm_nav_txt_item',
  522. 'required' => '0',
  523. 'db' => array (
  524. 'pass' => 'Xss',
  525. ),
  526. ),
  527. 'title' => array(
  528. 'type' => 'text_translatable',
  529. 'name' => 'title',
  530. 'caption' => _t('_adm_nav_txt_items_title'),
  531. 'info' => _t('_adm_nav_dsc_items_title'),
  532. 'value' => isset($aItem['title']) ? $aItem['title'] : '_adm_nav_txt_item',
  533. 'required' => '0',
  534. 'db' => array (
  535. 'pass' => 'Xss',
  536. ),
  537. ),
  538. 'title_attr' => array(
  539. 'type' => 'text_translatable',
  540. 'name' => 'title_attr',
  541. 'caption' => _t('_adm_nav_txt_items_title_attr'),
  542. 'info' => _t('_adm_nav_dsc_items_title_attr'),
  543. 'value' => isset($aItem['title_attr']) ? $aItem['title_attr'] : '_adm_nav_txt_item',
  544. 'required' => '0',
  545. 'db' => array (
  546. 'pass' => 'Xss',
  547. ),
  548. ),
  549. 'info' => array(
  550. 'type' => 'text_translatable',
  551. 'name' => 'info',
  552. 'caption' => _t('_adm_nav_txt_items_info'),
  553. 'info' => _t('_adm_nav_dsc_items_info'),
  554. 'value' => isset($aItem['info']) ? $aItem['info'] : '_adm_nav_txt_item',
  555. 'required' => '0',
  556. 'db' => array (
  557. 'pass' => 'Xss',
  558. ),
  559. ),
  560. 'parent_id' => array(
  561. 'type' => 'select',
  562. 'name' => 'parent_id',
  563. 'caption' => _t('_adm_nav_txt_items_parent_id'),
  564. 'info' => _t('_adm_nav_dsc_items_parent_id'),
  565. 'value' => isset($aItem['parent_id']) ? $aItem['parent_id'] : '',
  566. 'values' => array(
  567. 0 => _t('_adm_nav_txt_items_parent_id_empty')
  568. ),
  569. 'required' => '0',
  570. 'attrs' => array(),
  571. 'db' => array (
  572. 'pass' => 'Int',
  573. ),
  574. ),
  575. 'submenu_object' => array(
  576. 'type' => 'select',
  577. 'name' => 'submenu_object',
  578. 'caption' => _t('_adm_nav_txt_items_submenu'),
  579. 'info' => _t('_adm_nav_dsc_items_submenu'),
  580. 'value' => isset($aItem['submenu_object']) ? $aItem['submenu_object'] : '',
  581. 'values' => array(),
  582. 'required' => '0',
  583. 'attrs' => array(
  584. 'onChange' => 'javascript:' . $this->getJsObject() . '.onChangeSubmenu(this)'
  585. ),
  586. 'db' => array (
  587. 'pass' => 'Xss',
  588. ),
  589. ),
  590. 'submenu_popup' => array(
  591. 'type' => 'switcher',
  592. 'name' => 'submenu_popup',
  593. 'caption' => _t('_adm_nav_txt_items_submenu_popup'),
  594. 'info' => '',
  595. 'value' => '1',
  596. 'checked' => isset($aItem['submenu_popup']) && $aItem['submenu_popup'] == '1',
  597. 'attrs' => array(
  598. 'onChange' => 'javascript:' . $this->getJsObject() . '.onChangeSubmenu(this)'
  599. ),
  600. 'db' => array (
  601. 'pass' => 'Int',
  602. )
  603. ),
  604. 'link' => array(
  605. 'type' => 'text',
  606. 'name' => 'link',
  607. 'caption' => _t('_adm_nav_txt_items_link'),
  608. 'info' => _t('_adm_nav_dsc_items_link'),
  609. 'value' => isset($aItem['link']) ? $aItem['link'] : '',
  610. 'required' => '0',
  611. 'db' => array (
  612. 'pass' => 'Xss',
  613. ),
  614. 'checker' => array (
  615. 'func' => '',
  616. 'params' => array(),
  617. 'error' => _t('_adm_nav_err_items_link'),
  618. ),
  619. ),
  620. 'target' => array(
  621. 'type' => 'select',
  622. 'name' => 'target',
  623. 'caption' => _t('_adm_nav_txt_items_target'),
  624. 'info' => _t('_adm_nav_dsc_items_target'),
  625. 'value' => isset($aItem['target']) ? $aItem['target'] : '_self',
  626. 'values' => array(
  627. array('key' => '', 'value' => _t('_adm_nav_txt_items_target_self')),
  628. array('key' => '_blank', 'value' => _t('_adm_nav_txt_items_target_blank'))
  629. ),
  630. 'required' => '0',
  631. 'db' => array (
  632. 'pass' => 'Xss',
  633. )
  634. ),
  635. 'onclick' => array(
  636. 'type' => 'text',
  637. 'name' => 'onclick',
  638. 'caption' => _t('_adm_nav_txt_items_onclick'),
  639. 'info' => _t('_adm_nav_dsc_items_onclick'),
  640. 'value' => isset($aItem['onclick']) ? $aItem['onclick'] : '',
  641. 'required' => '0',
  642. 'db' => array (
  643. 'pass' => 'Xss',
  644. ),
  645. 'checker' => array (
  646. 'func' => '',
  647. 'params' => array(),
  648. 'error' => _t('_adm_nav_err_items_onclick'),
  649. ),
  650. ),
  651. 'area_label' => array(
  652. 'type' => 'text_translatable',
  653. 'name' => 'area_label',
  654. 'caption' => _t('_adm_nav_txt_items_area_label'),
  655. 'info' => _t('_adm_nav_dsc_items_area_label'),
  656. 'value' => isset($aItem['area_label']) ? $aItem['area_label'] : '_adm_nav_txt_item',
  657. 'required' => '0',
  658. 'db' => array (
  659. 'pass' => 'Xss',
  660. ),
  661. ),
  662. 'hidden_on' => array(
  663. 'type' => 'select_multiple',
  664. 'name' => 'hidden_on',
  665. 'caption' => _t('_adm_nav_txt_block_hidden_on'),
  666. 'info' => '',
  667. 'value' => isset($aItem['hidden_on']) ? (int)$aItem['hidden_on'] : '',
  668. 'values' => array(
  669. BX_DB_HIDDEN_PHONE => _t('_adm_nav_txt_block_hidden_on_phone'),
  670. BX_DB_HIDDEN_TABLET => _t('_adm_nav_txt_block_hidden_on_tablet'),
  671. BX_DB_HIDDEN_DESKTOP => _t('_adm_nav_txt_block_hidden_on_desktop'),
  672. BX_DB_HIDDEN_MOBILE => _t('_adm_nav_txt_block_hidden_on_mobile')
  673. ),
  674. 'db' => array (
  675. 'pass' => 'Set',
  676. )
  677. ),
  678. 'hidden_on_pt' => array(
  679. 'type' => 'select_multiple',
  680. 'name' => 'hidden_on_pt',
  681. 'caption' => _t('_adm_nav_txt_block_hidden_on_pt'),
  682. 'info' => '',
  683. 'value' => isset($aItem['hidden_on_pt']) ? (int)$aItem['hidden_on_pt'] : '',
  684. 'values' => array(),
  685. 'db' => array (
  686. 'pass' => 'Set',
  687. )
  688. ),
  689. 'hidden_on_col' => array(
  690. 'type' => 'select_multiple',
  691. 'name' => 'hidden_on_col',
  692. 'caption' => _t('_adm_nav_txt_block_hidden_on_col'),
  693. 'info' => '',
  694. 'value' => isset($aItem['hidden_on_col']) ? (int)$aItem['hidden_on_col'] : '',
  695. 'values' => array(),
  696. 'db' => array (
  697. 'pass' => 'Set',
  698. )
  699. ),
  700. 'icon' => array(
  701. 'type' => 'textarea',
  702. 'name' => 'icon',
  703. 'caption' => _t('_adm_nav_txt_items_icon'),
  704. 'info' => _t('_adm_nav_dsc_items_icon'),
  705. 'value' => '',
  706. 'code' => 1,
  707. 'required' => '0',
  708. 'db' => array (
  709. 'pass' => 'Xss',
  710. ),
  711. 'checker' => array (
  712. 'func' => '',
  713. 'params' => array(),
  714. 'error' => _t('_adm_nav_err_items_icon'),
  715. ),
  716. 'attrs' => array('class' => 'bx-form-input-textarea-small'),
  717. ),
  718. 'icon_image' => array(
  719. 'type' => 'file',
  720. 'name' => 'icon_image',
  721. 'caption' => _t('_adm_nav_txt_items_icon_image'),
  722. 'info' => _t('_adm_nav_dsc_items_icon_image'),
  723. 'value' => '',
  724. 'checker' => array (
  725. 'func' => '',
  726. 'params' => '',
  727. 'error' => _t('_adm_nav_err_items_icon_image'),
  728. ),
  729. ),
  730. 'icon_preview' => array(
  731. 'type' => 'custom',
  732. 'name' => 'icon_preview',
  733. 'caption' => _t('_adm_nav_txt_items_icon_image_old'),
  734. 'content' => ''
  735. ),
  736. 'icon_only' => array(
  737. 'type' => 'switcher',
  738. 'name' => 'icon_only',
  739. 'caption' => _t('_adm_nav_txt_items_icon_only'),
  740. 'info' => '',
  741. 'value' => '1',
  742. 'checked' => isset($aItem['icon_only']) && (int)$aItem['icon_only'] == 1,
  743. 'db' => array (
  744. 'pass' => 'Int',
  745. )
  746. ),
  747. 'primary' => array(
  748. 'type' => 'switcher',
  749. 'name' => 'primary',
  750. 'caption' => _t('_adm_nav_txt_items_primary'),
  751. 'info' => '',
  752. 'value' => '1',
  753. 'checked' => isset($aItem['primary']) && (int)$aItem['primary'] == 1,
  754. 'db' => array (
  755. 'pass' => 'Int',
  756. )
  757. ),
  758. 'collapsed' => array(
  759. 'type' => 'switcher',
  760. 'name' => 'collapsed',
  761. 'caption' => _t('_adm_nav_txt_items_collapsed'),
  762. 'info' => '',
  763. 'value' => '1',
  764. 'checked' => isset($aItem['collapsed']) && (int)$aItem['collapsed'] == 1,
  765. 'db' => array (
  766. 'pass' => 'Int',
  767. )
  768. ),
  769. 'persistent' => array(
  770. 'type' => 'switcher',
  771. 'name' => 'persistent',
  772. 'caption' => _t('_adm_nav_txt_items_persistent'),
  773. 'info' => '',
  774. 'value' => '1',
  775. 'checked' => isset($aItem['persistent']) && (int)$aItem['persistent'] == 1,
  776. 'db' => array (
  777. 'pass' => 'Int',
  778. )
  779. ),
  780. 'active_api' => array(
  781. 'type' => 'switcher',
  782. 'name' => 'active_api',
  783. 'caption' => _t('_adm_nav_txt_items_active_api'),
  784. 'info' => '',
  785. 'value' => '1',
  786. 'checked' => isset($aItem['active_api']) && (int)$aItem['active_api'] == 1,
  787. 'db' => array (
  788. 'pass' => 'Int',
  789. )
  790. ),
  791. 'controls' => array(
  792. 'name' => 'controls',
  793. 'type' => 'input_set',
  794. array(
  795. 'type' => 'submit',
  796. 'name' => 'do_submit',
  797. 'value' => _t('_adm_nav_btn_items_add'),
  798. ),
  799. array (
  800. 'type' => 'reset',
  801. 'name' => 'close',
  802. 'value' => _t('_adm_nav_btn_items_cancel'),
  803. 'attrs' => array(
  804. 'onclick' => "$('.bx-popup-applied:visible').dolPopupHide()",
  805. 'class' => 'bx-def-margin-sec-left',
  806. ),
  807. )
  808. )
  809. )
  810. );
  811. $aSetItems = array();
  812. $this->oDb->getItems(array('type' => 'by_set_name', 'value' => $this->sSet), $aSetItems, false);
  813. foreach($aSetItems as $aSetItem)
  814. $aForm['inputs']['parent_id']['values'][$aSetItem['id']] = _t(!empty($aSetItem['title_system']) ? $aSetItem['title_system'] : $aSetItem['title']);
  815. $aMenus = array();
  816. $this->oDb->getMenus(array('type' => 'all'), $aMenus, false);
  817. foreach($aMenus as $aMenu)
  818. $aForm['inputs']['submenu_object']['values'][$aMenu['object']] = _t($aMenu['title']);
  819. asort($aForm['inputs']['submenu_object']['values']);
  820. $aForm['inputs']['submenu_object']['values'] = array_merge(array('' => _t('_adm_nav_txt_items_submenu_empty')), $aForm['inputs']['submenu_object']['values']);
  821. $aPageTypes = BxDolPageQuery::getPageTypes();
  822. foreach($aPageTypes as $aPageType) {
  823. $iPageType = (int)$aPageType['id'];
  824. if($iPageType == 1)
  825. continue;
  826. $aForm['inputs']['hidden_on_pt']['values'][$iPageType - 1] = _t($aPageType['title']);
  827. }
  828. $aForm['inputs']['hidden_on_col']['values'][1] = _t('_adm_nav_txt_block_hidden_on_col_thin');
  829. $aForm['inputs']['hidden_on_col']['values'][2] = _t('_adm_nav_txt_block_hidden_on_col_half');
  830. $aForm['inputs']['hidden_on_col']['values'][3] = _t('_adm_nav_txt_block_hidden_on_col_wide');
  831. $aForm['inputs']['hidden_on_col']['values'][4] = _t('_adm_nav_txt_block_hidden_on_col_full');
  832. switch($sAction) {
  833. case 'add':
  834. unset($aForm['inputs']['id']);
  835. unset($aForm['inputs']['icon_preview']);
  836. $aForm['form_attrs']['id'] .= 'create';
  837. break;
  838. case 'edit':
  839. unset($aForm['inputs']['set_name']);
  840. $aForm['form_attrs']['id'] .= 'edit';
  841. $aForm['inputs']['icon_image']['caption'] = _t('_adm_nav_txt_items_icon_image_new');
  842. $aForm['inputs']['controls'][0]['value'] = _t('_adm_nav_btn_items_save');
  843. $bSubmenu = !empty($aItem['submenu_object']);
  844. if($bSubmenu !== true)
  845. $aForm['inputs']['submenu_popup']['tr_attrs']['style'] = 'display:none;';
  846. if(!$bSubmenu && ($aItem['onclick'] != "" || !in_array($aItem['target'], array('', '_blank')))) {
  847. $aForm['inputs']['submenu_object']['tr_attrs']['style'] = 'display:none;';
  848. $aForm['inputs']['link']['tr_attrs']['style'] = 'display:none;';
  849. $aForm['inputs']['target']['tr_attrs']['style'] = 'display:none;';
  850. }
  851. $sIconImage = $sIconFont = "";
  852. if(!empty($aItem['icon'])) {
  853. if(is_numeric($aItem['icon']) && (int)$aItem['icon'] != 0) {
  854. $oStorage = BxDolStorage::getObjectInstance(BX_DOL_STORAGE_OBJ_IMAGES);
  855. $sIconImage = $oStorage->getFileUrlById((int)$aItem['icon']);
  856. }
  857. else {
  858. $sIconFont = $aItem['icon'];
  859. $aForm['inputs']['icon']['value'] = $sIconFont;
  860. }
  861. }
  862. $aForm['inputs']['icon_preview']['content'] = $this->_getIconPreview($aItem['id'], $sIconImage, $sIconFont);
  863. break;
  864. }
  865. return new BxTemplStudioFormView($aForm);
  866. }
  867. protected function _getIconPreview($iId, $sIconImage = '', $sIcon = '')
  868. {
  869. $bIconImage = !empty($sIconImage);
  870. $aIcons = BxTemplFunctions::getInstanceWithTemplate($this->_oTemplate)->getIcon($sIcon);
  871. $sIconHtml = $aIcons[2] . $aIcons[3] . $aIcons[4];
  872. $bIconHtml = !empty($sIconHtml) && !$bIconImage;
  873. return $this->_oTemplate->parseHtmlByName('item_icon_preview.html', array(
  874. 'id' => $iId,
  875. 'bx_if:show_icon_empty' => array(
  876. 'condition' => !$bIconImage && !$bIconHtml,
  877. 'content' => array()
  878. ),
  879. 'bx_if:show_icon_image' => array(
  880. 'condition' => $bIconImage,
  881. 'content' => array(
  882. 'js_object' => $this->getJsObject(),
  883. 'url' => $sIconImage,
  884. 'id' => $iId
  885. )
  886. ),
  887. 'bx_if:show_icon_html' => array(
  888. 'condition' => $bIconHtml,
  889. 'content' => array(
  890. 'icon' => $sIconHtml
  891. )
  892. )
  893. ));
  894. }
  895. protected function _isEditable(&$aRow)
  896. {
  897. return (int)$aRow['editable'] != 0;
  898. }
  899. protected function _isDeletable(&$aRow)
  900. {
  901. return $aRow['module'] != BX_DOL_STUDIO_MODULE_SYSTEM;
  902. }
  903. protected function onMenuItemsChanged()
  904. {
  905. bx_alert('system', 'menu_items_changed', 0, 0, array(
  906. 'set' => $this->sSet
  907. ));
  908. // clear all menus cache related to the current set
  909. $aMenus = [];
  910. $this->oDb->getMenus(array('type' => 'by_set_name', 'value' => $this->sSet), $aMenus, false);
  911. foreach($aMenus as $aMenu) {
  912. bx_content_cache_del_by_prefix('menu_' . $aMenu['object']);
  913. }
  914. }
  915. }
  916. /** @} */