index.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  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. Portions created by the Initial Developer are Copyright (C) 2008-2019
  17. the Initial Developer. All Rights Reserved.
  18. Contributor(s):
  19. Mark J Crane <[email protected]>
  20. James Rose <[email protected]>
  21. */
  22. //set the include path
  23. $conf = glob("{/usr/local/etc,/etc}/fusionpbx/config.conf", GLOB_BRACE);
  24. set_include_path(parse_ini_file($conf[0])['document.root']);
  25. //includes fileshp";
  26. require_once "resources/require.php";
  27. require_once "resources/check_auth.php";
  28. //check permissions
  29. if (permission_exists('edit_view')) {
  30. //access granted
  31. }
  32. else {
  33. echo "access denied";
  34. exit;
  35. }
  36. //add multi-lingual support
  37. $language = new text;
  38. $text = $language->get();
  39. //set the directory title and mode
  40. $_SESSION["app"]["edit"]["dir"] = $_GET["dir"];
  41. $title = escape($_GET["dir"]);
  42. unset($mode);
  43. switch ($_GET["dir"]) {
  44. case 'xml':
  45. $title = 'XML';
  46. $mode = 'xml';
  47. break;
  48. case 'provision':
  49. $title = 'Provision';
  50. $mode = 'xml';
  51. break;
  52. case 'php':
  53. $title = 'PHP';
  54. $mode = 'php';
  55. break;
  56. case 'scripts':
  57. $title = 'Scripts';
  58. $mode = 'lua';
  59. break;
  60. case 'grammar':
  61. $title = 'Grammar';
  62. $mode = 'xml';
  63. default: $mode = 'text';
  64. }
  65. //load editor preferences/defaults
  66. $setting_size = !empty($_SESSION["editor"]["font_size"]["text"]) ? $_SESSION["editor"]["font_size"]["text"] : '12px';
  67. $setting_theme = !empty($_SESSION["editor"]["theme"]["text"]) ? $_SESSION["editor"]["theme"]["text"] : 'cobalt';
  68. $setting_invisibles = !empty($_SESSION["editor"]["invisibles"]["boolean"]) ? $_SESSION["editor"]["invisibles"]["boolean"] : 'false';
  69. $setting_indenting = !empty($_SESSION["editor"]["indent_guides"]["boolean"]) ? $_SESSION["editor"]["indent_guides"]["boolean"] : 'false';
  70. $setting_numbering = !empty($_SESSION["editor"]["line_numbers"]["boolean"]) ? $_SESSION["editor"]["line_numbers"]["boolean"] : 'true';
  71. //get and then set the favicon
  72. if (isset($_SESSION['theme']['favicon']['text'])){
  73. $favicon = $_SESSION['theme']['favicon']['text'];
  74. }
  75. else {
  76. $favicon = $PROJECT_ROOT .'/themes/default/favicon.ico';
  77. }
  78. //create a token
  79. $key_name = '/app/edit/'.$mode;
  80. $_SESSION['keys'][$key_name] = bin2hex(random_bytes(32));
  81. $_SESSION['token'] = hash_hmac('sha256', $key_name, $_SESSION['keys'][$key_name]);
  82. //generate the captcha image
  83. $_SESSION['captcha'] = generate_password(7, 2);
  84. $captcha = new captcha;
  85. $captcha->code = $_SESSION['captcha'];
  86. $image_base64 = $captcha->image_base64();
  87. ?>
  88. <html>
  89. <head>
  90. <meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
  91. <title><?php echo $title; ?></title>
  92. <link rel="icon" type="image/x-icon" href="<?php echo $favicon; ?>">
  93. <script language="JavaScript" type="text/javascript" src="<?php echo PROJECT_PATH; ?>/resources/jquery/jquery-3.6.1.min.js"></script>
  94. <script src='https://code.jquery.com/jquery-migrate-3.1.0.js'></script>
  95. <script language="JavaScript" type="text/javascript">
  96. function submit_check() {
  97. if (document.getElementById('filepath').value != '') {
  98. document.getElementById('editor_source').value = editor.getSession().getValue();
  99. return true;
  100. }
  101. focus_editor();
  102. return false;
  103. }
  104. function toggle_option(opt) {
  105. switch (opt) {
  106. case 'numbering': toggle_option_do('showLineNumbers'); toggle_option_do('fadeFoldWidgets'); break;
  107. case 'invisibles': toggle_option_do('showInvisibles'); break;
  108. case 'indenting': toggle_option_do('displayIndentGuides'); break;
  109. }
  110. focus_editor();
  111. }
  112. function toggle_option_do(opt_name) {
  113. var opt_val = editor.getOption(opt_name);
  114. editor.setOption(opt_name, ((opt_val) ? false : true));
  115. }
  116. function toggle_sidebar() {
  117. var td_sidebar = document.getElementById('sidebar');
  118. td_sidebar.style.display = (td_sidebar.style.display == '') ? 'none' : '';
  119. focus_editor();
  120. }
  121. function insert_clip(before, after) {
  122. var selected_text = editor.session.getTextRange(editor.getSelectionRange());
  123. editor.insert(before + selected_text + after);
  124. focus_editor();
  125. }
  126. function focus_editor() {
  127. editor.focus();
  128. }
  129. function http_request(url, form_data) {
  130. var http = new XMLHttpRequest();
  131. http.open('POST', url, true);
  132. //http.onload = function(e) { ... };
  133. http.onload = function(e) {
  134. if (this.status == 200) {
  135. //data sent successfully
  136. alert(this.responseText);
  137. }
  138. else {
  139. alert('<?php echo $text['message-problem']; ?>');
  140. }
  141. };
  142. http.send(form_data);
  143. }
  144. function save() {
  145. var form_data = new FormData();
  146. form_data.append('filepath', document.getElementById('filepath').value);
  147. form_data.append('content', editor.getSession().getValue());
  148. form_data.append('token',document.getElementById('token').value);
  149. form_data.append('mode',"<?php echo $mode; ?>");
  150. http_request('file_save.php', form_data);
  151. }
  152. </script>
  153. <style>
  154. img.control {
  155. cursor: pointer;
  156. width: auto;
  157. height: 23px;
  158. border: none;
  159. opacity: 0.5;
  160. }
  161. img.control:hover {
  162. opacity: 1.0;
  163. }
  164. div#editor {
  165. box-shadow: 0 5px 15px #333;
  166. }
  167. </style>
  168. </head>
  169. <body style='padding: 0; margin: 0; overflow: hidden;'>
  170. <table id='frame' cellpadding='0' cellspacing='0' border='0' style="height: 100%; width: 100%;">
  171. <tr>
  172. <td id='sidebar' valign='top' style="width: 300px; height: 100%;">
  173. <iframe id='file_list' src='file_list.php' style='border: none; height: 65%; width: 100%;'></iframe><br>
  174. <iframe id='clip_list' src='clip_list.php' style='border: none; border-top: 1px solid #ccc; height: calc(35% - 1px); width: 100%;'></iframe>
  175. </td>
  176. <td align='right' valign='top' style='height: 100%;'>
  177. <form style='margin: 0;' name='frm_edit' id='frm_edit' method='post' action='file_save.php' onsubmit="return submit_check();">
  178. <textarea name='content' id='editor_source' style='display: none;'></textarea>
  179. <input type='hidden' name='filepath' id='filepath' value=''>
  180. <input type='hidden' name='token' id='token' value='<?php echo $_SESSION['token']; ?>'>
  181. <table cellpadding='0' cellspacing='0' border='0' style='width: 100%;'>
  182. <tr>
  183. <td valign='middle'><img src='resources/images/icon_save.png' title='Save Changes [Ctrl+S]' class='control' onclick="save();";></td>
  184. <td align='left' valign='middle' width='100%' style='padding: 0 15px 0 6px;'><input id='current_file' type='text' style='height: 23px; width: 100%;'></td>
  185. <!--
  186. <td style='padding: 0;'><img src="data:image/png;base64, <?php echo $image_base64; ?>" /></td>
  187. <td align='left' valign='middle' width='80' style='padding: 0 6px 0 0;'><input type='text' class='txt' style='width: 80px; text-align: center;' name='code' id='code' value='' placeholder='CAPTCHA'></td>
  188. -->
  189. <td style='padding: 0;'><img src='resources/images/blank.gif' style='width: 1px; height: 40px; border: none;'></td>
  190. <td valign='middle' style='padding-left: 6px;'><img src='resources/images/icon_sidebar.png' title='Toggle Side Bar [Ctrl+Q]' class='control' onclick="toggle_sidebar();"></td>
  191. <td valign='middle' style='padding-left: 6px;'><img src='resources/images/icon_numbering.png' title='Toggle Line Numbers' class='control' onclick="toggle_option('numbering');"></td>
  192. <td valign='middle' style='padding-left: 6px;'><img src='resources/images/icon_invisibles.png' title='Toggle Invisibles' class='control' onclick="toggle_option('invisibles');"></td>
  193. <td valign='middle' style='padding-left: 6px;'><img src='resources/images/icon_indenting.png' title='Toggle Indent Guides' class='control' onclick="toggle_option('indenting');"></td>
  194. <td valign='middle' style='padding-left: 6px;'><img src='resources/images/icon_replace.png' title='Show Find/Replace [Ctrl+H]' class='control' onclick="editor.execCommand('replace');"></td>
  195. <td valign='middle' style='padding-left: 6px;'><img src='resources/images/icon_goto.png' title='Show Go To Line' class='control' onclick="editor.execCommand('gotoline');"></td>
  196. <td valign='middle' style='padding-left: 10px;'>
  197. <select id='mode' style='height: 23px; max-width: 70px;' onchange="editor.getSession().setMode('ace/mode/' + this.options[this.selectedIndex].value); focus_editor();">
  198. <?php
  199. $modes['php'] = 'PHP';
  200. $modes['css'] = 'CSS';
  201. $modes['html'] = 'HTML';
  202. $modes['javascript'] = 'JS';
  203. $modes['json'] = 'JSON';
  204. $modes['ini'] = 'Conf';
  205. $modes['lua'] = 'Lua';
  206. $modes['text'] = 'Text';
  207. $modes['xml'] = 'XML';
  208. $modes['sql'] = 'SQL';
  209. $modes['sh'] = 'SH';
  210. $modes['smarty'] = 'Smarty';
  211. $modes['svg'] = 'SVG';
  212. $modes['makefile'] = 'Makefile';
  213. $modes['c_cpp'] = 'C';
  214. $modes['c_cpp'] = 'CPP';
  215. $modes['pgsql'] = 'PGSQL';
  216. foreach ($modes as $value => $label) {
  217. $selected = ($value == $mode) ? 'selected' : null;
  218. echo "<option value='".$value."' ".$selected.">".$label."</option>\n";
  219. }
  220. ?>
  221. </select>
  222. </td>
  223. <td valign='middle' style='padding-left: 4px;'>
  224. <select id='size' style='height: 23px;' onchange="document.getElementById('editor').style.fontSize = this.options[this.selectedIndex].value; focus_editor();">
  225. <?php
  226. $sizes = explode(',','9px,10px,11px,12px,14px,16px,18px,20px');
  227. if (!in_array($setting_size, $sizes)) {
  228. echo "<option value='".$setting_size."'>".$setting_size."</option>\n";
  229. echo "<option value='' disabled='disabled'></option>\n";
  230. }
  231. foreach ($sizes as $size) {
  232. $selected = ($size == $setting_size) ? 'selected' : null;
  233. echo "<option value='".$size."' ".$selected.">".$size."</option>\n";
  234. }
  235. ?>
  236. </select>
  237. </td>
  238. <td valign='middle' style='padding-left: 4px; padding-right: 4px;'>
  239. <select id='theme' style='height: 23px; max-width: 100px;' onchange="editor.setTheme('ace/theme/' + this.options[this.selectedIndex].value); focus_editor();">
  240. <?php
  241. $themes['Bright']['chrome']= 'Chrome';
  242. $themes['Bright']['clouds']= 'Clouds';
  243. $themes['Bright']['crimson_editor']= 'Crimson Editor';
  244. $themes['Bright']['dawn']= 'Dawn';
  245. $themes['Bright']['dreamweaver']= 'Dreamweaver';
  246. $themes['Bright']['eclipse']= 'Eclipse';
  247. $themes['Bright']['github']= 'GitHub';
  248. $themes['Bright']['iplastic']= 'IPlastic';
  249. $themes['Bright']['solarized_light']= 'Solarized Light';
  250. $themes['Bright']['textmate']= 'TextMate';
  251. $themes['Bright']['tomorrow']= 'Tomorrow';
  252. $themes['Bright']['xcode']= 'XCode';
  253. $themes['Bright']['kuroir']= 'Kuroir';
  254. $themes['Bright']['katzenmilch']= 'KatzenMilch';
  255. $themes['Bright']['sqlserver']= 'SQL Server';
  256. $themes['Dark']['ambiance']= 'Ambiance';
  257. $themes['Dark']['chaos']= 'Chaos';
  258. $themes['Dark']['clouds_midnight']= 'Clouds Midnight';
  259. $themes['Dark']['cobalt']= 'Cobalt';
  260. $themes['Dark']['idle_fingers']= 'idle Fingers';
  261. $themes['Dark']['kr_theme']= 'krTheme';
  262. $themes['Dark']['merbivore']= 'Merbivore';
  263. $themes['Dark']['merbivore_soft']= 'Merbivore Soft';
  264. $themes['Dark']['mono_industrial']= 'Mono Industrial';
  265. $themes['Dark']['monokai']= 'Monokai';
  266. $themes['Dark']['pastel_on_dark']= 'Pastel on dark';
  267. $themes['Dark']['solarized_dark']= 'Solarized Dark';
  268. $themes['Dark']['terminal']= 'Terminal';
  269. $themes['Dark']['tomorrow_night']= 'Tomorrow Night';
  270. $themes['Dark']['tomorrow_night_blue']= 'Tomorrow Night Blue';
  271. $themes['Dark']['tomorrow_night_bright']= 'Tomorrow Night Bright';
  272. $themes['Dark']['tomorrow_night_eighties']= 'Tomorrow Night 80s';
  273. $themes['Dark']['twilight']= 'Twilight';
  274. $themes['Dark']['vibrant_ink']= 'Vibrant Ink';
  275. foreach ($themes as $optgroup => $theme) {
  276. echo "<optgroup label='".$optgroup."'>\n";
  277. foreach ($theme as $value => $label) {
  278. $selected = (strtolower($label) == strtolower($setting_theme)) ? 'selected' : null;
  279. echo "<option value='".$value."' ".$selected.">".$label."</option>\n";
  280. }
  281. echo "</optgroup>\n";
  282. }
  283. ?>
  284. </select>
  285. </td>
  286. </tr>
  287. </table>
  288. </form>
  289. <div id='editor' style="text-align: left; width: 100%; height: calc(100% - 30px); font-size: 12px;"></div>
  290. </td>
  291. </tr>
  292. </table>
  293. <script type="text/javascript" src="<?php echo PROJECT_PATH; ?>/resources/ace/ace.js" charset="utf-8"></script>
  294. <script type="text/javascript">
  295. //load ace editor
  296. var editor = ace.edit("editor");
  297. editor.setOptions({
  298. mode: 'ace/mode/<?php echo $mode;?>',
  299. theme: 'ace/theme/'+document.getElementById('theme').options[document.getElementById('theme').selectedIndex].value,
  300. selectionStyle: 'text',
  301. cursorStyle: 'smooth',
  302. showInvisibles: <?php echo $setting_invisibles;?>,
  303. displayIndentGuides: <?php echo $setting_indenting;?>,
  304. showLineNumbers: <?php echo $setting_numbering;?>,
  305. showGutter: true,
  306. scrollPastEnd: true,
  307. fadeFoldWidgets: <?php echo $setting_numbering;?>,
  308. showPrintMargin: false,
  309. highlightGutterLine: false,
  310. useSoftTabs: false
  311. });
  312. document.getElementById('editor').style.fontSize='<?php echo $setting_size;?>';
  313. focus_editor();
  314. //prevent form submit with enter key on file path input
  315. <?php key_press('enter', 'down', '#current_file', null, null, 'return false;', false); ?>
  316. //save file
  317. <?php key_press('ctrl+s', 'down', 'window', null, null, "save(); return false;", false); ?>
  318. //open file manager/clip library pane
  319. <?php key_press('ctrl+q', 'down', 'window', null, null, 'toggle_sidebar(); focus_editor(); return false;', false); ?>
  320. //remove certain keyboard shortcuts
  321. editor.commands.bindKey("Ctrl-T", null); //new browser tab
  322. </script>
  323. </body>
  324. </html>