menu.php 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213
  1. <?php
  2. /*
  3. FusionPBX
  4. Version: MPL 1.1
  5. The contents of this file are subject to the Mozilla Public License Version
  6. 1.1 (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.mozilla.org/MPL/
  9. Software distributed under the License is distributed on an "AS IS" basis,
  10. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. for the specific language governing rights and limitations under the
  12. License.
  13. The Original Code is FusionPBX
  14. The Initial Developer of the Original Code is
  15. Mark J Crane <[email protected]>
  16. Copyright (C) 2010 - 2023
  17. All Rights Reserved.
  18. Contributor(s):
  19. Mark J Crane <[email protected]>
  20. */
  21. /**
  22. * menu class
  23. *
  24. * @method null delete
  25. * @method null toggle
  26. * @method null copy
  27. */
  28. if (!class_exists('menu')) {
  29. class menu {
  30. /**
  31. * declare the variables
  32. */
  33. private $app_name;
  34. private $app_uuid;
  35. private $name;
  36. private $table;
  37. private $toggle_field;
  38. private $toggle_values;
  39. private $description_field;
  40. private $location;
  41. public $menu_uuid;
  42. public $menu_language;
  43. public $text;
  44. /**
  45. * called when the object is created
  46. */
  47. public function __construct() {
  48. //assign the variables
  49. $this->app_name = 'menus';
  50. $this->app_uuid = 'f4b3b3d2-6287-489c-2a00-64529e46f2d7';
  51. $this->location = 'menus.php';
  52. }
  53. /**
  54. * delete rows from the database
  55. */
  56. public function delete($records) {
  57. //assign the variables
  58. $this->name = 'menu';
  59. $this->table = 'menus';
  60. if (permission_exists($this->name.'_delete')) {
  61. //add multi-lingual support
  62. $language = new text;
  63. $text = $language->get();
  64. //validate the token
  65. $token = new token;
  66. if (!$token->validate($_SERVER['PHP_SELF'])) {
  67. message::add($text['message-invalid_token'],'negative');
  68. header('Location: '.$this->location);
  69. exit;
  70. }
  71. //delete multiple records
  72. if (is_array($records) && @sizeof($records) != 0) {
  73. //build the delete array
  74. $x = 0;
  75. foreach ($records as $record) {
  76. if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
  77. //remove menu languages
  78. $array['menu_languages'][$x][$this->name.'_uuid'] = $record['uuid'];
  79. //remove menu item groups
  80. $array['menu_item_groups'][$x][$this->name.'_uuid'] = $record['uuid'];
  81. //remove menu items
  82. $array['menu_items'][$x][$this->name.'_uuid'] = $record['uuid'];
  83. //build array to remove the menu
  84. $array[$this->table][$x][$this->name.'_uuid'] = $record['uuid'];
  85. //increment
  86. $x++;
  87. }
  88. }
  89. //delete the checked rows
  90. if (is_array($array) && @sizeof($array) != 0) {
  91. //grant temporary permissions
  92. $p = new permissions;
  93. $p->add('menu_item_delete', 'temp');
  94. $p->add('menu_item_group_delete', 'temp');
  95. $p->add('menu_language_delete', 'temp');
  96. //execute delete
  97. $database = new database;
  98. $database->app_name = $this->app_name;
  99. $database->app_uuid = $this->app_uuid;
  100. $database->delete($array);
  101. unset($array);
  102. //revoke temporary permissions
  103. $p->delete('menu_item_delete', 'temp');
  104. $p->delete('menu_item_group_delete', 'temp');
  105. $p->delete('menu_language_delete', 'temp');
  106. //set message
  107. message::add($text['message-delete']);
  108. }
  109. unset($records);
  110. }
  111. }
  112. }
  113. public function delete_items($records) {
  114. //assign the variables
  115. $this->name = 'menu_item';
  116. $this->table = 'menu_items';
  117. if (permission_exists($this->name.'_delete')) {
  118. //add multi-lingual support
  119. $language = new text;
  120. $text = $language->get();
  121. //validate the token
  122. $token = new token;
  123. if (!$token->validate('/core/menu/menu_item_list.php')) {
  124. message::add($text['message-invalid_token'],'negative');
  125. header('Location: '.$this->location);
  126. exit;
  127. }
  128. //delete multiple records
  129. if (is_array($records) && @sizeof($records) != 0) {
  130. //build the delete array
  131. $x = 0;
  132. foreach ($records as $record) {
  133. if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
  134. //build array
  135. $uuids[] = "'".$record['uuid']."'";
  136. //remove menu languages
  137. $array['menu_languages'][$x][$this->name.'_uuid'] = $record['uuid'];
  138. //remove menu item groups
  139. $array['menu_item_groups'][$x][$this->name.'_uuid'] = $record['uuid'];
  140. //remove menu items
  141. $array[$this->table][$x][$this->name.'_uuid'] = $record['uuid'];
  142. //increment
  143. $x++;
  144. }
  145. }
  146. //include child menu items
  147. if (!empty($uuids) && @sizeof($uuids) != 0) {
  148. $sql = "select menu_item_uuid as uuid from v_".$this->table." ";
  149. $sql .= "where menu_item_parent_uuid in (".implode(', ', $uuids).") ";
  150. $database = new database;
  151. $rows = $database->select($sql, null, 'all');
  152. if (!empty($rows) && @sizeof($rows) != 0) {
  153. foreach ($rows as $row) {
  154. //remove menu languages
  155. $array['menu_languages'][$x][$this->name.'_uuid'] = $row['uuid'];
  156. //remove menu item groups
  157. $array['menu_item_groups'][$x][$this->name.'_uuid'] = $row['uuid'];
  158. //remove menu items
  159. $array[$this->table][$x][$this->name.'_uuid'] = $row['uuid'];
  160. //increment
  161. $x++;
  162. }
  163. }
  164. }
  165. //delete the checked rows
  166. if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
  167. //grant temporary permissions
  168. $p = new permissions;
  169. $p->add('menu_language_delete', 'temp');
  170. $p->add('menu_item_group_delete', 'temp');
  171. //execute delete
  172. $database = new database;
  173. $database->app_name = $this->app_name;
  174. $database->app_uuid = $this->app_uuid;
  175. $database->delete($array);
  176. unset($array);
  177. //revoke temporary permissions
  178. $p->delete('menu_language_delete', 'temp');
  179. $p->delete('menu_item_group_delete', 'temp');
  180. //set message
  181. message::add($text['message-delete']);
  182. }
  183. unset($records);
  184. }
  185. }
  186. }
  187. /**
  188. * toggle a field between two values
  189. */
  190. public function toggle_items($records) {
  191. //assign the variables
  192. $this->name = 'menu_item';
  193. $this->table = 'menu_items';
  194. $this->toggle_field = 'menu_item_protected';
  195. $this->toggle_values = ['true','false'];
  196. if (permission_exists($this->name.'_edit')) {
  197. //add multi-lingual support
  198. $language = new text;
  199. $text = $language->get();
  200. //validate the token
  201. $token = new token;
  202. if (!$token->validate('/core/menu/menu_item_list.php')) {
  203. message::add($text['message-invalid_token'],'negative');
  204. header('Location: '.$this->location);
  205. exit;
  206. }
  207. //toggle the checked records
  208. if (is_array($records) && @sizeof($records) != 0) {
  209. //get current toggle state
  210. foreach ($records as $record) {
  211. if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) {
  212. $uuids[] = "'".$record['uuid']."'";
  213. }
  214. }
  215. if (!empty($uuids) && is_array($uuids) && @sizeof($uuids) != 0) {
  216. $sql = "select ".$this->name."_uuid as uuid, ".$this->toggle_field." as toggle from v_".$this->table." ";
  217. $sql .= "where ".$this->name."_uuid in (".implode(', ', $uuids).") ";
  218. $database = new database;
  219. $parameters = null;
  220. $rows = $database->select($sql, $parameters, 'all');
  221. if (is_array($rows) && @sizeof($rows) != 0) {
  222. foreach ($rows as $row) {
  223. $states[$row['uuid']] = $row['toggle'] == '' ? $this->toggle_values[1] : $row['toggle'];
  224. }
  225. }
  226. unset($sql, $parameters, $rows, $row);
  227. }
  228. //build update array
  229. $x = 0;
  230. if (!empty($states) && is_array($states) && @sizeof($states) != 0) {
  231. foreach ($states as $uuid => $state) {
  232. //create the array
  233. $array[$this->table][$x][$this->name.'_uuid'] = $uuid;
  234. $array[$this->table][$x][$this->toggle_field] = $state == $this->toggle_values[0] ? $this->toggle_values[1] : $this->toggle_values[0];
  235. //increment
  236. $x++;
  237. }
  238. }
  239. //save the changes
  240. if (!empty($array) && is_array($array) && @sizeof($array) != 0) {
  241. //save the array
  242. $database = new database;
  243. $database->app_name = $this->app_name;
  244. $database->app_uuid = $this->app_uuid;
  245. $database->save($array);
  246. unset($array);
  247. //set message
  248. message::add($text['message-toggle']);
  249. }
  250. unset($records, $states);
  251. }
  252. }
  253. }
  254. /**
  255. * delete items in the menu that are not protected
  256. */
  257. public function delete_unprotected() {
  258. //remove existing menu languages
  259. $sql = "delete from v_menu_languages ";
  260. $sql .= "where menu_uuid = :menu_uuid ";
  261. $sql .= "and menu_item_uuid in ( ";
  262. $sql .= " select menu_item_uuid ";
  263. $sql .= " from v_menu_items ";
  264. $sql .= " where menu_uuid = :menu_uuid ";
  265. $sql .= " and ( ";
  266. $sql .= " menu_item_protected <> 'true' ";
  267. $sql .= " or menu_item_protected is null ";
  268. $sql .= " ) ";
  269. $sql .= ") ";
  270. $parameters['menu_uuid'] = $this->menu_uuid;
  271. $database = new database;
  272. $database->execute($sql, $parameters);
  273. unset($sql, $parameters);
  274. //remove existing unprotected menu item groups
  275. $sql = "delete from v_menu_item_groups ";
  276. $sql .= "where menu_uuid = :menu_uuid ";
  277. $sql .= "and menu_item_uuid in ( ";
  278. $sql .= " select menu_item_uuid ";
  279. $sql .= " from v_menu_items ";
  280. $sql .= " where menu_uuid = :menu_uuid ";
  281. $sql .= " and ( ";
  282. $sql .= " menu_item_protected <> 'true' ";
  283. $sql .= " or menu_item_protected is null ";
  284. $sql .= " ) ";
  285. $sql .= ") ";
  286. $parameters['menu_uuid'] = $this->menu_uuid;
  287. $database = new database;
  288. $database->execute($sql, $parameters);
  289. unset($sql, $parameters);
  290. //remove existing unprotected menu items
  291. $sql = "delete from v_menu_items ";
  292. $sql .= "where menu_uuid = :menu_uuid ";
  293. $sql .= "and ( ";
  294. $sql .= " menu_item_protected <> 'true' ";
  295. $sql .= " or menu_item_protected is null ";
  296. $sql .= ") ";
  297. $parameters['menu_uuid'] = $this->menu_uuid;
  298. $database = new database;
  299. $database->execute($sql, $parameters);
  300. unset($sql, $parameters);
  301. }
  302. /**
  303. * restore the menu
  304. */
  305. public function restore() {
  306. //get the $apps array from the installed apps from the core and mod directories
  307. $config_list = glob($_SERVER["DOCUMENT_ROOT"].PROJECT_PATH."/*/*/app_menu.php");
  308. $x = 0;
  309. if (is_array($config_list)) {
  310. foreach ($config_list as $config_path) {
  311. $app_path = dirname($config_path);
  312. $app_path = preg_replace('/\A.*(\/.*\/.*)\z/', '$1', $app_path);
  313. $y = 0;
  314. try {
  315. //echo "[".$x ."] ".$config_path."\n";
  316. include($config_path);
  317. $x++;
  318. }
  319. catch (Exception $e) {
  320. echo 'exception caught: ' . $e->getMessage() . "\n";
  321. exit;
  322. }
  323. }
  324. }
  325. //get the list of languages
  326. $language = new text;
  327. //create a uuid array of the original uuid used as the key and new uuid as the value
  328. if (is_array($apps)) {
  329. $x = 0;
  330. foreach ($apps as $row) {
  331. if (is_array($row['menu'])) {
  332. foreach ($row['menu'] as $menu) {
  333. $uuid_array[$menu['uuid']] = uuid();
  334. }
  335. }
  336. }
  337. }
  338. //if the item uuid is not currently in the db then add it
  339. $sql = "select * from v_menu_items ";
  340. $sql .= "where menu_uuid = :menu_uuid ";
  341. $parameters['menu_uuid'] = $this->menu_uuid;
  342. $database = new database;
  343. $menu_items = $database->select($sql, $parameters, 'all');
  344. //use the app array to restore the default menu
  345. if (is_array($apps)) {
  346. $x = 0;
  347. foreach ($apps as $row) {
  348. if (is_array($row['menu'])) {
  349. foreach ($row['menu'] as $menu) {
  350. //set the variables
  351. if (!empty($menu['title'][$this->menu_language])) {
  352. $menu_item_title = $menu['title'][$this->menu_language];
  353. }
  354. else {
  355. $menu_item_title = $menu['title']['en-us'];
  356. }
  357. $uuid = $menu['uuid'];
  358. $menu_item_uuid = $uuid_array[$menu['uuid']];
  359. $menu_item_parent_uuid = $uuid_array[$menu['parent_uuid']] ?? null;
  360. $menu_item_category = $menu['category'];
  361. $menu_item_icon = $menu['icon'] ?? null;
  362. $menu_item_path = $menu['path'];
  363. $menu_item_order = $menu['order'] ?? null;
  364. $menu_item_description = $menu['desc'] ?? null;
  365. //sanitize the menu link
  366. $menu_item_path = preg_replace('#[^a-zA-Z0-9_:\-\.\&\=\?\/]#', '', $menu_item_path);
  367. //check if the menu item exists and if it does set the row array
  368. $menu_item_exists = false;
  369. foreach ($menu_items as $item) {
  370. if ($item['uuid'] == $menu['uuid']) {
  371. $menu_item_exists = true;
  372. $row = $item;
  373. }
  374. }
  375. //item exists in the database
  376. if ($menu_item_exists) {
  377. //get parent_menu_item_protected
  378. foreach ($menu_items as $item) {
  379. if ($item['uuid'] == $menu['parent_uuid']) {
  380. $parent_menu_item_protected = $item['menu_item_protected'];
  381. }
  382. }
  383. //parent is not protected so the parent uuid needs to be updated
  384. if (is_uuid($menu_item_parent_uuid) && $menu_item_parent_uuid != $row['menu_item_parent_uuid'] && $parent_menu_item_protected != 'true') {
  385. $array['menu_items'][$x]['menu_item_uuid'] = $row['menu_item_uuid'];
  386. $array['menu_items'][$x]['menu_item_parent_uuid'] = $menu_item_parent_uuid;
  387. $x++;
  388. }
  389. }
  390. //item does not exist in the database
  391. if (!$menu_item_exists) {
  392. if ($menu_item_uuid != $menu_item_parent_uuid) {
  393. $array['menu_items'][$x]['menu_item_uuid'] = $menu_item_uuid;
  394. $array['menu_items'][$x]['menu_uuid'] = $this->menu_uuid;
  395. $array['menu_items'][$x]['uuid'] = $uuid;
  396. $array['menu_items'][$x]['menu_item_title'] = $menu_item_title;
  397. $array['menu_items'][$x]['menu_item_link'] = $menu_item_path;
  398. $array['menu_items'][$x]['menu_item_category'] = $menu_item_category;
  399. $array['menu_items'][$x]['menu_item_icon'] = $menu_item_icon;
  400. if (!empty($menu_item_order)) {
  401. $array['menu_items'][$x]['menu_item_order'] = $menu_item_order;
  402. }
  403. if (is_uuid($menu_item_parent_uuid)) {
  404. $array['menu_items'][$x]['menu_item_parent_uuid'] = $menu_item_parent_uuid;
  405. }
  406. $array['menu_items'][$x]['menu_item_description'] = $menu_item_description;
  407. $x++;
  408. }
  409. }
  410. unset($field, $parameters, $num_rows);
  411. //set the menu languages
  412. if (!$menu_item_exists && is_array($language->languages)) {
  413. foreach ($language->languages as $menu_language) {
  414. //set the menu item title
  415. if (!empty($menu["title"][$menu_language])) {
  416. $menu_item_title = $menu["title"][$menu_language];
  417. }
  418. else {
  419. $menu_item_title = $menu["title"]['en-us'];
  420. }
  421. //build insert array
  422. $array['menu_languages'][$x]['menu_language_uuid'] = uuid();
  423. $array['menu_languages'][$x]['menu_item_uuid'] = $menu_item_uuid;
  424. $array['menu_languages'][$x]['menu_uuid'] = $this->menu_uuid;
  425. $array['menu_languages'][$x]['menu_language'] = $menu_language;
  426. $array['menu_languages'][$x]['menu_item_title'] = $menu_item_title;
  427. $x++;
  428. }
  429. }
  430. }
  431. }
  432. }
  433. if (is_array($array) && @sizeof($array) != 0) {
  434. //grant temporary permissions
  435. $p = new permissions;
  436. $p->add('menu_item_add', 'temp');
  437. $p->add('menu_language_add', 'temp');
  438. //execute insert
  439. $database = new database;
  440. $database->app_name = 'menu';
  441. $database->app_uuid = 'f4b3b3d2-6287-489c-2a00-64529e46f2d7';
  442. $database->save($array);
  443. unset($array);
  444. //revoke temporary permissions
  445. $p->delete('menu_item_add', 'temp');
  446. $p->delete('menu_language_add', 'temp');
  447. }
  448. }
  449. //make sure the default user groups exist
  450. $group = new groups;
  451. $group->defaults();
  452. //get default global group_uuids
  453. $sql = "select group_uuid, group_name from v_groups ";
  454. $sql .= "where domain_uuid is null ";
  455. $database = new database;
  456. $result = $database->select($sql, null, 'all');
  457. if (is_array($result) && @sizeof($result) != 0) {
  458. foreach ($result as $row) {
  459. $group_uuids[$row['group_name']] = $row['group_uuid'];
  460. }
  461. }
  462. unset($sql, $result, $row);
  463. //if there are no groups listed in v_menu_item_groups under menu_item_uuid then add the default groups
  464. if (is_array($apps)) {
  465. $x = 0;
  466. foreach($apps as $app) {
  467. if (is_array($apps)) {
  468. foreach ($app['menu'] as $sub_row) {
  469. if (isset($sub_row['groups'])) {
  470. foreach ($sub_row['groups'] as $group) {
  471. $sql = "select count(*) from v_menu_item_groups ";
  472. $sql .= "where menu_item_uuid = :menu_item_uuid ";
  473. $sql .= "and menu_uuid = :menu_uuid ";
  474. $sql .= "and group_name = :group_name ";
  475. $sql .= "and group_uuid = :group_uuid ";
  476. $parameters['menu_item_uuid'] = $uuid_array[$sub_row['uuid']];
  477. $parameters['menu_uuid'] = $this->menu_uuid;
  478. $parameters['group_name'] = $group;
  479. $parameters['group_uuid'] = $group_uuids[$group] ?? null;
  480. $database = new database;
  481. $num_rows = $database->select($sql, $parameters, 'column');
  482. if ($num_rows == 0) {
  483. //no menu item groups found, build insert array for defaults
  484. $array['menu_item_groups'][$x]['menu_item_group_uuid'] = uuid();
  485. $array['menu_item_groups'][$x]['menu_uuid'] = $this->menu_uuid;
  486. $array['menu_item_groups'][$x]['menu_item_uuid'] = $uuid_array[$sub_row['uuid']];
  487. $array['menu_item_groups'][$x]['group_name'] = $group;
  488. $array['menu_item_groups'][$x]['group_uuid'] = $group_uuids[$group] ?? null;
  489. $x++;
  490. }
  491. unset($sql, $parameters, $num_rows);
  492. }
  493. }
  494. }
  495. }
  496. }
  497. if (is_array($array) && @sizeof($array) != 0) {
  498. //grant temporary permissions
  499. $p = new permissions;
  500. $p->add('menu_item_group_add', 'temp');
  501. //execute insert
  502. $database = new database;
  503. $database->app_name = 'menu';
  504. $database->app_uuid = 'f4b3b3d2-6287-489c-2a00-64529e46f2d7';
  505. $database->save($array);
  506. unset($array);
  507. //revoke temporary permissions
  508. $p->delete('menu_item_group_add', 'temp');
  509. }
  510. }
  511. }
  512. /**
  513. * create the menu
  514. */
  515. public function build_html($menu_item_level = 0) {
  516. $menu_html_full = '';
  517. $menu_array = $this->menu_array();
  518. if (!isset($_SESSION['groups'])) {
  519. $_SESSION['groups'][0]['group_name'] = 'public';
  520. }
  521. if (is_array($menu_array)) {
  522. foreach($menu_array as $menu_field) {
  523. //set the variables
  524. $menu_item_link = $menu_field['menu_item_link'];
  525. $menu_item_category = $menu_field['menu_item_category'];
  526. $menu_items = $menu_field['menu_items'];
  527. //prepare the protected menus
  528. $menu_item_title = ($menu_field['menu_item_protected'] == "true") ? $menu_field['menu_item_title'] : $menu_field['menu_language_title'];
  529. //prepare the menu_tags according to the category
  530. $menu_tags = '';
  531. switch ($menu_item_category) {
  532. case "internal":
  533. $menu_tags = "href='".PROJECT_PATH.$submenu_item_link."'";
  534. break;
  535. case "external":
  536. if (substr($submenu_item_link, 0,1) == "/") {
  537. $submenu_item_link = PROJECT_PATH.$submenu_item_link;
  538. }
  539. $menu_tags = "href='".$submenu_item_link."' target='_blank'";
  540. break;
  541. case "email":
  542. $menu_tags = "href='mailto:".$submenu_item_link."'";
  543. break;
  544. }
  545. if ($menu_item_level == 0) {
  546. $menu_html = "<ul class='menu_main'>\n";
  547. $menu_html .= "<li>\n";
  548. if (!isset($_SESSION["username"])) {
  549. $_SESSION["username"] = '';
  550. }
  551. if (empty($_SESSION["username"])) {
  552. $menu_html .= "<a $menu_tags style='padding: 0px 0px; border-style: none; background: none;'><h2 align='center' style=''>".$menu_item_title."</h2></a>\n";
  553. }
  554. else {
  555. if ($submenu_item_link == "/login.php" || $submenu_item_link == "/users/signup.php") {
  556. //hide login and sign-up when the user is logged in
  557. }
  558. else {
  559. if (empty($submenu_item_link)) {
  560. $menu_html .= "<h2 align='center' style=''>".$menu_item_title."</h2>\n";
  561. }
  562. else {
  563. $menu_html .= "<a ".$menu_tags." style='padding: 0px 0px; border-style: none; background: none;'><h2 align='center' style=''>".$menu_item_title."</h2></a>\n";
  564. }
  565. }
  566. }
  567. }
  568. if (is_array($menu_field['menu_items']) && count($menu_field['menu_items']) > 0) {
  569. $menu_html .= $this->build_child_html($menu_item_level, $menu_field['menu_items']);
  570. }
  571. if ($menu_item_level == 0) {
  572. $menu_html .= "</li>\n";
  573. $menu_html .= "</ul>\n\n";
  574. }
  575. $menu_html_full .= $menu_html;
  576. } //end for each
  577. }
  578. return $menu_html_full;
  579. }
  580. /**
  581. * create the sub menus
  582. */
  583. private function build_child_html($menu_item_level, $submenu_array) {
  584. $menu_item_level = $menu_item_level+1;
  585. if (count($_SESSION['groups']) == 0) {
  586. $_SESSION['groups'][0]['group_name'] = 'public';
  587. }
  588. if (is_array($submenu_array)) {
  589. //child menu found
  590. $submenu_html = "<ul class='menu_sub'>\n";
  591. foreach($submenu_array as $submenu_field) {
  592. //set the variables
  593. $menu_item_link = $submenu_field['menu_item_link'];
  594. $menu_item_category = $submenu_field['menu_item_category'];
  595. $menu_items = $submenu_field['menu_items'];
  596. //prepare the protected menus
  597. $menu_item_title = ($submenu_field['menu_item_protected'] == "true") ? $submenu_field['menu_item_title'] : $submenu_field['menu_language_title'];
  598. //prepare the menu_tags according to the category
  599. switch ($menu_item_category) {
  600. case "internal":
  601. $menu_tags = "href='".PROJECT_PATH.$menu_item_link."'";
  602. break;
  603. case "external":
  604. if (substr($menu_item_link, 0,1) == "/") {
  605. $menu_item_link = PROJECT_PATH.$menu_item_link;
  606. }
  607. $menu_tags = "href='".$menu_item_link."' target='_blank'";
  608. break;
  609. case "email":
  610. $menu_tags = "href='mailto:".$menu_item_link."'";
  611. break;
  612. }
  613. $submenu_html .= "<li>";
  614. //get sub menu for children
  615. if (is_array($menu_items) && count($menu_items) > 0) {
  616. $str_child_menu = $this->build_child_html($menu_item_level, $menu_items);
  617. }
  618. if (strlen($str_child_menu) > 1) {
  619. $submenu_html .= "<a ".$menu_tags.">".$menu_item_title."</a>";
  620. $submenu_html .= $str_child_menu;
  621. unset($str_child_menu);
  622. }
  623. else {
  624. $submenu_html .= "<a ".$menu_tags.">".$menu_item_title."</a>";
  625. }
  626. $submenu_html .= "</li>\n";
  627. }
  628. unset($submenu_array);
  629. $submenu_html .="</ul>\n";
  630. return $submenu_html;
  631. }
  632. }
  633. /**
  634. * create the menu array
  635. */
  636. public function menu_array($menu_item_level = 0) {
  637. //if there are no groups then set the public group
  638. if (!isset($_SESSION['groups'][0]['group_name'])) {
  639. $_SESSION['groups'][0]['group_name'] = 'public';
  640. }
  641. //get the menu from the database
  642. $sql = "select i.menu_item_link, l.menu_item_title as menu_language_title, ";
  643. $sql .= "i.menu_item_title, i.menu_item_protected, i.menu_item_category, ";
  644. $sql .= "i.menu_item_icon, i.menu_item_uuid, i.menu_item_parent_uuid ";
  645. $sql .= "from v_menu_items as i, v_menu_languages as l ";
  646. $sql .= "where i.menu_item_uuid = l.menu_item_uuid ";
  647. $sql .= "and l.menu_language = :menu_language ";
  648. $sql .= "and l.menu_uuid = :menu_uuid ";
  649. $sql .= "and i.menu_uuid = :menu_uuid ";
  650. $sql .= "and i.menu_item_parent_uuid is null ";
  651. $sql .= "and i.menu_item_uuid in ";
  652. $sql .= "( ";
  653. $sql .= "select menu_item_uuid ";
  654. $sql .= "from v_menu_item_groups ";
  655. $sql .= "where menu_uuid = :menu_uuid ";
  656. $x = 0;
  657. foreach($_SESSION['groups'] as $row) {
  658. $sql_where_or[] = "group_name = :group_name_".$x;
  659. $parameters['group_name_'.$x] = $row['group_name'];
  660. $x++;
  661. }
  662. if (is_array($sql_where_or) && @sizeof($sql_where_or) != 0) {
  663. $sql .= "and ( ";
  664. $sql .= implode(' or ', $sql_where_or);
  665. $sql .= ") ";
  666. }
  667. $sql .= "and menu_item_uuid is not null ";
  668. $sql .= ") ";
  669. $sql .= "order by i.menu_item_order asc ";
  670. $parameters['menu_language'] = $_SESSION['domain']['language']['code'] ?? null;
  671. $parameters['menu_uuid'] = $this->menu_uuid;
  672. $database = new database;
  673. $result = $database->select($sql, $parameters, 'all');
  674. unset($sql, $parameters);
  675. //save the menu into an array
  676. $x = 0;
  677. $a = Array();
  678. if (is_array($result) && @sizeof($result) != 0) {
  679. foreach($result as $row) {
  680. //add the row to the array
  681. $a[$x] = $row;
  682. //add the sub menus to the array
  683. $menu_item_level = 0;
  684. if (!empty($row['menu_item_uuid'])) {
  685. $a[$x]['menu_items'] = $this->menu_child_array($menu_item_level, $row['menu_item_uuid']);
  686. }
  687. //increment the row number
  688. $x++;
  689. }
  690. }
  691. unset($result, $row);
  692. //return the array
  693. return $a;
  694. }
  695. /**
  696. * create the sub menus
  697. */
  698. private function menu_child_array($menu_item_level, $menu_item_uuid) {
  699. //set the level
  700. $menu_item_level = $menu_item_level + 1;
  701. //if there are no groups then set the public group
  702. if (!isset($_SESSION['groups'][0]['group_name'])) {
  703. $_SESSION['groups'][0]['group_name'] = 'public';
  704. }
  705. //get the child menu from the database
  706. $sql = "select i.menu_item_link, l.menu_item_title as menu_language_title, i.menu_item_title, i.menu_item_protected, i.menu_item_category, i.menu_item_icon, i.menu_item_uuid, i.menu_item_parent_uuid ";
  707. $sql .= "from v_menu_items as i, v_menu_languages as l ";
  708. $sql .= "where i.menu_item_uuid = l.menu_item_uuid ";
  709. $sql .= "and l.menu_language = :menu_language ";
  710. $sql .= "and l.menu_uuid = :menu_uuid ";
  711. $sql .= "and i.menu_uuid = :menu_uuid ";
  712. $sql .= "and i.menu_item_parent_uuid = :menu_item_parent_uuid ";
  713. $sql .= "and i.menu_item_uuid in ";
  714. $sql .= "( ";
  715. $sql .= "select menu_item_uuid ";
  716. $sql .= "from v_menu_item_groups ";
  717. $sql .= "where menu_uuid = :menu_uuid ";
  718. $x = 0;
  719. foreach($_SESSION['groups'] as $row) {
  720. $sql_where_or[] = "group_name = :group_name_".$x;
  721. $parameters['group_name_'.$x] = $row['group_name'];
  722. $x++;
  723. }
  724. if (is_array($sql_where_or) && @sizeof($sql_where_or) != 0) {
  725. $sql .= "and ( ";
  726. $sql .= implode(' or ', $sql_where_or);
  727. $sql .= ") ";
  728. }
  729. $sql .= ") ";
  730. $sql .= "order by l.menu_item_title, i.menu_item_order asc ";
  731. $parameters['menu_language'] = $_SESSION['domain']['language']['code'];
  732. $parameters['menu_uuid'] = $this->menu_uuid;
  733. $parameters['menu_item_parent_uuid'] = $menu_item_uuid;
  734. $database = new database;
  735. $sub_result = $database->select($sql, $parameters, 'all');
  736. unset($sql, $parameters);
  737. //save the child menu into an array
  738. $x = 0;
  739. $a = Array();
  740. if (is_array($sub_result) && @sizeof($sub_result) != 0) {
  741. foreach($sub_result as $row) {
  742. //set the variables
  743. $menu_item_link = $row['menu_item_link'];
  744. $menu_item_category = $row['menu_item_category'];
  745. $menu_item_icon = $row['menu_item_icon'];
  746. $menu_item_uuid = $row['menu_item_uuid'];
  747. $menu_item_parent_uuid = $row['menu_item_parent_uuid'];
  748. //add the row to the array
  749. $a[$x] = $row;
  750. //prepare the protected menus
  751. if ($row['menu_item_protected'] == "true") {
  752. $a[$x]['menu_item_title'] = $row['menu_item_title'];
  753. }
  754. else {
  755. $a[$x]['menu_item_title'] = $row['menu_language_title'];
  756. }
  757. //get sub menu for children
  758. if (!empty($menu_item_uuid)) {
  759. $a[$x]['menu_items'] = $this->menu_child_array($menu_item_level, $menu_item_uuid);
  760. }
  761. //increment the row
  762. $x++;
  763. }
  764. }
  765. unset($sub_result, $row);
  766. //return the array
  767. return $a;
  768. }
  769. /**
  770. * add the default menu when no menu exists
  771. */
  772. public function menu_default() {
  773. //set the default menu_uuid
  774. $this->menu_uuid = 'b4750c3f-2a86-b00d-b7d0-345c14eca286';
  775. //check to see if any menu exists
  776. $sql = "select count(*) as count from v_menus ";
  777. $sql .= "where menu_uuid = :menu_uuid ";
  778. $parameters['menu_uuid'] = $this->menu_uuid;
  779. $database = new database;
  780. $num_rows = $database->select($sql, $parameters, 'column');
  781. if ($num_rows == 0) {
  782. //built insert array
  783. $array['menus'][0]['menu_uuid'] = $this->menu_uuid;
  784. $array['menus'][0]['menu_name'] = 'default';
  785. $array['menus'][0]['menu_language'] = 'en-us';
  786. $array['menus'][0]['menu_description'] = 'Default Menu';
  787. //grant temporary permissions
  788. $p = new permissions;
  789. $p->add('menu_add', 'temp');
  790. //execute insert
  791. $database = new database;
  792. $database->app_name = 'menu';
  793. $database->app_uuid = 'f4b3b3d2-6287-489c-2a00-64529e46f2d7';
  794. $database->save($array);
  795. unset($array);
  796. //revoke temporary permissions
  797. $p->delete('menu_add', 'temp');
  798. //add the menu items
  799. $this->restore();
  800. }
  801. unset($sql, $parameters, $result, $row);
  802. }
  803. /**
  804. * build the fixed, static or inline horizontal menu html
  805. */
  806. public function menu_horizontal($menu_array) {
  807. //determine menu behavior
  808. $menu_style = !empty($_SESSION['theme']['menu_style']['text']) ? $_SESSION['theme']['menu_style']['text'] : 'fixed';
  809. switch ($menu_style) {
  810. case 'inline':
  811. $menu_type = 'default';
  812. $menu_width = 'calc(100% - 20px)';
  813. $menu_brand = false;
  814. $menu_corners = null;
  815. break;
  816. case 'static':
  817. $menu_type = 'static-top';
  818. $menu_width = 'calc(100% - 40px)';
  819. $menu_brand = true;
  820. $menu_corners = "style='-webkit-border-radius: 0 0 4px 4px; -moz-border-radius: 0 0 4px 4px; border-radius: 0 0 4px 4px;'";
  821. break;
  822. case 'fixed':
  823. default:
  824. $menu_type = 'fixed-'.(!empty($_SESSION['theme']['menu_position']['text']) ? $_SESSION['theme']['menu_position']['text'] : 'top');
  825. if (!http_user_agent('mobile')) {
  826. $menu_width = !empty($_SESSION['theme']['menu_width_fixed']['text']) ? $_SESSION['theme']['menu_width_fixed']['text'] : 'calc(90% - 20px)';
  827. }
  828. $menu_brand = true;
  829. $menu_corners = null;
  830. }
  831. //begin navbar code
  832. $html = "<nav class='navbar navbar-expand-sm ".$menu_type."' ".$menu_corners.">\n";
  833. $html .= " <div class='container-fluid' style='width: ".($menu_width ?? '100%')."; padding: 0;'>\n";
  834. $html .= " <div class='navbar-brand'>\n";
  835. if ($menu_brand) {
  836. //define menu brand mark
  837. $menu_brand_text = (!empty($_SESSION['theme']['menu_brand_text']['text'])) ? escape($_SESSION['theme']['menu_brand_text']['text']) : "FusionPBX";
  838. switch ($_SESSION['theme']['menu_brand_type']['text'] ?? null) {
  839. case 'text':
  840. $html .= " <a class='navbar-brand-text' href='".PROJECT_PATH."/'>".$menu_brand_text."</a>\n";
  841. break;
  842. case 'image_text':
  843. $menu_brand_image = (!empty($_SESSION['theme']['menu_brand_image']['text'])) ? escape($_SESSION['theme']['menu_brand_image']['text']) : PROJECT_PATH."/themes/default/images/logo.png";
  844. $html .= " <a href='".PROJECT_PATH."/'>";
  845. $html .= " <img id='menu_brand_image' class='navbar-logo' src='".$menu_brand_image."' title=\"".escape($menu_brand_text)."\">";
  846. if (!empty($_SESSION['theme']['menu_brand_image_hover']['text'])) {
  847. $html .= "<img id='menu_brand_image_hover' class='navbar-logo' style='display: none;' src='".$_SESSION['theme']['menu_brand_image_hover']['text']."' title=\"".escape($menu_brand_text)."\">";
  848. }
  849. $html .= "</a>\n";
  850. $html .= " <a class='navbar-brand-text' href='".PROJECT_PATH."/'>".$menu_brand_text."</a>\n";
  851. break;
  852. case 'none':
  853. break;
  854. case 'image':
  855. default:
  856. $menu_brand_image = !empty($_SESSION['theme']['menu_brand_image']['text']) ? escape($_SESSION['theme']['menu_brand_image']['text']) : PROJECT_PATH."/themes/default/images/logo.png";
  857. $html .= " <a href='".PROJECT_PATH."/'>";
  858. $html .= " <img id='menu_brand_image' class='navbar-logo' src='".$menu_brand_image."' title=\"".escape($menu_brand_text)."\">";
  859. if (isset($_SESSION['theme']['menu_brand_image_hover']['text']) && !empty($_SESSION['theme']['menu_brand_image_hover']['text'])) {
  860. $html .= "<img id='menu_brand_image_hover' class='navbar-logo' style='display: none;' src='".$_SESSION['theme']['menu_brand_image_hover']['text']."' title=\"".escape($menu_brand_text)."\">";
  861. }
  862. $html .= "</a>\n";
  863. $html .= " <a style='margin: 0;'></a>\n";
  864. }
  865. }
  866. $html .= " </div>\n";
  867. $html .= " <button type='button' class='navbar-toggler' data-toggle='collapse' data-target='#main_navbar' aria-expanded='false' aria-controls='main_navbar' aria-label='Toggle Menu'>\n";
  868. $html .= " <span class='fas fa-bars'></span>\n";
  869. $html .= " </button>\n";
  870. $html .= " <div class='collapse navbar-collapse' id='main_navbar'>\n";
  871. $html .= " <ul class='navbar-nav'>\n";
  872. if (!empty($menu_array) && sizeof($menu_array) != 0) {
  873. foreach ($menu_array as $index_main => $menu_parent) {
  874. $mod_li = "nav-item";
  875. $mod_a_1 = "";
  876. $submenu = false;
  877. if (!empty($menu_parent['menu_items']) && sizeof($menu_parent['menu_items']) > 0) {
  878. $mod_li = "nav-item dropdown ";
  879. $mod_a_1 = "data-toggle='dropdown' ";
  880. $submenu = true;
  881. }
  882. $mod_a_2 = (!empty($menu_parent['menu_item_link']) && !$submenu) ? $menu_parent['menu_item_link'] : '#';
  883. $mod_a_3 = ($menu_parent['menu_item_category'] == 'external') ? "target='_blank' " : null;
  884. if (isset($_SESSION['theme']['menu_main_icons']['boolean']) && $_SESSION['theme']['menu_main_icons']['boolean'] == 'true') {
  885. if (!empty($menu_parent['menu_item_icon']) && substr_count($menu_parent['menu_item_icon'], 'fa-') > 0) {
  886. $menu_main_icon = "<span class='fas ".$menu_parent['menu_item_icon']."' title=\"".escape($menu_parent['menu_language_title'])."\"></span>";
  887. }
  888. else {
  889. $menu_main_icon = null;
  890. }
  891. $menu_main_item = "<span class='d-sm-none d-md-none d-lg-inline' style='margin-left: 5px;'>".$menu_parent['menu_language_title']."</span>\n";
  892. }
  893. else {
  894. $menu_main_item = $menu_parent['menu_language_title'];
  895. }
  896. $html .= " <li class='".$mod_li."'>\n";
  897. $html .= " <a class='nav-link' ".$mod_a_1." href='".$mod_a_2."' ".$mod_a_3.">\n";
  898. $html .= " ".$menu_main_icon.$menu_main_item;
  899. $html .= " </a>\n";
  900. if ($submenu) {
  901. $columns = @sizeof($menu_parent['menu_items']) > 20 ? 2 : 1;
  902. $column_current = 1;
  903. $mod_ul = $columns > 1 ? 'multi-column' : null;
  904. $html .= " <ul class='dropdown-menu ".$mod_ul."'>\n";
  905. if ($columns > 1) {
  906. $html .= " <div class='row'>\n";
  907. $html .= " <div class='col-12 col-sm-6 pr-sm-0'>\n";
  908. $html .= " <ul class='multi-column-dropdown'>\n";
  909. }
  910. foreach ($menu_parent['menu_items'] as $index_sub => $menu_sub) {
  911. $mod_a_2 = $menu_sub['menu_item_link'];
  912. if ($mod_a_2 == '') {
  913. $mod_a_2 = '#';
  914. }
  915. $mod_a_3 = ($menu_sub['menu_item_category'] == 'external') ? "target='_blank' " : null;
  916. $menu_sub_icon = null;
  917. if ($_SESSION['theme']['menu_sub_icons']['boolean'] != 'false') {
  918. if (!empty($menu_sub['menu_item_icon']) && substr_count($menu_sub['menu_item_icon'], 'fa-') > 0) {
  919. $menu_sub_icon = "<span class='fas ".escape($menu_sub['menu_item_icon'])."'></span>";
  920. }
  921. else {
  922. $menu_sub_icon = null;
  923. }
  924. }
  925. $html .= " <li class='nav-item'><a class='nav-link' href='".$mod_a_2."' ".$mod_a_3.">".($_SESSION['theme']['menu_sub_icons']['boolean'] != 'false' ? "<span class='fas fa-bar d-inline-block d-sm-none float-left' style='margin: 4px 10px 0 25px;'></span>" : null).escape($menu_sub['menu_language_title']).$menu_sub_icon."</a></li>\n";
  926. if ($columns > 1 && $column_current == 1 && ($index_sub+1) > (ceil(@sizeof($menu_parent['menu_items'])/2)-1)) {
  927. $html .= " </ul>\n";
  928. $html .= " </div>\n";
  929. $html .= " <div class='col-12 col-sm-6 pl-sm-0'>\n";
  930. $html .= " <ul class='multi-column-dropdown'>\n";
  931. $column_current = 2;
  932. }
  933. }
  934. if ($columns > 1) {
  935. $html .= " </ul>\n";
  936. $html .= " </div>\n";
  937. $html .= " </div>\n";
  938. }
  939. $html .= " </ul>\n";
  940. }
  941. $html .= " </li>\n";
  942. }
  943. }
  944. $html .= " </ul>\n";
  945. $html .= " <ul class='navbar-nav ml-auto'>\n";
  946. //current user
  947. if (isset($_SESSION['theme']['user_visible']['text']) && $_SESSION['theme']['user_visible']['text'] == 'true') {
  948. $html .= " <li class='nav-item'>\n";
  949. $html .= " <a class='header_user' href='".PROJECT_PATH."/core/users/user_edit.php?id=user' title=\"".$this->text['theme-label-user']."\"><i class='fas fa-".(!empty($_SESSION['theme']['body_header_icon_user']['text']) ? $_SESSION['theme']['body_header_icon_user']['text'] : 'user-circle')." fa-lg fa-fw' style='margin-top: 6px; margin-right: 5px;'></i>".$_SESSION['username']."</a>";
  950. $html .= " </li>\n";
  951. }
  952. //domain name/selector
  953. if (!empty($_SESSION['username']) && permission_exists('domain_select') && count($_SESSION['domains']) > 1 && $_SESSION['theme']['domain_visible']['text'] == 'true') {
  954. $html .= " <li class='nav-item'>\n";
  955. $html .= " <a class='header_domain' href='#' id='header_domain_selector_domain' title='".$this->text['theme-label-open_selector']."'><i class='fas fa-".(!empty($_SESSION['theme']['body_header_icon_domain']['text']) ? $_SESSION['theme']['body_header_icon_domain']['text'] : 'globe-americas')." fa-lg fa-fw' style='margin-top: 6px; margin-right: 5px;'></i>".escape($_SESSION['domain_name'])."</a>";
  956. $html .= " </li>\n";
  957. }
  958. //logout icon
  959. if (!empty($_SESSION['username']) && isset($_SESSION['theme']['logout_icon_visible']) && $_SESSION['theme']['logout_icon_visible']['text'] == "true") {
  960. $username_full = $_SESSION['username'].((count($_SESSION['domains']) > 1) ? "@".$_SESSION["user_context"] : null);
  961. $html .= " <li class='nav-item'>\n";
  962. $html .= " <a class='logout_icon' href='#' title=\"".$this->text['theme-label-logout']."\" onclick=\"modal_open('modal-logout','btn_logout');\"><span class='fas fa-sign-out-alt'></span></a>";
  963. $html .= " </li>\n";
  964. unset($username_full);
  965. }
  966. $html .= " </ul>\n";
  967. $html .= " </div>\n";
  968. $html .= " </div>\n";
  969. $html .= "</nav>\n";
  970. //modal for logout icon (above)
  971. if (!empty($_SESSION['username']) && isset($_SESSION['theme']['logout_icon_visible']) && $_SESSION['theme']['logout_icon_visible']['text'] == "true") {
  972. $html .= modal::create(['id'=>'modal-logout','type'=>'general','message'=>$this->text['theme-confirm-logout'],'actions'=>button::create(['type'=>'button','label'=>$this->text['theme-label-logout'],'icon'=>'sign-out-alt','id'=>'btn_logout','style'=>'float: right; margin-left: 15px;','collapse'=>'never','link'=>PROJECT_PATH.'/logout.php','onclick'=>"modal_close();"])]);
  973. }
  974. return $html;
  975. unset($html);
  976. }
  977. /**
  978. * build the vertical side menu html
  979. */
  980. public function menu_vertical($menu_array) {
  981. //menu brand image and/or text
  982. $html .= " <div id='menu_side_control_container'>\n";
  983. $html .= " <div class='menu_side_control_state' style='float: right; ".($_SESSION['theme']['menu_side_state']['text'] != 'expanded' ? 'display: none' : null)."'>\n";
  984. if ($_SESSION['theme']['menu_brand_type']['text'] != 'none') {
  985. $html .= " <a class='menu_side_item_main menu_side_contract' onclick='menu_side_contract();' style='padding: 8px 15px !important; ".($_SESSION['theme']['menu_side_state']['text'] != 'expanded' ? "display: none;" : null)."'><i class='fas fa-bars fa-fw'></i></a>\n";
  986. }
  987. if ($_SESSION['theme']['menu_side_pin']['boolean'] == 'true') {
  988. $html .= " <a class='menu_side_item_main' id='menu_side_state_set_expanded' onclick=\"menu_side_state_set('expanded');\" oncontextmenu=\"menu_side_state_set('delete'); return false;\" style='padding: 8px 14px 8px 16px !important; ".($_SESSION['theme']['menu_side_state']['text'] == 'expanded' ? 'display: none' : null)."' title=\"".$this->text['theme-label-pin_menu']."\"><i class='fas fa-toggle-off fa-sm fa-fw'></i></a>\n";
  989. $html .= " <a class='menu_side_item_main' id='menu_side_state_set_contracted' onclick=\"menu_side_state_set('contracted');\" oncontextmenu=\"menu_side_state_set('delete'); return false;\" style='padding: 8px 14px 8px 16px !important; ".($_SESSION['theme']['menu_side_state']['text'] != 'expanded' ? 'display: none' : null)."' title=\"".$this->text['theme-label-unpin_menu']."\"><i class='fas fa-toggle-on fa-sm fa-fw'></i></a>\n";
  990. }
  991. $html .= " </div>\n";
  992. if ($_SESSION['theme']['menu_brand_type']['text'] == 'none') {
  993. $html .= " <a class='menu_side_item_main menu_side_contract' onclick='menu_side_contract();' style='".($_SESSION['theme']['menu_side_pin']['boolean'] == 'true' ? "max-width: calc(100% - 50px);" : null)." ".($_SESSION['theme']['menu_side_state']['text'] != 'expanded' ? "display: none;" : null)."' title=\"".$this->text['theme-label-contract_menu']."\"><i class='fas fa-bars fa-fw' style='z-index: 99800; padding-left: 1px;'></i></a>";
  994. }
  995. $menu_brand_text = !empty($_SESSION['theme']['menu_brand_text']['text']) ? escape($_SESSION['theme']['menu_brand_text']['text']) : "FusionPBX";
  996. if ($_SESSION['theme']['menu_brand_type']['text'] == 'text') {
  997. $html .= " <a class='menu_brand_text' ".($_SESSION['theme']['menu_side_state']['text'] != 'expanded' ? "style='display: none;'" : null)." href='".PROJECT_PATH."/'>".$menu_brand_text."</a>\n";
  998. }
  999. if ($_SESSION['theme']['menu_brand_type']['text'] == 'image' || $_SESSION['theme']['menu_brand_type']['text'] == 'image_text' || $_SESSION['theme']['menu_brand_type']['text'] == '') {
  1000. $menu_brand_image_contracted = !empty($_SESSION['theme']['menu_side_brand_image_contracted']['text']) ? $_SESSION['theme']['menu_side_brand_image_contracted']['text'] : PROJECT_PATH."/themes/default/images/logo_side_contracted.png";
  1001. $menu_brand_image_expanded = !empty($_SESSION['theme']['menu_side_brand_image_expanded']['text']) ? $_SESSION['theme']['menu_side_brand_image_expanded']['text'] : PROJECT_PATH."/themes/default/images/logo_side_expanded.png";
  1002. $html .= " <a class='menu_brand_image' href='".PROJECT_PATH."/'>";
  1003. $html .= "<img id='menu_brand_image_contracted' style='".($_SESSION['theme']['menu_side_state']['text'] == 'expanded' ? "display: none;" : null)."' src='".escape($menu_brand_image_contracted)."' title=\"".escape($menu_brand_text)."\">";
  1004. $html .= "<img id='menu_brand_image_expanded' ".($_SESSION['theme']['menu_side_state']['text'] != 'expanded' ? "style='display: none;'" : null)." src='".escape($menu_brand_image_expanded)."' title=\"".escape($menu_brand_text)."\">";
  1005. $html .= "</a>\n";
  1006. }
  1007. // else {
  1008. // $html .= " <a class='menu_side_item_main menu_side_expand' ".($_SESSION['theme']['menu_side_state']['text'] == 'expanded' ? "style='display: none';" : null)." onclick='menu_side_expand();' title=\"".$this->text['theme-label-expand_menu']."\"><i class='fas fa-bars fa-fw' style='z-index: 99800; padding-left: 1px;'></i></a>";
  1009. // }
  1010. $html .= " </div>\n";
  1011. //main menu items
  1012. if (!empty($menu_array)) {
  1013. foreach ($menu_array as $menu_index_main => $menu_item_main) {
  1014. $menu_target = ($menu_item_main['menu_item_category'] == 'external') ? '_blank' : '';
  1015. $html .= " <a class='menu_side_item_main' ".(!empty($menu_item_main['menu_item_link']) ? "href='".$menu_item_main['menu_item_link']."' target='".$menu_target."'" : "onclick=\"menu_side_expand(); menu_side_item_toggle('".$menu_item_main['menu_item_uuid']."');\"")." title=\"".$menu_item_main['menu_language_title']."\">";
  1016. if (is_array($menu_item_main['menu_items']) && sizeof($menu_item_main['menu_items']) != 0 && $_SESSION['theme']['menu_side_item_main_sub_icons']['boolean'] == 'true') {
  1017. $html .= " <div class='menu_side_item_main_sub_icons' style='float: right; margin-right: -1px; ".($_SESSION['theme']['menu_side_state']['text'] != 'expanded' ? "display: none;" : null)."'><i id='sub_arrow_".$menu_item_main['menu_item_uuid']."' class='sub_arrows fas fa-".(!empty($_SESSION['theme']['menu_side_item_main_sub_icon_expand']['text']) ? $_SESSION['theme']['menu_side_item_main_sub_icon_expand']['text'] : 'chevron-down')." fa-xs'></i></div>\n";
  1018. }
  1019. if (!empty($menu_item_main['menu_item_icon'])) {
  1020. $html .= "<i class='menu_side_item_icon fas ".$menu_item_main['menu_item_icon']." fa-fw' style='z-index: 99800; margin-right: 8px;'></i>";
  1021. }
  1022. $html .= "<span class='menu_side_item_title' ".($_SESSION['theme']['menu_side_state']['text'] != 'expanded' ? "style='display: none;'" : null).">".$menu_item_main['menu_language_title']."</span>";
  1023. $html .= "</a>\n";
  1024. //sub menu items
  1025. if (is_array($menu_item_main['menu_items']) && sizeof($menu_item_main['menu_items']) != 0) {
  1026. $html .= " <div id='sub_".$menu_item_main['menu_item_uuid']."' class='menu_side_sub' style='display: none;'>\n";
  1027. foreach ($menu_item_main['menu_items'] as $menu_index_sub => $menu_item_sub) {
  1028. $html .= " <a class='menu_side_item_sub' ".($menu_item_sub['menu_item_category'] == 'external' ? "target='_blank'" : null)." href='".$menu_item_sub['menu_item_link']."'>";
  1029. $html .= "<span class='menu_side_item_title' ".($_SESSION['theme']['menu_side_state']['text'] != 'expanded' ? "style='display: none;'" : null).">".$menu_item_sub['menu_language_title']."</span>";
  1030. $html .= "</a>\n";
  1031. }
  1032. $html .= " </div>\n";
  1033. }
  1034. }
  1035. $html .= " <div style='height: 100px;'></div>\n";
  1036. }
  1037. $html .= "</div>\n";
  1038. if ($_SESSION['theme']['menu_side_state']['text'] != 'expanded' && $_SESSION['theme']['menu_side_state']['text'] != 'hidden') {
  1039. $content_container_onclick = "onclick=\"clearTimeout(menu_side_contract_timer); if ($(window).width() >= 576) { menu_side_contract(); }\"";
  1040. }
  1041. $html .= "<div id='content_container' ".$content_container_onclick.">\n";
  1042. $html .= " <div id='body_header'>\n";
  1043. //header: left
  1044. $html .= "<div class='float-left'>\n";
  1045. $html .= button::create(['type'=>'button','id'=>'menu_side_state_hidden_button','title'=>$this->text['theme-label-expand_menu'],'icon'=>'bars','class'=>'default '.($_SESSION['theme']['menu_side_state']['text'] != 'hidden' ? 'hide-sm-up ' : null).'float-left','onclick'=>'menu_side_expand();']);
  1046. $body_header_brand_text = !empty($_SESSION['theme']['body_header_brand_text']['text']) ? escape($_SESSION['theme']['body_header_brand_text']['text']) : "FusionPBX";
  1047. if ($_SESSION['theme']['body_header_brand_type']['text'] == 'image' || $_SESSION['theme']['body_header_brand_type']['text'] == 'image_text') {
  1048. $body_header_brand_image = !empty($_SESSION['theme']['body_header_brand_image']['text']) ? $_SESSION['theme']['body_header_brand_image']['text'] : PROJECT_PATH."/themes/default/images/logo_side_expanded.png";
  1049. $html .= "<div id='body_header_brand_image'>";
  1050. $html .= "<a href='".PROJECT_PATH."/'><img id='body_header_brand_image' src='".escape($body_header_brand_image)."' title=\"".escape($body_header_brand_text)."\"></a>";
  1051. $html .= "</div>";
  1052. }
  1053. if ($_SESSION['theme']['body_header_brand_type']['text'] == 'text' || $_SESSION['theme']['body_header_brand_type']['text'] == 'image_text') {
  1054. $html .= "<div id='body_header_brand_text'><a href='".PROJECT_PATH."/'>".$body_header_brand_text."</a></div>";
  1055. }
  1056. $html .= "</div>\n";
  1057. //header: right
  1058. $html .= "<div class='float-right' style='white-space: nowrap;'>";
  1059. //current user
  1060. $html .= "<span style='display: inline-block; padding-right: 20px; font-size: 90%;'>\n";
  1061. $html .= " <a href='".PROJECT_PATH."/core/users/user_edit.php?id=user' title=\"".$this->text['theme-label-user']."\"><i class='fas fa-".($_SESSION['theme']['body_header_icon_user']['text'] != '' ? $_SESSION['theme']['body_header_icon_user']['text'] : 'user-circle')." fa-lg fa-fw' style='margin-top: 6px; margin-right: 5px;'></i>".$_SESSION['username']."</a>";
  1062. $html .= "</span>\n";
  1063. //domain name/selector (sm+)
  1064. if (!empty($_SESSION['username']) && permission_exists('domain_select') && count($_SESSION['domains']) > 1 && $_SESSION['theme']['domain_visible']['text'] == 'true') {
  1065. $html .= "<span style='display: inline-block; padding-right: 10px; font-size: 90%;'>\n";
  1066. $html .= " <a href='#' id='header_domain_selector_domain' title='".$this->text['theme-label-open_selector']."'><i class='fas fa-".($_SESSION['theme']['body_header_icon_domain']['text'] != '' ? $_SESSION['theme']['body_header_icon_domain']['text'] : 'globe-americas')." fa-lg fa-fw' style='margin-top: 6px; margin-right: 5px;'></i>".escape($_SESSION['domain_name'])."</a>";
  1067. $html .= "</span>\n";
  1068. }
  1069. //logout icon
  1070. if (!empty($_SESSION['username']) && $_SESSION['theme']['logout_icon_visible']['text'] == "true") {
  1071. $html .= "<a id='header_logout_icon' href='#' title=\"".$this->text['theme-label-logout']."\" onclick=\"modal_open('modal-logout','btn_logout');\"><span class='fas fa-sign-out-alt'></span></a>";
  1072. }
  1073. $html .= "</div>";
  1074. $html .= " </div>\n";
  1075. //modal for logout icon (above)
  1076. if (!empty($_SESSION['username']) && $_SESSION['theme']['logout_icon_visible']['text'] == "true") {
  1077. $html .= modal::create(['id'=>'modal-logout','type'=>'general','message'=>$this->text['theme-confirm-logout'],'actions'=>button::create(['type'=>'button','label'=>$this->text['theme-label-logout'],'icon'=>'sign-out-alt','id'=>'btn_logout','style'=>'float: right; margin-left: 15px;','collapse'=>'never','link'=>PROJECT_PATH.'/logout.php','onclick'=>"modal_close();"])]);
  1078. }
  1079. return $html;
  1080. unset($html);
  1081. }
  1082. }
  1083. }
  1084. ?>