PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/modules/main/admin/php_command_line.php

https://gitlab.com/alexprowars/bitrix
PHP | 476 lines | 418 code | 50 blank | 8 comment | 88 complexity | dfddc328b4b1717147ff5ecd15a6e28e MD5 | raw file
  1. <?
  2. /* This code captures parse errors*/
  3. register_shutdown_function('error_alert');
  4. function error_alert()
  5. {
  6. $arErrorType = array(
  7. E_ERROR => "Fatal error",
  8. E_PARSE => "Parse error",
  9. );
  10. $e = error_get_last();
  11. if(is_null($e) === false && isset($arErrorType[$e['type']]))
  12. {
  13. ob_end_clean();
  14. echo "<h2>".GetMessage("php_cmd_error")."&nbsp;</h2><p>";
  15. echo '<b>'.$arErrorType[$e['type']].'</b>: '.htmlspecialcharsbx($e['message']).' in <b>'.htmlspecialcharsbx($e['file']).'</b> on line <b>'.htmlspecialcharsbx($e['line']).'</b>';
  16. }
  17. else
  18. {
  19. global $DB;
  20. if(
  21. isset($DB)
  22. && is_object($DB)
  23. && $DB->GetErrorMessage() != ''
  24. )
  25. {
  26. ob_end_clean();
  27. echo "<h2>".GetMessage("php_cmd_error")."&nbsp;</h2><p>";
  28. echo '<font color=#ff0000>Query Error: '.htmlspecialcharsbx($DB->GetErrorSQL()).'</font> ['.htmlspecialcharsbx($DB->GetErrorMessage()).']';
  29. }
  30. }
  31. }
  32. function fancy_output($content)
  33. {
  34. if (isTextMode())
  35. {
  36. $flags = ENT_COMPAT;
  37. if (defined('ENT_SUBSTITUTE'))
  38. $flags |= ENT_SUBSTITUTE;
  39. else
  40. $flags |= ENT_IGNORE;
  41. return sprintf('<pre>%s</pre>', htmlspecialcharsbx($content, $flags));
  42. }
  43. return sprintf('<p>%s</e>', $content);
  44. }
  45. function isTextMode()
  46. {
  47. return (isset($_POST['result_as_text']) && $_POST['result_as_text'] === 'y');
  48. }
  49. require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_before.php");
  50. define("HELP_FILE", "utilities/php_command_line.php");
  51. /**
  52. * @global \CUser $USER
  53. * @global \CMain $APPLICATION
  54. **/
  55. if(!$USER->CanDoOperation('view_other_settings'))
  56. $APPLICATION->AuthForm(GetMessage("ACCESS_DENIED"));
  57. $isAdmin = $USER->CanDoOperation('edit_php');
  58. IncludeModuleLangFile(__FILE__);
  59. $remove = 0;
  60. if (isset($_REQUEST["remove"]) && preg_match('/^tab(\d+)$/', $_REQUEST["remove"], $match) && check_bitrix_sessid())
  61. {
  62. $remove = $match[1];
  63. }
  64. if (isset($_REQUEST["query_count"]) && $_REQUEST["query_count"] > 1 && check_bitrix_sessid())
  65. {
  66. $query_count = intval($_REQUEST["query_count"]);
  67. CUserOptions::SetOption("php_command_line", "count", $query_count);
  68. }
  69. $query_count = CUserOptions::GetOption("php_command_line", "count", 1);
  70. if ($query_count <= 1)
  71. $remove = 0;
  72. if (isset($_REQUEST["save"]) && check_bitrix_sessid())
  73. {
  74. CUtil::JSPostUnescape();
  75. require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_js.php");
  76. $i = 1;
  77. while (isset($_POST["query".$i]))
  78. {
  79. $saved = CUserOptions::GetOption("php_command_line", "query".$i, '');
  80. if ($saved !== $_POST["query".$i])
  81. {
  82. CUserOptions::SetOption("php_command_line", "query".$i, $_POST["query".$i]);
  83. }
  84. $i++;
  85. }
  86. while(CUserOptions::GetOption("php_command_line", "query".$i, '') <> '')
  87. {
  88. CUserOptions::DeleteOption("php_command_line", "query".$i);
  89. $i++;
  90. }
  91. echo "saved";
  92. require($_SERVER["DOCUMENT_ROOT"].BX_ROOT."/modules/main/include/epilog_admin_js.php");
  93. die();
  94. }
  95. if(
  96. $_SERVER['REQUEST_METHOD'] == 'POST'
  97. && $_POST["ajax"] === "y"
  98. && !isset($_POST["add"])
  99. && !$remove
  100. )
  101. {
  102. CUtil::JSPostUnescape();
  103. require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_js.php");
  104. if(
  105. $_POST['query'] <> ''
  106. && $isAdmin
  107. && check_bitrix_sessid()
  108. )
  109. {
  110. printf('<h2>%s</h2>', getMessage('php_cmd_result'));
  111. if (isTextMode())
  112. ini_set('html_errors', 0);
  113. ob_start('fancy_output');
  114. $query = rtrim($_POST['query'], ";\x20\n").";\n";
  115. $stime = microtime(1);
  116. eval($query);
  117. ob_end_flush();
  118. printf("<hr>".GetMessage("php_cmd_exec_time")." %0.6f", microtime(1) - $stime);
  119. }
  120. require($_SERVER["DOCUMENT_ROOT"].BX_ROOT."/modules/main/include/epilog_admin_js.php");
  121. die();
  122. }
  123. $APPLICATION->SetTitle(GetMessage("php_cmd_title"));
  124. CJSCore::Init(array('ls'));
  125. if(
  126. $_SERVER['REQUEST_METHOD'] == 'POST'
  127. && $_POST["ajax"] === "y"
  128. && (isset($_POST["add"]) || $remove)
  129. )
  130. {
  131. CUtil::JSPostUnescape();
  132. require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_js.php");
  133. }
  134. else
  135. {
  136. require($_SERVER["DOCUMENT_ROOT"].BX_ROOT."/modules/main/include/prolog_admin_after.php");
  137. }
  138. $aTabs = array();
  139. for ($i = 1; $i <= $query_count - ($remove? 1: 0); $i++)
  140. {
  141. $aTabs[] = array(
  142. "DIV" => "tab".$i,
  143. "TAB" => GetMessage("php_cmd_input")." (".$i.")",
  144. "TITLE" => GetMessage("php_cmd_php"),
  145. );
  146. }
  147. $aTabs[] = array(
  148. "DIV" => "tab_plus",
  149. "TAB" => '',
  150. "ONSELECT" => "AddNewTab();",
  151. );
  152. $editTab = new CAdminTabControl("editTab", $aTabs);
  153. ?>
  154. <script>
  155. var tabActionInProgress = false;
  156. function TabAction(action, param, showWait)
  157. {
  158. var firstTab = BX('tab_cont_tab1');
  159. if (!firstTab)
  160. return;
  161. tabActionInProgress = true;
  162. var data = {
  163. ajax: 'y'
  164. };
  165. data[action] = param;
  166. var lastIndex = 1;
  167. while (BX('tab_cont_tab' + lastIndex))
  168. {
  169. data['query' + lastIndex] = BX('query' + lastIndex).value;
  170. lastIndex++;
  171. }
  172. if (action == 'add')
  173. data['query_count'] = lastIndex;
  174. var selectedTab = BX('editTab_active_tab');
  175. if (action == 'add')
  176. data[selectedTab.name] = 'tab' + lastIndex;
  177. else
  178. data[selectedTab.name] = param;
  179. if (showWait)
  180. {
  181. ShowWaitWindow();
  182. }
  183. BX.ajax.post(
  184. 'php_command_line.php?lang=' + phpVars.LANGUAGE_ID + '&sessid=' + phpVars.bitrix_sessid, data,
  185. function(result){
  186. if (result && BX.util.trim(result) != 'saved')
  187. {
  188. document.getElementById('whole_form').innerHTML = result;
  189. queries = [];
  190. CloseWaitWindow();
  191. }
  192. tabActionInProgress = false;
  193. }
  194. );
  195. }
  196. function AddNewTab()
  197. {
  198. TabAction('add', 'y');
  199. }
  200. function RemoveTab(event)
  201. {
  202. if (event)
  203. {
  204. var tab = event.target.parentNode;
  205. var m = tab.id.match(/^tab_cont_(.+)$/);
  206. if (m)
  207. {
  208. TabAction('remove', m[1]);
  209. }
  210. }
  211. }
  212. var oldQueries = {};
  213. function saveQueries(firstRun)
  214. {
  215. var newQueries = {};
  216. var lastIndex = 1;
  217. while (BX('query' + lastIndex))
  218. {
  219. newQueries['query' + lastIndex] = BX('query' + lastIndex).value;
  220. lastIndex++;
  221. }
  222. if (firstRun)
  223. {
  224. oldQueries = newQueries;
  225. return;
  226. }
  227. if (!tabActionInProgress && !compareMaps(oldQueries, newQueries))
  228. {
  229. oldQueries = newQueries;
  230. TabAction('save', 'y', false);
  231. }
  232. }
  233. var queries = [];
  234. function adjustTabTitles()
  235. {
  236. var lastIndex = 1;
  237. while (BX('tab_cont_tab' + lastIndex))
  238. {
  239. var query = BX('query' + lastIndex).value;
  240. if (query != queries[lastIndex])
  241. {
  242. var m = query.match(/^\/\/title:\s*(.+)\n/);
  243. if (m)
  244. BX('tab_cont_tab' + lastIndex).innerHTML = BX.util.htmlspecialchars(m[1]);
  245. var close = BX.findChildren(BX('tab_cont_tab' + lastIndex), {className: 'adm-detail-tab-close'}, true);
  246. if (!close || close.length == 0)
  247. {
  248. var button = BX.create('SPAN', {props: {className: 'adm-detail-tab-close'}});
  249. BX('tab_cont_tab' + lastIndex).appendChild(button);
  250. BX.bind(button, 'click', RemoveTab);
  251. //BX.bind(BX('query' + lastIndex), "keyup", saveQueries);
  252. }
  253. }
  254. queries[lastIndex] = query;
  255. lastIndex++;
  256. }
  257. var plus = BX.findChildren(BX('tab_cont_tab_plus'), {className: 'adm-detail-tab-plus'}, true);
  258. if(!plus || plus.length == 0)
  259. {
  260. button = BX.create('SPAN', {props: {className: 'adm-detail-tab-plus'}});
  261. BX('tab_cont_tab_plus').appendChild(button);
  262. }
  263. }
  264. BX.ready(
  265. function init()
  266. {
  267. var resultAsText = BX.localStorage.get('result_as_text');
  268. BX('result_as_text').checked = resultAsText != 'n';
  269. saveQueries(true);
  270. adjustTabTitles();
  271. setInterval(function()
  272. {
  273. saveQueries();
  274. adjustTabTitles();
  275. }, 250);
  276. BX.addCustomEvent('OnAfterActionSelectionChanged', function()
  277. {
  278. saveQueries();
  279. adjustTabTitles();
  280. });
  281. }
  282. );
  283. function __FPHPRenderResult(result)
  284. {
  285. document.getElementById('result_div').innerHTML = result;
  286. CloseWaitWindow();
  287. }
  288. function __FPHPSubmit()
  289. {
  290. if(confirm('<?=GetMessageJS("php_cmd_confirm")?>'))
  291. {
  292. var resultAsText = BX('result_as_text').checked? 'y': 'n';
  293. if (resultAsText != BX.localStorage.get('result_as_text'))
  294. BX.localStorage.set('result_as_text', resultAsText, 31104000);
  295. var selectedTab = BX('editTab_active_tab');
  296. var m = selectedTab.value.match(/^tab(\d+)$/);
  297. window.scrollTo(0, 500);
  298. ShowWaitWindow();
  299. var data = BX.ajax.prepareData({
  300. query: BX('query' + m[1]).value,
  301. result_as_text: resultAsText,
  302. ajax: 'y'
  303. });
  304. BX.ajax({
  305. 'method': 'POST',
  306. 'dataType': 'html',
  307. 'url': 'php_command_line.php?lang=' + phpVars.LANGUAGE_ID + '&sessid=' + phpVars.bitrix_sessid,
  308. 'data': data,
  309. 'onsuccess': function (result) {
  310. __FPHPRenderResult(result);
  311. },
  312. 'onfailure': function (type, status, config) {
  313. __FPHPRenderResult(config.xhr.responseText);
  314. }
  315. });
  316. }
  317. }
  318. function __FPHPClear()
  319. {
  320. var selectedTab = BX('editTab_active_tab');
  321. var m = selectedTab.value.match(/^tab(\d+)$/);
  322. var textarea = BX('query' + m[1]);
  323. textarea.value = '';
  324. textarea.focus();
  325. }
  326. function compareMaps(map1, map2)
  327. {
  328. var testVal;
  329. if (map1.size !== map2.size)
  330. {
  331. return false;
  332. }
  333. for (key in map1)
  334. {
  335. if (map1.hasOwnProperty(key))
  336. {
  337. val = map1[key];
  338. testVal = map2[key];
  339. // in cases of an undefined value, make sure the key
  340. // actually exists on the object so there are no false positives
  341. if (testVal !== val || (testVal === undefined && !map2.hasOwnProperty(key)))
  342. {
  343. return false;
  344. }
  345. }
  346. }
  347. return true;
  348. }
  349. </script>
  350. <div id="whole_form">
  351. <?
  352. if(
  353. $_SERVER['REQUEST_METHOD'] == 'POST'
  354. && $_POST["ajax"] === "y"
  355. && (isset($_POST["add"]) || $remove)
  356. )
  357. {
  358. $APPLICATION->RestartBuffer();
  359. ?>
  360. <script>window.editTab = null;</script>
  361. <?
  362. }
  363. ?>
  364. <form name="form1" action="<?echo $APPLICATION->GetCurPage()?>?lang=<?=LANG?>" method="POST">
  365. <?
  366. $editTab->Begin();
  367. for ($i = 1; $i <= $query_count - ($remove? 1: 0); $i++)
  368. {
  369. $index = $remove? ($i >= $remove? $i + 1: $i): $i;
  370. if (isset($_REQUEST['query'.$index]))
  371. $query = $_REQUEST['query'.$index];
  372. else
  373. $query = CUserOptions::GetOption("php_command_line", "query".$index, '');
  374. $editTab->BeginNextTab();
  375. ?>
  376. <tr valign="top">
  377. <td width="100%" colspan="2">
  378. <textarea cols="60" name="query<?echo $i?>" id="query<?echo $i?>" rows="15" wrap="OFF" style="width:100%;"><?echo htmlspecialcharsbx($query); ?></textarea><br />
  379. <?
  380. if(COption::GetOptionString('fileman', "use_code_editor", "Y") == "Y" && CModule::IncludeModule('fileman'))
  381. {
  382. CCodeEditor::Show(array(
  383. 'textareaId' => 'query'.$i,
  384. 'height' => 350,
  385. 'forceSyntax' => 'php',
  386. ));
  387. }
  388. ?>
  389. </td>
  390. </tr>
  391. <?
  392. }
  393. ?>
  394. <?$editTab->Buttons();
  395. ?>
  396. <input<?if(!$isAdmin) echo " disabled"?> type="button" accesskey="x" name="execute" value="<?echo GetMessage("php_cmd_button")?>" onclick="return __FPHPSubmit();" class="adm-btn-save">
  397. <input type="button" value="<?echo GetMessage("php_cmd_button_clear")?>" onclick="this.form.reset(); __FPHPClear();">
  398. <input type="checkbox" value="Y" name="result_as_text" id="result_as_text">
  399. <label for="result_as_text"><?=GetMessage("php_cmd_text_result")?></label>
  400. <?
  401. $editTab->End();
  402. ?>
  403. </form>
  404. <?
  405. if(
  406. $_SERVER['REQUEST_METHOD'] == 'POST'
  407. && $_POST["ajax"] === "y"
  408. && (isset($_POST["add"]) || $remove)
  409. )
  410. {
  411. if ($remove)
  412. {
  413. CUserOptions::SetOption("php_command_line", "count", $query_count - 1);
  414. }
  415. ?><script>adjustTabTitles();</script><?
  416. require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_admin_js.php");
  417. }
  418. else
  419. {
  420. ?>
  421. </div>
  422. <div id="result_div"></div>
  423. <?echo BeginNote(), GetMessage("php_cmd_note"), EndNote();?>
  424. <?
  425. require($_SERVER["DOCUMENT_ROOT"].BX_ROOT."/modules/main/include/epilog_admin.php");
  426. }