api.devconsole.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. <?php
  2. /**
  3. * Developers console implementation
  4. */
  5. class DevConsole {
  6. /**
  7. * Contains alter config a key=>value
  8. */
  9. protected $altCfg = array();
  10. /**
  11. * Protected OnePunch scripts object instance
  12. *
  13. * @var object
  14. */
  15. protected $onePunch = '';
  16. /**
  17. * Some predefined stuff like routes here
  18. */
  19. const URL_ME = '?module=sqlconsole';
  20. const URL_DEVCON = '?module=sqlconsole&devconsole=true';
  21. const OPTION_KEEP = 'DEVCON_SQL_KEEP';
  22. const OPTION_DEBUG = 'DEVCON_VERBOSE_DEBUG';
  23. const ROUTE_PHP_CON = 'devconsole';
  24. const ROUTE_OP_RUN = 'runscript';
  25. const ROUTE_OP_CREATE = 'scriptadd';
  26. const ROUTE_OP_DELETE = 'delscript';
  27. const ROUTE_OP_EDIT = 'editscript';
  28. const ROUTE_OP_IMPORT = 'importoldcodetemplates';
  29. /**
  30. * forms inputs post-routes here
  31. */
  32. const PROUTE_SQL = 'sqlq';
  33. const PROUTE_PHP = 'phpq';
  34. const PROUTE_OPN_NAME = 'newscriptname';
  35. const PROUTE_OPN_ALIAS = 'newscriptalias';
  36. const PROUTE_OPN_CONTENT = 'newscriptcontent';
  37. const PROUTE_OPE_ID = 'editscriptid';
  38. const PROUTE_OPE_OLDALIAS = 'editscriptoldalias';
  39. const PROUTE_OPE_NAME = 'editscriptname';
  40. const PROUTE_OPE_ALIAS = 'editscriptalias';
  41. const PROUTE_OPE_CONTENT = 'editscriptcontent';
  42. const PROUTE_HLIGHT = 'phphightlight';
  43. const PROUTE_TABLE = 'tableresult';
  44. const PROUTE_TRUETABLE = 'truetableresult';
  45. /**
  46. * Plagued by doubt that it can be done
  47. * In a culture so committed to temporal pleasure and distraction
  48. * Should I flee into lifelong mountain retreat?
  49. */
  50. public function __construct() {
  51. $this->loadConfigs();
  52. if (ubRouting::checkGet(self::ROUTE_PHP_CON)) {
  53. $this->initOnePunch();
  54. }
  55. }
  56. /**
  57. * Loads required configs data
  58. *
  59. * @return void
  60. */
  61. protected function loadConfigs() {
  62. global $ubillingConfig;
  63. $this->altCfg = $ubillingConfig->getAlter();
  64. }
  65. /**
  66. * Initializes the OnePunch object
  67. *
  68. * @return void
  69. */
  70. protected function initOnePunch() {
  71. $this->onePunch = new OnePunch();
  72. }
  73. /**
  74. * Renders the controls for the developers console
  75. *
  76. * @return string
  77. */
  78. protected function renderControls() {
  79. $result = '';
  80. $migrationControls = '';
  81. $result .= wf_Link(self::URL_ME, wf_img('skins/icon_restoredb.png') . ' ' . __('SQL Console'), false, 'ubButton');
  82. $result .= wf_Link(self::URL_ME . '&' . self::ROUTE_PHP_CON . '=true', wf_img('skins/icon_php.png') . ' ' . __('PHP Console'), false, 'ubButton');
  83. if (cfr('ROOT')) {
  84. $migrationControls .= wf_Link("?module=migration", wf_img('skins/icon_puzzle.png') . ' ' . __('Migration'), false, 'ubButton');
  85. $migrationControls .= wf_Link("?module=migration2", wf_img('skins/icon_puzzle.png') . ' ' . __('Migration') . ' 2', false, 'ubButton');
  86. $migrationControls .= wf_Link("?module=migration2_exten", wf_img('skins/icon_puzzle.png') . ' ' . __('Migration live (occupancy & tags)'), false, 'ubButton');
  87. $migrationControls .= wf_Link("?module=migration2_ukv", wf_img('skins/icon_puzzle.png') . ' ' . __('Migration') . ' 2 UKV', false, 'ubButton');
  88. }
  89. if (cfr('MIKMIGR')) {
  90. $migrationControls .= wf_Link("?module=mikbill_migration", wf_img('skins/ukv/dollar.png') . ' ' . __('Migration') . ' MikBiLL', false, 'ubButton');
  91. }
  92. $result .= wf_modalAuto(wf_img('skins/icon_puzzle.png') . ' ' . __('Migration'), __('Migration'), $migrationControls, 'ubButton');
  93. $result .= wf_tag('br');
  94. return ($result);
  95. }
  96. /**
  97. * Renders the SQL console form
  98. *
  99. * This method generates the HTML form for the SQL console, including input fields for the SQL query,
  100. * and options for displaying the query result as a table
  101. *
  102. * @return string
  103. */
  104. public function renderSqlForm() {
  105. $startQuery = '';
  106. $result = '';
  107. $sqlinputs = $this->renderControls();
  108. $tableResultFlag = (ubRouting::checkPost(self::PROUTE_TABLE)) ? true : false;
  109. $trueTableResultFlag = (ubRouting::checkPost(self::PROUTE_TRUETABLE)) ? true : false;
  110. if (ubRouting::checkPost(self::PROUTE_SQL)) {
  111. if ($this->altCfg[self::OPTION_KEEP]) {
  112. $startQuery = ubRouting::post(self::PROUTE_SQL, 'callback', 'trim');
  113. }
  114. }
  115. $sqlinputs .= wf_TextArea(self::PROUTE_SQL, '', $startQuery, true, '80x10');
  116. $sqlinputs .= wf_CheckInput(self::PROUTE_TABLE, 'Display query result as table', true, $tableResultFlag);
  117. $sqlinputs .= wf_CheckInput(self::PROUTE_TRUETABLE, 'Display query result as table with fields', true, $trueTableResultFlag);
  118. $sqlinputs .= wf_Submit('Process query');
  119. $result = wf_Form('', 'POST', $sqlinputs, 'glamour');
  120. return ($result);
  121. }
  122. /**
  123. * Renders the PHP form for the dev console.
  124. *
  125. * This method generates the HTML code for the PHP form in the dev console.
  126. * It includes the necessary inputs, such as text areas and checkboxes, for
  127. * running and highlighting PHP code.
  128. *
  129. * @return string
  130. */
  131. public function renderPhpForm() {
  132. $result = '';
  133. $runCode = '';
  134. $phpinputs = $this->renderControls();
  135. $phphightlightFlag = (ubRouting::checkPost(self::PROUTE_HLIGHT)) ? true : false;
  136. //is this template run or clear area?
  137. if (ubRouting::checkGet(self::ROUTE_OP_RUN)) {
  138. $this->initOnePunch();
  139. $runCode = htmlentities($this->onePunch->getScriptContent(ubRouting::get(self::ROUTE_OP_RUN)), ENT_COMPAT, "UTF-8");
  140. } else {
  141. if ($this->altCfg[self::OPTION_KEEP]) {
  142. if (ubRouting::checkPost(self::PROUTE_PHP)) {
  143. $runCode = ubRouting::post(self::PROUTE_PHP);
  144. }
  145. }
  146. }
  147. $phpinputs .= wf_TextArea(self::PROUTE_PHP, '', $runCode, true, '80x10');
  148. $phpinputs .= wf_CheckInput(self::PROUTE_HLIGHT, 'Hightlight this PHP code', true, $phphightlightFlag);
  149. $phpinputs .= wf_Submit('Run this code inside framework');
  150. $result .= wf_Form(self::URL_DEVCON, 'POST', $phpinputs, 'glamour');
  151. return ($result);
  152. }
  153. /**
  154. * Renders the PHP interfaces grid for the dev console.
  155. *
  156. * @return string
  157. */
  158. public function renderPhpInterfaces() {
  159. $result = '';
  160. $phpForm = $this->renderPhpForm();
  161. //php console grid assemble
  162. $phpcells = wf_TableCell($phpForm, '50%', '', 'valign="top"');
  163. if (ubRouting::checkGet(array(self::ROUTE_OP_CREATE))) {
  164. //show script creation form
  165. $punchCreateForm = $this->onePunch->renderCreateForm();
  166. //override devconsole forms with script creation interface
  167. $phpcells = wf_TableCell($punchCreateForm, '100%', '', 'valign="top"');
  168. } else {
  169. if (ubRouting::checkGet(self::ROUTE_OP_EDIT)) {
  170. //show scripts edit form
  171. $punchEditForm = $this->onePunch->renderEditForm($_GET['editscript']);
  172. //override devconsole forms with script editing interface
  173. $phpcells = wf_TableCell($punchEditForm, '100%', '', 'valign="top"');
  174. } else {
  175. //show scripts list
  176. $punchScriptsList = $this->onePunch->renderScriptsList();
  177. $punchScriptsList .= wf_tag('br');
  178. $punchScriptsList .= wf_Link(self::URL_DEVCON . '&scriptadd=true', web_icon_create() . ' ' . __('Create') . ' ' . __('One-Punch') . ' ' . __('Script'), true, 'ubButton');
  179. $phpcells .= wf_TableCell($punchScriptsList, '50%', '', 'valign="top"');
  180. }
  181. }
  182. $phprows = wf_TableRow($phpcells);
  183. $result .= wf_TableBody($phprows, '100%', '0', '');
  184. return ($result);
  185. }
  186. /**
  187. * Executes an SQL query and displays the result.
  188. *
  189. * This method checks if the SQL query is received through the POST request and then attempts to execute it.
  190. * If the query is not empty, it logs the query and starts buffering the output.
  191. * Depending on the PHP extension loaded (mysql or mysqli), it executes the query and fetches the result.
  192. * If the query execution fails, it returns an error message.
  193. * If the query execution is successful, it stores the query debug data and displays it if the corresponding option is enabled.
  194. * It then renders the query result based on the selected options: raw array result, table with fields, or table without fields.
  195. * Finally, it displays the query result, query status, and the number of returned records.
  196. *
  197. * @return void
  198. */
  199. public function executeSqlQuery() {
  200. //here we go?
  201. if (ubRouting::checkPost(self::PROUTE_SQL)) {
  202. if (!extension_loaded('mysql')) {
  203. global $loginDB; //that instance initialized outside
  204. }
  205. $newquery = ubRouting::post(self::PROUTE_SQL, 'callback', 'trim');
  206. $recCount = 0; //preventing notices on empty queries
  207. $vdump = ''; //used for storing query executing result
  208. $query_result = array(); //executed query result shall to be there
  209. //trying to execute received SQL query
  210. if (!empty($newquery)) {
  211. $stripquery = substr($newquery, 0, 70) . '..';
  212. log_register('SQLCONSOLE ' . $stripquery);
  213. ob_start();
  214. if (!extension_loaded('mysql')) {
  215. mysqli_report(0);
  216. $queried = mysqli_query($loginDB, $newquery);
  217. } else {
  218. $queried = mysql_query($newquery);
  219. }
  220. if ($queried === false) {
  221. ob_end_clean();
  222. return (show_error(wf_tag('b') . __('Wrong query') . ': ' . wf_tag('b', true) . $newquery));
  223. } else {
  224. if (!extension_loaded('mysql')) {
  225. mysqli_report(0);
  226. if ($queried !== true) {
  227. while (@$row = mysqli_fetch_assoc($queried)) {
  228. $query_result[] = $row;
  229. }
  230. }
  231. } else {
  232. while (@$row = mysql_fetch_assoc($queried)) {
  233. $query_result[] = $row;
  234. }
  235. }
  236. $sqlDebugData = ob_get_contents();
  237. ob_end_clean();
  238. log_register('SQLCONSOLE QUERYDONE');
  239. if ($this->altCfg[self::OPTION_DEBUG]) {
  240. show_window(__('Console debug data'), $sqlDebugData);
  241. }
  242. }
  243. // trying to render SQL query execution results depends on selected options
  244. if (!empty($query_result)) {
  245. $recCount = count($query_result);
  246. if (!ubRouting::checkPost(self::PROUTE_TABLE) and !ubRouting::checkPost(self::PROUTE_TRUETABLE)) {
  247. //raw array result
  248. $vdump = var_export($query_result, true);
  249. } elseif (ubRouting::checkPost(self::PROUTE_TRUETABLE)) {
  250. //show query result as table with fields
  251. $tablecells = '';
  252. $tablerows = '';
  253. $fieldNames = array_keys($query_result[0]);
  254. if (!empty($fieldNames)) {
  255. $fieldsCnt = count($fieldNames);
  256. foreach ($fieldNames as $fieldName) {
  257. $tablecells .= wf_TableCell($fieldName);
  258. }
  259. $tablerows .= $tablecells;
  260. $tablecells = '';
  261. foreach ($query_result as $eachresult) {
  262. for ($k = 0; $k < $fieldsCnt; $k++) {
  263. $tablecells .= wf_TableCell('');
  264. }
  265. $tablerows .= wf_TableRow($tablecells, 'row1');
  266. $tablecells = '';
  267. foreach ($eachresult as $io => $key) {
  268. $tablecells .= wf_TableCell($key);
  269. }
  270. $tablerows .= wf_TableRow($tablecells, 'row3');
  271. $tablecells = '';
  272. }
  273. }
  274. $vdump = wf_TableBody($tablerows, '100%', '0', '');
  275. } else {
  276. //show query result as table
  277. $tablerows = '';
  278. foreach ($query_result as $eachresult) {
  279. $tablecells = wf_TableCell('');
  280. $tablecells .= wf_TableCell('');
  281. $tablerows .= wf_TableRow($tablecells, 'row1');
  282. foreach ($eachresult as $io => $key) {
  283. $tablecells = wf_TableCell($io);
  284. $tablecells .= wf_TableCell($key);
  285. $tablerows .= wf_TableRow($tablecells, 'row3');
  286. }
  287. }
  288. $vdump = wf_TableBody($tablerows, '100%', '0', '');
  289. }
  290. }
  291. }
  292. //rendering records if available
  293. show_window(__('Result'), wf_tag('pre') . $vdump . wf_tag('pre', 'true'));
  294. //rendering query status here
  295. if (empty($newquery)) {
  296. show_warning(__('Empty query'));
  297. } else {
  298. if ($queried !== false) {
  299. show_info(__('SQL Query') . ': ' . $newquery);
  300. }
  301. if (empty($query_result)) {
  302. show_warning(__('Query returned empty result'));
  303. } else {
  304. show_success(__('Returned records count') . ': ' . $recCount);
  305. }
  306. }
  307. }
  308. }
  309. /**
  310. * Displays the debug data in the PHP console if enabled with option.
  311. *
  312. * @param string $debugData The debug data to be displayed.
  313. *
  314. * @return void
  315. */
  316. public function showDebugData($debugData) {
  317. if ($this->altCfg[self::OPTION_DEBUG]) {
  318. show_window(__('Console debug data'), wf_tag('pre') . $debugData) . wf_tag('pre', true);
  319. }
  320. }
  321. /**
  322. * Displays the highlighted PHP code in a window if the POST request matches the specified route.
  323. *
  324. * @param string $phpCode The PHP code to be highlighted and displayed.
  325. *
  326. * @return void
  327. */
  328. public function showCodeHighlight($phpCode) {
  329. if (ubRouting::checkPost(self::PROUTE_HLIGHT)) {
  330. $code = '<?php' . PHP_EOL . PHP_EOL;
  331. $code .= $phpCode . PHP_EOL . PHP_EOL;
  332. $code .= '?>';
  333. show_window(__('Running this'), highlight_string($code, true));
  334. }
  335. }
  336. }