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

/pma/libraries/display_tbl.lib.php

https://bitbucket.org/StasPiv/playzone
PHP | 2316 lines | 1527 code | 238 blank | 551 comment | 622 complexity | b74bfdb4cbd90be77285bdfcee93f5db MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-2.0, LGPL-2.1
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * library for displaying table with results from all sort of select queries
  5. *
  6. * @version $Id: display_tbl.lib.php 12390 2009-05-04 16:05:24Z lem9 $
  7. * @package phpMyAdmin
  8. */
  9. /**
  10. *
  11. */
  12. require_once './libraries/Table.class.php';
  13. require_once './libraries/Index.class.php';
  14. /**
  15. * Defines the display mode to use for the results of a SQL query
  16. *
  17. * It uses a synthetic string that contains all the required informations.
  18. * In this string:
  19. * - the first two characters stand for the action to do while
  20. * clicking on the "edit" link (e.g. 'ur' for update a row, 'nn' for no
  21. * edit link...);
  22. * - the next two characters stand for the action to do while
  23. * clicking on the "delete" link (e.g. 'kp' for kill a process, 'nn' for
  24. * no delete link...);
  25. * - the next characters are boolean values (1/0) and respectively stand
  26. * for sorting links, navigation bar, "insert a new row" link, the
  27. * bookmark feature, the expand/collapse text/blob fields button and
  28. * the "display printable view" option.
  29. * Of course '0'/'1' means the feature won't/will be enabled.
  30. *
  31. * @param string the synthetic value for display_mode (see a few
  32. * lines above for explanations)
  33. * @param integer the total number of rows returned by the SQL query
  34. * without any programmatically appended "LIMIT" clause
  35. * (just a copy of $unlim_num_rows if it exists, else
  36. * computed inside this function)
  37. *
  38. * @return array an array with explicit indexes for all the display
  39. * elements
  40. *
  41. * @global string the database name
  42. * @global string the table name
  43. * @global integer the total number of rows returned by the SQL query
  44. * without any programmatically appended "LIMIT" clause
  45. * @global array the properties of the fields returned by the query
  46. * @global string the URL to return to in case of error in a SQL
  47. * statement
  48. *
  49. * @access private
  50. *
  51. * @see PMA_displayTable()
  52. */
  53. function PMA_setDisplayMode(&$the_disp_mode, &$the_total)
  54. {
  55. global $db, $table;
  56. global $unlim_num_rows, $fields_meta;
  57. global $err_url;
  58. // 1. Initializes the $do_display array
  59. $do_display = array();
  60. $do_display['edit_lnk'] = $the_disp_mode[0] . $the_disp_mode[1];
  61. $do_display['del_lnk'] = $the_disp_mode[2] . $the_disp_mode[3];
  62. $do_display['sort_lnk'] = (string) $the_disp_mode[4];
  63. $do_display['nav_bar'] = (string) $the_disp_mode[5];
  64. $do_display['ins_row'] = (string) $the_disp_mode[6];
  65. $do_display['bkm_form'] = (string) $the_disp_mode[7];
  66. $do_display['text_btn'] = (string) $the_disp_mode[8];
  67. $do_display['pview_lnk'] = (string) $the_disp_mode[9];
  68. // 2. Display mode is not "false for all elements" -> updates the
  69. // display mode
  70. if ($the_disp_mode != 'nnnn000000') {
  71. // 2.0 Print view -> set all elements to false!
  72. if (isset($GLOBALS['printview']) && $GLOBALS['printview'] == '1') {
  73. $do_display['edit_lnk'] = 'nn'; // no edit link
  74. $do_display['del_lnk'] = 'nn'; // no delete link
  75. $do_display['sort_lnk'] = (string) '0';
  76. $do_display['nav_bar'] = (string) '0';
  77. $do_display['ins_row'] = (string) '0';
  78. $do_display['bkm_form'] = (string) '0';
  79. $do_display['text_btn'] = (string) '0';
  80. $do_display['pview_lnk'] = (string) '0';
  81. }
  82. // 2.1 Statement is a "SELECT COUNT", a
  83. // "CHECK/ANALYZE/REPAIR/OPTIMIZE", an "EXPLAIN" one or
  84. // contains a "PROC ANALYSE" part
  85. elseif ($GLOBALS['is_count'] || $GLOBALS['is_analyse'] || $GLOBALS['is_maint'] || $GLOBALS['is_explain']) {
  86. $do_display['edit_lnk'] = 'nn'; // no edit link
  87. $do_display['del_lnk'] = 'nn'; // no delete link
  88. $do_display['sort_lnk'] = (string) '0';
  89. $do_display['nav_bar'] = (string) '0';
  90. $do_display['ins_row'] = (string) '0';
  91. $do_display['bkm_form'] = (string) '1';
  92. if ($GLOBALS['is_maint']) {
  93. $do_display['text_btn'] = (string) '1';
  94. } else {
  95. $do_display['text_btn'] = (string) '0';
  96. }
  97. $do_display['pview_lnk'] = (string) '1';
  98. }
  99. // 2.2 Statement is a "SHOW..."
  100. elseif ($GLOBALS['is_show']) {
  101. /**
  102. * 2.2.1
  103. * @todo defines edit/delete links depending on show statement
  104. */
  105. $tmp = preg_match('@^SHOW[[:space:]]+(VARIABLES|(FULL[[:space:]]+)?PROCESSLIST|STATUS|TABLE|GRANTS|CREATE|LOGS|DATABASES|FIELDS)@i', $GLOBALS['sql_query'], $which);
  106. if (isset($which[1]) && strpos(' ' . strtoupper($which[1]), 'PROCESSLIST') > 0) {
  107. $do_display['edit_lnk'] = 'nn'; // no edit link
  108. $do_display['del_lnk'] = 'kp'; // "kill process" type edit link
  109. } else {
  110. // Default case -> no links
  111. $do_display['edit_lnk'] = 'nn'; // no edit link
  112. $do_display['del_lnk'] = 'nn'; // no delete link
  113. }
  114. // 2.2.2 Other settings
  115. $do_display['sort_lnk'] = (string) '0';
  116. $do_display['nav_bar'] = (string) '0';
  117. $do_display['ins_row'] = (string) '0';
  118. $do_display['bkm_form'] = (string) '1';
  119. $do_display['text_btn'] = (string) '1';
  120. $do_display['pview_lnk'] = (string) '1';
  121. }
  122. // 2.3 Other statements (ie "SELECT" ones) -> updates
  123. // $do_display['edit_lnk'], $do_display['del_lnk'] and
  124. // $do_display['text_btn'] (keeps other default values)
  125. else {
  126. $prev_table = $fields_meta[0]->table;
  127. $do_display['text_btn'] = (string) '1';
  128. for ($i = 0; $i < $GLOBALS['fields_cnt']; $i++) {
  129. $is_link = ($do_display['edit_lnk'] != 'nn'
  130. || $do_display['del_lnk'] != 'nn'
  131. || $do_display['sort_lnk'] != '0'
  132. || $do_display['ins_row'] != '0');
  133. // 2.3.2 Displays edit/delete/sort/insert links?
  134. if ($is_link
  135. && ($fields_meta[$i]->table == '' || $fields_meta[$i]->table != $prev_table)) {
  136. $do_display['edit_lnk'] = 'nn'; // don't display links
  137. $do_display['del_lnk'] = 'nn';
  138. /**
  139. * @todo May be problematic with same fields names in two joined table.
  140. */
  141. // $do_display['sort_lnk'] = (string) '0';
  142. $do_display['ins_row'] = (string) '0';
  143. if ($do_display['text_btn'] == '1') {
  144. break;
  145. }
  146. } // end if (2.3.2)
  147. // 2.3.3 Always display print view link
  148. $do_display['pview_lnk'] = (string) '1';
  149. $prev_table = $fields_meta[$i]->table;
  150. } // end for
  151. } // end if..elseif...else (2.1 -> 2.3)
  152. } // end if (2)
  153. // 3. Gets the total number of rows if it is unknown
  154. if (isset($unlim_num_rows) && $unlim_num_rows != '') {
  155. $the_total = $unlim_num_rows;
  156. } elseif (($do_display['nav_bar'] == '1' || $do_display['sort_lnk'] == '1')
  157. && (strlen($db) && !empty($table))) {
  158. $the_total = PMA_Table::countRecords($db, $table, true);
  159. }
  160. // 4. If navigation bar or sorting fields names URLs should be
  161. // displayed but there is only one row, change these settings to
  162. // false
  163. if ($do_display['nav_bar'] == '1' || $do_display['sort_lnk'] == '1') {
  164. // - Do not display sort links if less than 2 rows.
  165. // - For a VIEW we (probably) did not count the number of rows
  166. // so don't test this number here, it would remove the possibility
  167. // of sorting VIEW results.
  168. if (isset($unlim_num_rows) && $unlim_num_rows < 2 && ! PMA_Table::isView($db, $table)) {
  169. // garvin: force display of navbar for vertical/horizontal display-choice.
  170. // $do_display['nav_bar'] = (string) '0';
  171. $do_display['sort_lnk'] = (string) '0';
  172. }
  173. } // end if (3)
  174. // 5. Updates the synthetic var
  175. $the_disp_mode = join('', $do_display);
  176. return $do_display;
  177. } // end of the 'PMA_setDisplayMode()' function
  178. /**
  179. * Displays a navigation bar to browse among the results of a SQL query
  180. *
  181. * @uses $_SESSION['userconf']['disp_direction']
  182. * @uses $_SESSION['userconf']['repeat_cells']
  183. * @uses $_SESSION['userconf']['max_rows']
  184. * @uses $_SESSION['userconf']['pos']
  185. * @param integer the offset for the "next" page
  186. * @param integer the offset for the "previous" page
  187. * @param string the URL-encoded query
  188. *
  189. * @global string $db the database name
  190. * @global string $table the table name
  191. * @global string $goto the URL to go back in case of errors
  192. * @global integer $num_rows the total number of rows returned by the
  193. * SQL query
  194. * @global integer $unlim_num_rows the total number of rows returned by the
  195. * SQL any programmatically appended "LIMIT" clause
  196. * @global boolean $is_innodb whether its InnoDB or not
  197. * @global array $showtable table definitions
  198. *
  199. * @access private
  200. *
  201. * @see PMA_displayTable()
  202. */
  203. function PMA_displayTableNavigation($pos_next, $pos_prev, $sql_query)
  204. {
  205. global $db, $table, $goto;
  206. global $num_rows, $unlim_num_rows;
  207. global $is_innodb;
  208. global $showtable;
  209. // here, using htmlentities() would cause problems if the query
  210. // contains accented characters
  211. $html_sql_query = htmlspecialchars($sql_query);
  212. /**
  213. * @todo move this to a central place
  214. * @todo for other future table types
  215. */
  216. $is_innodb = (isset($showtable['Type']) && $showtable['Type'] == 'InnoDB');
  217. ?>
  218. <!-- Navigation bar -->
  219. <table border="0" cellpadding="2" cellspacing="0">
  220. <tr>
  221. <?php
  222. // Move to the beginning or to the previous page
  223. if ($_SESSION['userconf']['pos'] && $_SESSION['userconf']['max_rows'] != 'all') {
  224. // loic1: patch #474210 from Gosha Sakovich - part 1
  225. if ($GLOBALS['cfg']['NavigationBarIconic']) {
  226. $caption1 = '&lt;&lt;';
  227. $caption2 = ' &lt; ';
  228. $title1 = ' title="' . $GLOBALS['strPos1'] . '"';
  229. $title2 = ' title="' . $GLOBALS['strPrevious'] . '"';
  230. } else {
  231. $caption1 = $GLOBALS['strPos1'] . ' &lt;&lt;';
  232. $caption2 = $GLOBALS['strPrevious'] . ' &lt;';
  233. $title1 = '';
  234. $title2 = '';
  235. } // end if... else...
  236. ?>
  237. <td>
  238. <form action="sql.php" method="post">
  239. <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
  240. <input type="hidden" name="sql_query" value="<?php echo $html_sql_query; ?>" />
  241. <input type="hidden" name="pos" value="0" />
  242. <input type="hidden" name="goto" value="<?php echo $goto; ?>" />
  243. <input type="submit" name="navig" value="<?php echo $caption1; ?>"<?php echo $title1; ?> />
  244. </form>
  245. </td>
  246. <td>
  247. <form action="sql.php" method="post">
  248. <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
  249. <input type="hidden" name="sql_query" value="<?php echo $html_sql_query; ?>" />
  250. <input type="hidden" name="pos" value="<?php echo $pos_prev; ?>" />
  251. <input type="hidden" name="goto" value="<?php echo $goto; ?>" />
  252. <input type="submit" name="navig" value="<?php echo $caption2; ?>"<?php echo $title2; ?> />
  253. </form>
  254. </td>
  255. <?php
  256. } // end move back
  257. ?>
  258. <td>
  259. &nbsp;&nbsp;&nbsp;
  260. </td>
  261. <td align="center">
  262. <?php // if displaying a VIEW, $unlim_num_rows could be zero because
  263. // of $cfg['MaxExactCountViews']; in this case, avoid passing
  264. // the 5th parameter to checkFormElementInRange()
  265. // (this means we can't validate the upper limit ?>
  266. <form action="sql.php" method="post"
  267. onsubmit="return (checkFormElementInRange(this, 'session_max_rows', '<?php echo str_replace('\'', '\\\'', $GLOBALS['strInvalidRowNumber']); ?>', 1) &amp;&amp; checkFormElementInRange(this, 'pos', '<?php echo str_replace('\'', '\\\'', $GLOBALS['strInvalidRowNumber']); ?>', 0<?php echo $unlim_num_rows > 0 ? ',' . $unlim_num_rows - 1 : ''; ?>))">
  268. <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
  269. <input type="hidden" name="sql_query" value="<?php echo $html_sql_query; ?>" />
  270. <input type="hidden" name="goto" value="<?php echo $goto; ?>" />
  271. <input type="submit" name="navig" value="<?php echo $GLOBALS['strShow']; ?> :" />
  272. <input type="text" name="session_max_rows" size="3" value="<?php echo (($_SESSION['userconf']['max_rows'] != 'all') ? $_SESSION['userconf']['max_rows'] : $GLOBALS['cfg']['MaxRows']); ?>" class="textfield" onfocus="this.select()" />
  273. <?php echo $GLOBALS['strRowsFrom'] . "\n"; ?>
  274. <input type="text" name="pos" size="6" value="<?php echo (($pos_next >= $unlim_num_rows) ? 0 : $pos_next); ?>" class="textfield" onfocus="this.select()" />
  275. <br />
  276. <?php
  277. // Display mode (horizontal/vertical and repeat headers)
  278. $param1 = ' <select name="disp_direction">' . "\n"
  279. . ' <option value="horizontal"' . (($_SESSION['userconf']['disp_direction'] == 'horizontal') ? ' selected="selected"': '') . '>' . $GLOBALS['strRowsModeHorizontal'] . '</option>' . "\n"
  280. . ' <option value="horizontalflipped"' . (($_SESSION['userconf']['disp_direction'] == 'horizontalflipped') ? ' selected="selected"': '') . '>' . $GLOBALS['strRowsModeFlippedHorizontal'] . '</option>' . "\n"
  281. . ' <option value="vertical"' . (($_SESSION['userconf']['disp_direction'] == 'vertical') ? ' selected="selected"': '') . '>' . $GLOBALS['strRowsModeVertical'] . '</option>' . "\n"
  282. . ' </select>' . "\n"
  283. . ' ';
  284. $param2 = ' <input type="text" size="3" name="repeat_cells" value="' . $_SESSION['userconf']['repeat_cells'] . '" class="textfield" />' . "\n"
  285. . ' ';
  286. echo ' ' . sprintf($GLOBALS['strRowsModeOptions'], "\n" . $param1, "\n" . $param2) . "\n";
  287. ?>
  288. </form>
  289. </td>
  290. <td>
  291. &nbsp;&nbsp;&nbsp;
  292. </td>
  293. <?php
  294. // Move to the next page or to the last one
  295. if (($_SESSION['userconf']['pos'] + $_SESSION['userconf']['max_rows'] < $unlim_num_rows) && $num_rows >= $_SESSION['userconf']['max_rows']
  296. && $_SESSION['userconf']['max_rows'] != 'all') {
  297. // loic1: patch #474210 from Gosha Sakovich - part 2
  298. if ($GLOBALS['cfg']['NavigationBarIconic']) {
  299. $caption3 = ' &gt; ';
  300. $caption4 = '&gt;&gt;';
  301. $title3 = ' title="' . $GLOBALS['strNext'] . '"';
  302. $title4 = ' title="' . $GLOBALS['strEnd'] . '"';
  303. } else {
  304. $caption3 = '&gt; ' . $GLOBALS['strNext'];
  305. $caption4 = '&gt;&gt; ' . $GLOBALS['strEnd'];
  306. $title3 = '';
  307. $title4 = '';
  308. } // end if... else...
  309. echo "\n";
  310. ?>
  311. <td>
  312. <form action="sql.php" method="post">
  313. <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
  314. <input type="hidden" name="sql_query" value="<?php echo $html_sql_query; ?>" />
  315. <input type="hidden" name="pos" value="<?php echo $pos_next; ?>" />
  316. <input type="hidden" name="goto" value="<?php echo $goto; ?>" />
  317. <input type="submit" name="navig" value="<?php echo $caption3; ?>"<?php echo $title3; ?> />
  318. </form>
  319. </td>
  320. <td>
  321. <form action="sql.php" method="post"
  322. onsubmit="return <?php echo (($_SESSION['userconf']['pos'] + $_SESSION['userconf']['max_rows'] < $unlim_num_rows && $num_rows >= $_SESSION['userconf']['max_rows']) ? 'true' : 'false'); ?>">
  323. <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
  324. <input type="hidden" name="sql_query" value="<?php echo $html_sql_query; ?>" />
  325. <input type="hidden" name="pos" value="<?php echo @((ceil($unlim_num_rows / $_SESSION['userconf']['max_rows'])- 1) * $_SESSION['userconf']['max_rows']); ?>" />
  326. <?php
  327. if ($is_innodb && $unlim_num_rows > $GLOBALS['cfg']['MaxExactCount']) {
  328. echo '<input type="hidden" name="find_real_end" value="1" />' . "\n";
  329. // no backquote around this message
  330. $onclick = ' onclick="return confirmAction(\'' . PMA_jsFormat($GLOBALS['strLongOperation'], false) . '\')"';
  331. }
  332. ?>
  333. <input type="hidden" name="goto" value="<?php echo $goto; ?>" />
  334. <input type="submit" name="navig" value="<?php echo $caption4; ?>"<?php echo $title4; ?> <?php echo (empty($onclick) ? '' : $onclick); ?>/>
  335. </form>
  336. </td>
  337. <?php
  338. } // end move toward
  339. //page redirection
  340. // (unless we are showing all records)
  341. if ('all' != $_SESSION['userconf']['max_rows']) { //if1
  342. $pageNow = @floor($_SESSION['userconf']['pos'] / $_SESSION['userconf']['max_rows']) + 1;
  343. $nbTotalPage = @ceil($unlim_num_rows / $_SESSION['userconf']['max_rows']);
  344. if ($nbTotalPage > 1){ //if2
  345. ?>
  346. <td>
  347. &nbsp;&nbsp;&nbsp;
  348. </td>
  349. <td>
  350. <?php //<form> for keep the form alignment of button < and << ?>
  351. <form action="none">
  352. <?php
  353. $_url_params = array(
  354. 'db' => $db,
  355. 'table' => $table,
  356. 'sql_query' => $sql_query,
  357. 'goto' => $goto,
  358. );
  359. echo PMA_pageselector(
  360. 'sql.php' . PMA_generate_common_url($_url_params) . PMA_get_arg_separator('js'),
  361. $_SESSION['userconf']['max_rows'],
  362. $pageNow,
  363. $nbTotalPage,
  364. 200,
  365. 5,
  366. 5,
  367. 20,
  368. 10,
  369. $GLOBALS['strPageNumber']
  370. );
  371. ?>
  372. </form>
  373. </td>
  374. <?php
  375. } //_if2
  376. } //_if1
  377. // Display the "Show all" button if allowed
  378. if ($GLOBALS['cfg']['ShowAll'] && ($num_rows < $unlim_num_rows)) {
  379. echo "\n";
  380. ?>
  381. <td>
  382. &nbsp;&nbsp;&nbsp;
  383. </td>
  384. <td>
  385. <form action="sql.php" method="post">
  386. <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
  387. <input type="hidden" name="sql_query" value="<?php echo $html_sql_query; ?>" />
  388. <input type="hidden" name="pos" value="0" />
  389. <input type="hidden" name="session_max_rows" value="all" />
  390. <input type="hidden" name="goto" value="<?php echo $goto; ?>" />
  391. <input type="submit" name="navig" value="<?php echo $GLOBALS['strShowAll']; ?>" />
  392. </form>
  393. </td>
  394. <?php
  395. } // end show all
  396. echo "\n";
  397. ?>
  398. </tr>
  399. </table>
  400. <?php
  401. } // end of the 'PMA_displayTableNavigation()' function
  402. /**
  403. * Displays the headers of the results table
  404. *
  405. * @uses $_SESSION['userconf']['disp_direction']
  406. * @uses $_SESSION['userconf']['repeat_cells']
  407. * @uses $_SESSION['userconf']['max_rows']
  408. * @uses $_SESSION['userconf']['display_text']
  409. * @uses $_SESSION['userconf']['display_binary']
  410. * @param array which elements to display
  411. * @param array the list of fields properties
  412. * @param integer the total number of fields returned by the SQL query
  413. * @param array the analyzed query
  414. *
  415. * @return boolean always true
  416. *
  417. * @global string $db the database name
  418. * @global string $table the table name
  419. * @global string $goto the URL to go back in case of errors
  420. * @global string $sql_query the SQL query
  421. * @global integer $num_rows the total number of rows returned by the
  422. * SQL query
  423. * @global array $vertical_display informations used with vertical display
  424. * mode
  425. *
  426. * @access private
  427. *
  428. * @see PMA_displayTable()
  429. */
  430. function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $analyzed_sql = '', $sort_expression, $sort_expression_nodirection, $sort_direction)
  431. {
  432. global $db, $table, $goto;
  433. global $sql_query, $num_rows;
  434. global $vertical_display, $highlight_columns;
  435. if ($analyzed_sql == '') {
  436. $analyzed_sql = array();
  437. }
  438. // can the result be sorted?
  439. if ($is_display['sort_lnk'] == '1') {
  440. // Just as fallback
  441. $unsorted_sql_query = $sql_query;
  442. if (isset($analyzed_sql[0]['unsorted_query'])) {
  443. $unsorted_sql_query = $analyzed_sql[0]['unsorted_query'];
  444. }
  445. // Handles the case of multiple clicks on a column's header
  446. // which would add many spaces before "ORDER BY" in the
  447. // generated query.
  448. $unsorted_sql_query = trim($unsorted_sql_query);
  449. // sorting by indexes, only if it makes sense (only one table ref)
  450. if (isset($analyzed_sql) && isset($analyzed_sql[0]) &&
  451. isset($analyzed_sql[0]['querytype']) && $analyzed_sql[0]['querytype'] == 'SELECT' &&
  452. isset($analyzed_sql[0]['table_ref']) && count($analyzed_sql[0]['table_ref']) == 1) {
  453. // grab indexes data:
  454. $indexes = PMA_Index::getFromTable($table, $db);
  455. // do we have any index?
  456. if ($indexes) {
  457. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  458. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  459. $span = $fields_cnt;
  460. if ($is_display['edit_lnk'] != 'nn') {
  461. $span++;
  462. }
  463. if ($is_display['del_lnk'] != 'nn') {
  464. $span++;
  465. }
  466. if ($is_display['del_lnk'] != 'kp' && $is_display['del_lnk'] != 'nn') {
  467. $span++;
  468. }
  469. } else {
  470. $span = $num_rows + floor($num_rows/$_SESSION['userconf']['repeat_cells']) + 1;
  471. }
  472. echo '<form action="sql.php" method="post">' . "\n";
  473. echo PMA_generate_common_hidden_inputs($db, $table);
  474. echo $GLOBALS['strSortByKey'] . ': <select name="sql_query" onchange="this.form.submit();">' . "\n";
  475. $used_index = false;
  476. $local_order = (isset($sort_expression) ? $sort_expression : '');
  477. foreach ($indexes as $index) {
  478. $asc_sort = '`' . implode('` ASC, `', array_keys($index->getColumns())) . '` ASC';
  479. $desc_sort = '`' . implode('` DESC, `', array_keys($index->getColumns())) . '` DESC';
  480. $used_index = $used_index || $local_order == $asc_sort || $local_order == $desc_sort;
  481. echo '<option value="'
  482. . htmlspecialchars($unsorted_sql_query . ' ORDER BY ' . $asc_sort)
  483. . '"' . ($local_order == $asc_sort ? ' selected="selected"' : '')
  484. . '>' . htmlspecialchars($index->getName()) . ' ('
  485. . $GLOBALS['strAscending'] . ')</option>';
  486. echo '<option value="'
  487. . htmlspecialchars($unsorted_sql_query . ' ORDER BY ' . $desc_sort)
  488. . '"' . ($local_order == $desc_sort ? ' selected="selected"' : '')
  489. . '>' . htmlspecialchars($index->getName()) . ' ('
  490. . $GLOBALS['strDescending'] . ')</option>';
  491. }
  492. echo '<option value="' . htmlspecialchars($unsorted_sql_query) . '"' . ($used_index ? '' : ' selected="selected"') . '>' . $GLOBALS['strNone'] . '</option>';
  493. echo '</select>' . "\n";
  494. echo '<noscript><input type="submit" value="' . $GLOBALS['strGo'] . '" /></noscript>';
  495. echo '</form>' . "\n";
  496. }
  497. }
  498. }
  499. $vertical_display['emptypre'] = 0;
  500. $vertical_display['emptyafter'] = 0;
  501. $vertical_display['textbtn'] = '';
  502. // Display options (if we are not in print view)
  503. if (! (isset($GLOBALS['printview']) && $GLOBALS['printview'] == '1')) {
  504. echo '<form method="post" action="sql.php" name="displayOptionsForm" id="displayOptionsForm">';
  505. $url_params = array(
  506. 'db' => $db,
  507. 'table' => $table,
  508. 'sql_query' => $sql_query,
  509. 'goto' => $goto,
  510. 'display_options_form' => 1
  511. );
  512. echo PMA_generate_common_hidden_inputs($url_params);
  513. echo '<br />';
  514. PMA_generate_slider_effect('displayoptions',$GLOBALS['strOptions']);
  515. echo '<fieldset>';
  516. echo '<div class="formelement">';
  517. $choices = array(
  518. 'P' => $GLOBALS['strPartialText'],
  519. 'F' => $GLOBALS['strFullText']
  520. );
  521. PMA_generate_html_radio('display_text', $choices, $_SESSION['userconf']['display_text']);
  522. echo '</div>';
  523. if ($GLOBALS['cfgRelation']['relwork'] && $GLOBALS['cfgRelation']['displaywork']) {
  524. echo '<div class="formelement">';
  525. $choices = array(
  526. 'K' => $GLOBALS['strRelationalKey'],
  527. 'D' => $GLOBALS['strRelationalDisplayField']
  528. );
  529. PMA_generate_html_radio('relational_display', $choices, $_SESSION['userconf']['relational_display']);
  530. echo '</div>';
  531. }
  532. echo '<div class="formelement">';
  533. PMA_generate_html_checkbox('display_binary', $GLOBALS['strShowBinaryContents'], ! empty($_SESSION['userconf']['display_binary']), false);
  534. echo '<br />';
  535. PMA_generate_html_checkbox('display_blob', $GLOBALS['strShowBLOBContents'], ! empty($_SESSION['userconf']['display_blob']), false);
  536. echo '</div>';
  537. // I would have preferred to name this "display_transformation".
  538. // This is the only way I found to be able to keep this setting sticky
  539. // per SQL query, and at the same time have a default that displays
  540. // the transformations.
  541. echo '<div class="formelement">';
  542. PMA_generate_html_checkbox('hide_transformation', $GLOBALS['strHide'] . ' ' . $GLOBALS['strMIME_transformation'], ! empty($_SESSION['userconf']['hide_transformation']), false);
  543. echo '</div>';
  544. echo '<div class="clearfloat"></div>';
  545. echo '</fieldset>';
  546. echo '<fieldset class="tblFooters">';
  547. echo '<input type="submit" value="' . $GLOBALS['strGo'] . '" />';
  548. echo '</fieldset>';
  549. echo '</div>';
  550. echo '</form>';
  551. }
  552. // Start of form for multi-rows edit/delete/export
  553. if ($is_display['del_lnk'] == 'dr' || $is_display['del_lnk'] == 'kp') {
  554. echo '<form method="post" action="tbl_row_action.php" name="rowsDeleteForm" id="rowsDeleteForm">' . "\n";
  555. echo PMA_generate_common_hidden_inputs($db, $table, 1);
  556. echo '<input type="hidden" name="goto" value="sql.php" />' . "\n";
  557. }
  558. echo '<table id="table_results" class="data">' . "\n";
  559. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  560. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  561. echo '<thead><tr>' . "\n";
  562. }
  563. // 1. Displays the full/partial text button (part 1)...
  564. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  565. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  566. $colspan = ($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn')
  567. ? ' colspan="3"'
  568. : '';
  569. } else {
  570. $rowspan = ($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn')
  571. ? ' rowspan="3"'
  572. : '';
  573. }
  574. // ... before the result table
  575. if (($is_display['edit_lnk'] == 'nn' && $is_display['del_lnk'] == 'nn')
  576. && $is_display['text_btn'] == '1') {
  577. $vertical_display['emptypre'] = ($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn') ? 3 : 0;
  578. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  579. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  580. ?>
  581. <th colspan="<?php echo $fields_cnt; ?>"></th>
  582. </tr>
  583. <tr>
  584. <?php
  585. } // end horizontal/horizontalflipped mode
  586. else {
  587. ?>
  588. <tr>
  589. <th colspan="<?php echo $num_rows + floor($num_rows/$_SESSION['userconf']['repeat_cells']) + 1; ?>"></th>
  590. </tr>
  591. <?php
  592. } // end vertical mode
  593. }
  594. // ... at the left column of the result table header if possible
  595. // and required
  596. elseif ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && $is_display['text_btn'] == '1') {
  597. $vertical_display['emptypre'] = ($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn') ? 3 : 0;
  598. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  599. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  600. ?>
  601. <th <?php echo $colspan; ?>></th>
  602. <?php
  603. } // end horizontal/horizontalflipped mode
  604. else {
  605. $vertical_display['textbtn'] = ' <th ' . $rowspan . ' valign="middle">' . "\n"
  606. . ' ' . "\n"
  607. . ' </th>' . "\n";
  608. } // end vertical mode
  609. }
  610. // ... elseif no button, displays empty(ies) col(s) if required
  611. elseif ($GLOBALS['cfg']['ModifyDeleteAtLeft']
  612. && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn')) {
  613. $vertical_display['emptypre'] = ($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn') ? 3 : 0;
  614. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  615. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  616. ?>
  617. <td<?php echo $colspan; ?>></td>
  618. <?php
  619. } // end horizontal/horizontalfipped mode
  620. else {
  621. $vertical_display['textbtn'] = ' <td' . $rowspan . '></td>' . "\n";
  622. } // end vertical mode
  623. }
  624. // 2. Displays the fields' name
  625. // 2.0 If sorting links should be used, checks if the query is a "JOIN"
  626. // statement (see 2.1.3)
  627. // 2.0.1 Prepare Display column comments if enabled ($GLOBALS['cfg']['ShowBrowseComments']).
  628. // Do not show comments, if using horizontalflipped mode, because of space usage
  629. if ($GLOBALS['cfg']['ShowBrowseComments']
  630. && $_SESSION['userconf']['disp_direction'] != 'horizontalflipped') {
  631. $comments_map = array();
  632. if (isset($analyzed_sql[0]) && is_array($analyzed_sql[0])) {
  633. foreach ($analyzed_sql[0]['table_ref'] as $tbl) {
  634. $tb = $tbl['table_true_name'];
  635. $comments_map[$tb] = PMA_getComments($db, $tb);
  636. unset($tb);
  637. }
  638. }
  639. }
  640. if ($GLOBALS['cfgRelation']['commwork'] && $GLOBALS['cfgRelation']['mimework'] && $GLOBALS['cfg']['BrowseMIME'] && ! $_SESSION['userconf']['hide_transformation']) {
  641. require_once './libraries/transformations.lib.php';
  642. $GLOBALS['mime_map'] = PMA_getMIME($db, $table);
  643. }
  644. if ($is_display['sort_lnk'] == '1') {
  645. $select_expr = $analyzed_sql[0]['select_expr_clause'];
  646. }
  647. // garvin: See if we have to highlight any header fields of a WHERE query.
  648. // Uses SQL-Parser results.
  649. $highlight_columns = array();
  650. if (isset($analyzed_sql) && isset($analyzed_sql[0]) &&
  651. isset($analyzed_sql[0]['where_clause_identifiers'])) {
  652. $wi = 0;
  653. if (isset($analyzed_sql[0]['where_clause_identifiers']) && is_array($analyzed_sql[0]['where_clause_identifiers'])) {
  654. foreach ($analyzed_sql[0]['where_clause_identifiers'] AS $wci_nr => $wci) {
  655. $highlight_columns[$wci] = 'true';
  656. }
  657. }
  658. }
  659. for ($i = 0; $i < $fields_cnt; $i++) {
  660. // garvin: See if this column should get highlight because it's used in the
  661. // where-query.
  662. if (isset($highlight_columns[$fields_meta[$i]->name]) || isset($highlight_columns[PMA_backquote($fields_meta[$i]->name)])) {
  663. $condition_field = true;
  664. } else {
  665. $condition_field = false;
  666. }
  667. // 2.0 Prepare comment-HTML-wrappers for each row, if defined/enabled.
  668. if (isset($comments_map) &&
  669. isset($comments_map[$fields_meta[$i]->table]) &&
  670. isset($comments_map[$fields_meta[$i]->table][$fields_meta[$i]->name])) {
  671. $comments = '<span class="tblcomment">' . htmlspecialchars($comments_map[$fields_meta[$i]->table][$fields_meta[$i]->name]) . '</span>';
  672. } else {
  673. $comments = '';
  674. }
  675. // 2.1 Results can be sorted
  676. if ($is_display['sort_lnk'] == '1') {
  677. // 2.1.1 Checks if the table name is required; it's the case
  678. // for a query with a "JOIN" statement and if the column
  679. // isn't aliased, or in queries like
  680. // SELECT `1`.`master_field` , `2`.`master_field`
  681. // FROM `PMA_relation` AS `1` , `PMA_relation` AS `2`
  682. if (isset($fields_meta[$i]->table) && strlen($fields_meta[$i]->table)) {
  683. $sort_tbl = PMA_backquote($fields_meta[$i]->table) . '.';
  684. } else {
  685. $sort_tbl = '';
  686. }
  687. // 2.1.2 Checks if the current column is used to sort the
  688. // results
  689. // the orgname member does not exist for all MySQL versions
  690. // but if found, it's the one on which to sort
  691. $name_to_use_in_sort = $fields_meta[$i]->name;
  692. if (isset($fields_meta[$i]->orgname) && strlen($fields_meta[$i]->orgname)) {
  693. $name_to_use_in_sort = $fields_meta[$i]->orgname;
  694. }
  695. // $name_to_use_in_sort might contain a space due to
  696. // formatting of function expressions like "COUNT(name )"
  697. // so we remove the space in this situation
  698. $name_to_use_in_sort = str_replace(' )', ')', $name_to_use_in_sort);
  699. if (empty($sort_expression)) {
  700. $is_in_sort = false;
  701. } else {
  702. // field name may be preceded by a space, or any number
  703. // of characters followed by a dot (tablename.fieldname)
  704. // so do a direct comparison
  705. // for the sort expression (avoids problems with queries
  706. // like "SELECT id, count(id)..." and clicking to sort
  707. // on id or on count(id))
  708. if (strpos($sort_expression_nodirection, $sort_tbl) === false) {
  709. $sort_expression_nodirection = $sort_tbl . $sort_expression_nodirection;
  710. }
  711. $is_in_sort = (str_replace('`', '', $sort_tbl) . $name_to_use_in_sort == str_replace('`', '', $sort_expression_nodirection) ? true : false);
  712. }
  713. // 2.1.3 Check the field name for a bracket.
  714. // If it contains one, it's probably a function column
  715. // like 'COUNT(`field`)'
  716. if (strpos($name_to_use_in_sort, '(') !== false) {
  717. $sort_order = ' ORDER BY ' . $name_to_use_in_sort . ' ';
  718. } else {
  719. $sort_order = ' ORDER BY ' . $sort_tbl . PMA_backquote($name_to_use_in_sort) . ' ';
  720. }
  721. unset($name_to_use_in_sort);
  722. // 2.1.4 Do define the sorting URL
  723. if (! $is_in_sort) {
  724. // loic1: patch #455484 ("Smart" order)
  725. $GLOBALS['cfg']['Order'] = strtoupper($GLOBALS['cfg']['Order']);
  726. if ($GLOBALS['cfg']['Order'] === 'SMART') {
  727. $sort_order .= (preg_match('@time|date@i', $fields_meta[$i]->type)) ? 'DESC' : 'ASC';
  728. } else {
  729. $sort_order .= $GLOBALS['cfg']['Order'];
  730. }
  731. $order_img = '';
  732. } elseif ('DESC' == $sort_direction) {
  733. $sort_order .= ' ASC';
  734. $order_img = ' <img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 's_desc.png" width="11" height="9" alt="'. $GLOBALS['strDescending'] . '" title="'. $GLOBALS['strDescending'] . '" id="soimg' . $i . '" />';
  735. } else {
  736. $sort_order .= ' DESC';
  737. $order_img = ' <img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 's_asc.png" width="11" height="9" alt="'. $GLOBALS['strAscending'] . '" title="'. $GLOBALS['strAscending'] . '" id="soimg' . $i . '" />';
  738. }
  739. if (preg_match('@(.*)([[:space:]](LIMIT (.*)|PROCEDURE (.*)|FOR UPDATE|LOCK IN SHARE MODE))@i', $unsorted_sql_query, $regs3)) {
  740. $sorted_sql_query = $regs3[1] . $sort_order . $regs3[2];
  741. } else {
  742. $sorted_sql_query = $unsorted_sql_query . $sort_order;
  743. }
  744. $_url_params = array(
  745. 'db' => $db,
  746. 'table' => $table,
  747. 'sql_query' => $sorted_sql_query,
  748. );
  749. $order_url = 'sql.php' . PMA_generate_common_url($_url_params);
  750. // 2.1.5 Displays the sorting URL
  751. // added 20004-06-09: Michael Keck <mail@michaelkeck.de>
  752. // enable sort order swapping for image
  753. $order_link_params = array();
  754. if (isset($order_img) && $order_img!='') {
  755. if (strstr($order_img, 'asc')) {
  756. $order_link_params['onmouseover'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_desc.png\'; }';
  757. $order_link_params['onmouseout'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_asc.png\'; }';
  758. } elseif (strstr($order_img, 'desc')) {
  759. $order_link_params['onmouseover'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_asc.png\'; }';
  760. $order_link_params['onmouseout'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_desc.png\'; }';
  761. }
  762. }
  763. if ($_SESSION['userconf']['disp_direction'] == 'horizontalflipped'
  764. && $GLOBALS['cfg']['HeaderFlipType'] == 'css') {
  765. $order_link_params['style'] = 'direction: ltr; writing-mode: tb-rl;';
  766. }
  767. $order_link_params['title'] = $GLOBALS['strSort'];
  768. $order_link_content = ($_SESSION['userconf']['disp_direction'] == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'fake' ? PMA_flipstring(htmlspecialchars($fields_meta[$i]->name), "<br />\n") : htmlspecialchars($fields_meta[$i]->name));
  769. $order_link = PMA_linkOrButton($order_url, $order_link_content . $order_img, $order_link_params, false, true);
  770. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  771. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  772. echo '<th';
  773. if ($condition_field) {
  774. echo ' class="condition"';
  775. }
  776. if ($_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  777. echo ' valign="bottom"';
  778. }
  779. echo '>' . $order_link . $comments . '</th>';
  780. }
  781. $vertical_display['desc'][] = ' <th '
  782. . ($condition_field ? ' class="condition"' : '') . '>' . "\n"
  783. . $order_link . $comments . ' </th>' . "\n";
  784. } // end if (2.1)
  785. // 2.2 Results can't be sorted
  786. else {
  787. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  788. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  789. echo '<th';
  790. if ($condition_field) {
  791. echo ' class="condition"';
  792. }
  793. if ($_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  794. echo ' valign="bottom"';
  795. }
  796. if ($_SESSION['userconf']['disp_direction'] == 'horizontalflipped'
  797. && $GLOBALS['cfg']['HeaderFlipType'] == 'css') {
  798. echo ' style="direction: ltr; writing-mode: tb-rl;"';
  799. }
  800. echo '>';
  801. if ($_SESSION['userconf']['disp_direction'] == 'horizontalflipped'
  802. && $GLOBALS['cfg']['HeaderFlipType'] == 'fake') {
  803. echo PMA_flipstring(htmlspecialchars($fields_meta[$i]->name), '<br />');
  804. } else {
  805. echo htmlspecialchars($fields_meta[$i]->name);
  806. }
  807. echo "\n" . $comments . '</th>';
  808. }
  809. $vertical_display['desc'][] = ' <th '
  810. . ($condition_field ? ' class="condition"' : '') . '>' . "\n"
  811. . ' ' . htmlspecialchars($fields_meta[$i]->name) . "\n"
  812. . $comments . ' </th>';
  813. } // end else (2.2)
  814. } // end for
  815. // 3. Displays the needed checkboxes at the right
  816. // column of the result table header if possible and required...
  817. if ($GLOBALS['cfg']['ModifyDeleteAtRight']
  818. && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn')
  819. && $is_display['text_btn'] == '1') {
  820. $vertical_display['emptyafter'] = ($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn') ? 3 : 1;
  821. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  822. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  823. echo "\n";
  824. ?>
  825. <th <?php echo $colspan; ?>>
  826. </th>
  827. <?php
  828. } // end horizontal/horizontalflipped mode
  829. else {
  830. $vertical_display['textbtn'] = ' <th ' . $rowspan . ' valign="middle">' . "\n"
  831. . ' ' . "\n"
  832. . ' </th>' . "\n";
  833. } // end vertical mode
  834. }
  835. // ... elseif no button, displays empty columns if required
  836. // (unless coming from Browse mode print view)
  837. elseif ($GLOBALS['cfg']['ModifyDeleteAtRight']
  838. && ($is_display['edit_lnk'] == 'nn' && $is_display['del_lnk'] == 'nn')
  839. && (!$GLOBALS['is_header_sent'])) {
  840. $vertical_display['emptyafter'] = ($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn') ? 3 : 1;
  841. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  842. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  843. echo "\n";
  844. ?>
  845. <td<?php echo $colspan; ?>></td>
  846. <?php
  847. } // end horizontal/horizontalflipped mode
  848. else {
  849. $vertical_display['textbtn'] = ' <td' . $rowspan . '></td>' . "\n";
  850. } // end vertical mode
  851. }
  852. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  853. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  854. ?>
  855. </tr>
  856. </thead>
  857. <?php
  858. }
  859. return true;
  860. } // end of the 'PMA_displayTableHeaders()' function
  861. /**
  862. * Displays the body of the results table
  863. *
  864. * @uses $_SESSION['userconf']['disp_direction']
  865. * @uses $_SESSION['userconf']['repeat_cells']
  866. * @uses $_SESSION['userconf']['max_rows']
  867. * @uses $_SESSION['userconf']['display_text']
  868. * @uses $_SESSION['userconf']['display_binary']
  869. * @uses $_SESSION['userconf']['display_blob']
  870. * @param integer the link id associated to the query which results have
  871. * to be displayed
  872. * @param array which elements to display
  873. * @param array the list of relations
  874. * @param array the analyzed query
  875. *
  876. * @return boolean always true
  877. *
  878. * @global string $db the database name
  879. * @global string $table the table name
  880. * @global string $goto the URL to go back in case of errors
  881. * @global string $sql_query the SQL query
  882. * @global array $fields_meta the list of fields properties
  883. * @global integer $fields_cnt the total number of fields returned by
  884. * the SQL query
  885. * @global array $vertical_display informations used with vertical display
  886. * mode
  887. * @global array $highlight_columns column names to highlight
  888. * @global array $row current row data
  889. *
  890. * @access private
  891. *
  892. * @see PMA_displayTable()
  893. */
  894. function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) {
  895. global $db, $table, $goto;
  896. global $sql_query, $fields_meta, $fields_cnt;
  897. global $vertical_display, $highlight_columns;
  898. global $row; // mostly because of browser transformations, to make the row-data accessible in a plugin
  899. $url_sql_query = $sql_query;
  900. // query without conditions to shorten URLs when needed, 200 is just
  901. // guess, it should depend on remaining URL length
  902. if (isset($analyzed_sql) && isset($analyzed_sql[0]) &&
  903. isset($analyzed_sql[0]['querytype']) && $analyzed_sql[0]['querytype'] == 'SELECT' &&
  904. strlen($sql_query) > 200) {
  905. $url_sql_query = 'SELECT ';
  906. if (isset($analyzed_sql[0]['queryflags']['distinct'])) {
  907. $url_sql_query .= ' DISTINCT ';
  908. }
  909. $url_sql_query .= $analyzed_sql[0]['select_expr_clause'];
  910. if (!empty($analyzed_sql[0]['from_clause'])) {
  911. $url_sql_query .= ' FROM ' . $analyzed_sql[0]['from_clause'];
  912. }
  913. }
  914. if (!is_array($map)) {
  915. $map = array();
  916. }
  917. $row_no = 0;
  918. $vertical_display['edit'] = array();
  919. $vertical_display['delete'] = array();
  920. $vertical_display['data'] = array();
  921. $vertical_display['row_delete'] = array();
  922. // Correction University of Virginia 19991216 in the while below
  923. // Previous code assumed that all tables have keys, specifically that
  924. // the phpMyAdmin GUI should support row delete/edit only for such
  925. // tables.
  926. // Although always using keys is arguably the prescribed way of
  927. // defining a relational table, it is not required. This will in
  928. // particular be violated by the novice.
  929. // We want to encourage phpMyAdmin usage by such novices. So the code
  930. // below has been changed to conditionally work as before when the
  931. // table being displayed has one or more keys; but to display
  932. // delete/edit options correctly for tables without keys.
  933. $odd_row = true;
  934. while ($row = PMA_DBI_fetch_row($dt_result)) {
  935. // lem9: "vertical display" mode stuff
  936. if ($row_no != 0 && $_SESSION['userconf']['repeat_cells'] != 0 && !($row_no % $_SESSION['userconf']['repeat_cells'])
  937. && ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  938. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped'))
  939. {
  940. echo '<tr>' . "\n";
  941. if ($vertical_display['emptypre'] > 0) {
  942. echo ' <th colspan="' . $vertical_display['emptypre'] . '">' . "\n"
  943. .' &nbsp;</th>' . "\n";
  944. }
  945. foreach ($vertical_display['desc'] as $val) {
  946. echo $val;
  947. }
  948. if ($vertical_display['emptyafter'] > 0) {
  949. echo ' <th colspan="' . $vertical_display['emptyafter'] . '">' . "\n"
  950. .' &nbsp;</th>' . "\n";
  951. }
  952. echo '</tr>' . "\n";
  953. } // end if
  954. $class = $odd_row ? 'odd' : 'even';
  955. $odd_row = ! $odd_row;
  956. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  957. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  958. // loic1: pointer code part
  959. echo ' <tr class="' . $class . '">' . "\n";
  960. $class = '';
  961. }
  962. // 1. Prepares the row (gets primary keys to use)
  963. // 1.1 Results from a "SELECT" statement -> builds the
  964. // "primary" key to use in links
  965. /**
  966. * @todo $unique_condition could be empty, for example a table
  967. * with only one field and it's a BLOB; in this case,
  968. * avoid to display the delete and edit links
  969. */
  970. $unique_condition = PMA_getUniqueCondition($dt_result, $fields_cnt, $fields_meta, $row);
  971. $unique_condition_html = urlencode($unique_condition);
  972. // 1.2 Defines the URLs for the modify/delete link(s)
  973. if ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn') {
  974. // We need to copy the value or else the == 'both' check will always return true
  975. if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') {
  976. $iconic_spacer = '<div class="nowrap">';
  977. } else {
  978. $iconic_spacer = '';
  979. }
  980. // 1.2.1 Modify link(s)
  981. if ($is_display['edit_lnk'] == 'ur') { // update row case
  982. $_url_params = array(
  983. 'db' => $db,
  984. 'table' => $table,
  985. 'primary_key' => $unique_condition,
  986. 'sql_query' => $url_sql_query,
  987. 'goto' => 'sql.php',
  988. );
  989. $edit_url = 'tbl_change.php' . PMA_generate_common_url($_url_params);
  990. $edit_str = PMA_getIcon('b_edit.png', $GLOBALS['strEdit'], true);
  991. } // end if (1.2.1)
  992. if (isset($GLOBALS['cfg']['Bookmark']['table']) && isset($GLOBALS['cfg']['Bookmark']['db']) && $table == $GLOBALS['cfg']['Bookmark']['table'] && $db == $GLOBALS['cfg']['Bookmark']['db'] && isset($row[1]) && isset($row[0])) {
  993. $_url_params = array(
  994. 'db' => $row[1],
  995. 'id_bookmark' => $row[0],
  996. 'action_bookmark' => '0',
  997. 'action_bookmark_all' => '1',
  998. 'SQL' => $GLOBALS['strExecuteBookmarked'],
  999. );
  1000. $bookmark_go = '<a href="import.php'
  1001. . PMA_generate_common_url($_url_params)
  1002. .' " title="' . $GLOBALS['strExecuteBookmarked'] . '">';
  1003. $bookmark_go .= PMA_getIcon('b_bookmark.png', $GLOBALS['strExecuteBookmarked'], true);
  1004. $bookmark_go .= '</a>';
  1005. } else {
  1006. $bookmark_go = '';
  1007. }
  1008. // 1.2.2 Delete/Kill link(s)
  1009. if ($is_display['del_lnk'] == 'dr') { // delete row case
  1010. $_url_params = array(
  1011. 'db' => $db,
  1012. 'table' => $table,
  1013. 'sql_query' => $url_sql_query,
  1014. 'zero_rows' => $GLOBALS['strDeleted'],
  1015. 'goto' => (empty($goto) ? 'tbl_sql.php' : $goto),
  1016. );
  1017. $lnk_goto = 'sql.php' . PMA_generate_common_url($_url_params, 'text');
  1018. $del_query = 'DELETE FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table)
  1019. . ' WHERE ' . $unique_condition . ' LIMIT 1';
  1020. $_url_params = array(
  1021. 'db' => $db,
  1022. 'table' => $table,
  1023. 'sql_query' => $del_query,
  1024. 'zero_rows' => $GLOBALS['strDeleted'],
  1025. 'goto' => $lnk_goto,
  1026. );
  1027. $del_url = 'sql.php' . PMA_generate_common_url($_url_params);
  1028. $js_conf = 'DELETE FROM ' . PMA_jsFormat($db) . '.' . PMA_jsFormat($table)
  1029. . ' WHERE ' . PMA_jsFormat($unique_condition, false)
  1030. . ' LIMIT 1';
  1031. $del_str = PMA_getIcon('b_drop.png', $GLOBALS['strDelete'], true);
  1032. } elseif ($is_display['del_lnk'] == 'kp') { // kill process case
  1033. $_url_params = array(
  1034. 'db' => $db,
  1035. 'table' => $table,
  1036. 'sql_query' => $url_sql_query,
  1037. 'goto' => 'main.php',
  1038. );
  1039. $lnk_goto = 'sql.php' . PMA_generate_common_url($_url_params, 'text');
  1040. $_url_params = array(
  1041. 'db' => 'mysql',
  1042. 'sql_query' => 'KILL ' . $row[0],
  1043. 'goto' => $lnk_goto,
  1044. );
  1045. $del_url = 'sql.php' . PMA_generate_common_url($_url_params);
  1046. $del_query = 'KILL ' . $row[0];
  1047. $js_conf = 'KILL ' . $row[0];
  1048. $del_str = PMA_getIcon('b_drop.png', $GLOBALS['strKill'], true);
  1049. } // end if (1.2.2)
  1050. // 1.3 Displays the links at left if required
  1051. if ($GLOBALS['cfg']['ModifyDeleteAtLeft']
  1052. && ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  1053. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped')) {
  1054. $doWriteModifyAt = 'left';
  1055. require './libraries/display_tbl_links.lib.php';
  1056. } // end if (1.3)
  1057. } // end if (1)
  1058. // 2. Displays the rows' values
  1059. for ($i = 0; $i < $fields_cnt; ++$i) {
  1060. $meta = $fields_meta[$i];
  1061. $pointer = $i;
  1062. // garvin: See if this column should get highlight because it's used in the
  1063. // where-query.
  1064. if (isset($highlight_columns) && (isset($highlight_columns[$meta->name]) || isset($highlight_columns[PMA_backquote($meta->name)]))) {
  1065. $condition_field = true;
  1066. } else {
  1067. $condition_field = false;
  1068. }
  1069. $mouse_events = '';
  1070. if ($_SESSION['userconf']['disp_direction'] == 'vertical' && (!isset($GLOBALS['printview']) || ($GLOBALS['printview'] != '1'))) {
  1071. if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) {
  1072. $mouse_events .= ' onmouseover="setVerticalPointer(this, ' . $row_no . ', \'over\', \'odd\', \'even\', \'hover\', \'marked\');"'
  1073. . ' onmouseout="setVerticalPointer(this, ' . $row_no . ', \'out\', \'odd\', \'even\', \'hover\', \'marked\');" ';
  1074. }
  1075. if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) {
  1076. $mouse_events .= ' onmousedown="setVerticalPointer(this, ' . $row_no . ', \'click\', \'odd\', \'even\', \'hover\', \'marked\'); setCheckboxColumn(\'id_rows_to_delete' . $row_no . '\');" ';
  1077. } else {
  1078. $mouse_events .= ' onmousedown="setCheckboxColumn(\'id_rows_to_delete' . $row_no . '\');" ';
  1079. }
  1080. }// end if
  1081. // garvin: Wrap MIME-transformations. [MIME]
  1082. $default_function = 'default_function'; // default_function
  1083. $transform_function = $default_function;
  1084. $transform_options = array();
  1085. if ($GLOBALS['cfgRelation']['mimework'] && $GLOBALS['cfg']['BrowseMIME']) {
  1086. if (isset($GLOBALS['mime_map'][$meta->name]['mimetype']) && isset($GLOBALS['mime_map'][$meta->name]['transformation']) && !empty($GLOBALS['mime_map'][$meta->name]['transformation'])) {
  1087. $include_file = $GLOBALS['mime_map'][$meta->name]['transformation'];
  1088. if (file_exists('./libraries/transformations/' . $include_file)) {
  1089. $transformfunction_name = str_replace('.inc.php', '', $GLOBALS['mime_map'][$meta->name]['transformation']);
  1090. require_once './libraries/transformations/' . $include_file;
  1091. if (function_exists('PMA_transformation_' . $transformfunction_name)) {
  1092. $transform_function = 'PMA_transformation_' . $transformfunction_name;
  1093. $transform_options = PMA_transformation_getOptions((isset($GLOBALS['mime_map'][$meta->name]['transformation_options']) ? $GLOBALS['mime_map'][$meta->name]['transformation_options'] : ''));
  1094. $meta->mimetype = str_replace('_', '/', $GLOBALS['mime_map'][$meta->name]['mimetype']);
  1095. }
  1096. } // end if file_exists
  1097. } // end if transformation is set
  1098. } // end if mime/transformation works.
  1099. $_url_params = array(
  1100. 'db' => $db,
  1101. 'table' => $table,
  1102. 'primary_key' => $unique_condition,
  1103. 'transform_key' => $meta->name,
  1104. );
  1105. if (! empty($sql_query)) {
  1106. $_url_params['sql_query'] = $url_sql_query;
  1107. }
  1108. $transform_options['wrapper_link'] = PMA_generate_common_url($_url_params);
  1109. // n u m e r i c
  1110. if ($meta->numeric == 1) {
  1111. // lem9: if two fields have the same name (this is possible
  1112. // with self-join queries, for example), using $meta->name
  1113. // will show both fields NULL even if only one is NULL,
  1114. // so use the $pointer
  1115. if (!isset($row[$i]) || is_null($row[$i])) {
  1116. $vertical_display['data'][$row_no][$i] = ' <td align="right"' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"><i>NULL</i></td>' . "\n";
  1117. } elseif ($row[$i] != '') {
  1118. $nowrap = ' nowrap';
  1119. $where_comparison = ' = ' . $row[$i];
  1120. $vertical_display['data'][$row_no][$i] = '<td align="right"' . PMA_prepare_row_data($mouse_events, $class, $condition_field, $analyzed_sql, $meta, $map, $row[$i], $transform_function, $default_function, $nowrap, $where_comparison, $transform_options);
  1121. } else {
  1122. $vertical_display['data'][$row_no][$i] = ' <td align="right"' . $mouse_events . ' class="' . $class . ' nowrap' . ($condition_field ? ' condition' : '') . '">&nbsp;</td>' . "\n";
  1123. }
  1124. // b l o b
  1125. } elseif (stristr($meta->type, 'BLOB')) {
  1126. // loic1 : PMA_mysql_fetch_fields returns BLOB in place of
  1127. // TEXT fields type so we have to ensure it's really a BLOB
  1128. $field_flags = PMA_DBI_field_flags($dt_result, $i);
  1129. if (stristr($field_flags, 'BINARY')) {
  1130. // rajk - for blobstreaming
  1131. $bs_reference_exists = $allBSTablesExist = FALSE;
  1132. // load PMA configuration
  1133. $PMA_Config = $_SESSION['PMA_Config'];
  1134. // if PMA configuration exists
  1135. if ($PMA_Config)
  1136. {
  1137. // load BS variables
  1138. $pluginsExist = $PMA_Config->get('BLOBSTREAMING_PLUGINS_EXIST');
  1139. // if BS plugins exist
  1140. if ($pluginsExist)
  1141. {
  1142. // load BS databases
  1143. $bs_tables = $PMA_Config->get('BLOBSTREAMABLE_DATABASES');
  1144. // if BS db array and specified db string not empty and valid
  1145. if (!empty($bs_tables) && strlen($db) > 0)
  1146. {
  1147. $bs_tables = $bs_tables[$db];
  1148. if (isset($bs_tables))
  1149. {
  1150. $allBSTablesExist = TRUE;
  1151. // check if BS tables exist for given database
  1152. foreach ($bs_tables as $table_key=>$bs_tbl)
  1153. if (!$bs_tables[$table_key]['Exists'])
  1154. {
  1155. $allBSTablesExist = FALSE;
  1156. break;
  1157. }
  1158. }
  1159. }
  1160. }
  1161. }
  1162. // if necessary BS tables exist
  1163. if ($allBSTablesExist)
  1164. $bs_reference_exists = PMA_BS_ReferenceExists($row[$i], $db);
  1165. // if valid BS reference exists
  1166. if ($bs_reference_exists)
  1167. $blobtext = PMA_BS_CreateReferenceLink($row[$i], $db);
  1168. else
  1169. $blobtext = PMA_handle_non_printable_contents('BLOB', (isset($row[$i]) ? $row[$i] : ''), $transform_function, $transform_options, $default_function, $meta);
  1170. $vertical_display['data'][$row_no][$i] = ' <td align="left"' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '">' . $blobtext . '</td>';
  1171. unset($blobtext);
  1172. } else {
  1173. if (!isset($row[$i]) || is_null($row[$i])) {
  1174. $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"><i>NULL</i></td>' . "\n";
  1175. } elseif ($row[$i] != '') {
  1176. // garvin: if a transform function for blob is set, none of these replacements will be made
  1177. if (PMA_strlen($row[$i]) > $GLOBALS['cfg']['LimitChars'] && $_SESSION['userconf']['display_text'] == 'P') {
  1178. $row[$i] = PMA_substr($row[$i], 0, $GLOBALS['cfg']['LimitChars']) . '...';
  1179. }
  1180. // loic1: displays all space characters, 4 space
  1181. // characters for tabulations and <cr>/<lf>
  1182. $row[$i] = ($default_function != $transform_function ? $transform_function($row[$i], $transform_options, $meta) : $default_function($row[$i], array(), $meta));
  1183. $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '">' . $row[$i] . '</td>' . "\n";
  1184. } else {
  1185. $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '">&nbsp;</td>' . "\n";
  1186. }
  1187. }
  1188. } else {
  1189. if (!isset($row[$i]) || is_null($row[$i])) {
  1190. $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"><i>NULL</i></td>' . "\n";
  1191. } elseif ($row[$i] != '') {
  1192. // loic1: support blanks in the key
  1193. $relation_id = $row[$i];
  1194. // nijel: Cut all fields to $GLOBALS['cfg']['LimitChars']
  1195. // lem9: (unless it's a link-type transformation)
  1196. if (PMA_strlen($row[$i]) > $GLOBALS['cfg']['LimitChars'] && $_SESSION['userconf']['display_text'] == 'P' && !strpos($transform_function, 'link') === true) {
  1197. $row[$i] = PMA_substr($row[$i], 0, $GLOBALS['cfg']['LimitChars']) . '...';
  1198. }
  1199. // loic1: displays special characters from binaries
  1200. $field_flags = PMA_DBI_field_flags($dt_result, $i);
  1201. if (isset($meta->_type) && $meta->_type === MYSQLI_TYPE_BIT) {
  1202. $row[$i] = PMA_printable_bit_value($row[$i], $meta->length);
  1203. } elseif (stristr($field_flags, 'BINARY') && $meta->type == 'string') {
  1204. if ($_SESSION['userconf']['display_binary'] || (isset($GLOBALS['is_analyse']) && $GLOBALS['is_analyse'])) {
  1205. // user asked to see the real contents of BINARY
  1206. // fields, or we detected a PROCEDURE ANALYSE in
  1207. // the query (results are reported as being
  1208. // binary strings)
  1209. $row[$i] = PMA_replace_binary_contents($row[$i]);
  1210. } else {
  1211. // we show the BINARY message and field's size
  1212. // (or maybe use a transformation)
  1213. $row[$i] = PMA_handle_non_printable_contents('BINARY', $row[$i], $transform_function, $transform_options, $default_function, $meta);
  1214. }
  1215. }
  1216. // garvin: transform functions may enable no-wrapping:
  1217. $function_nowrap = $transform_function . '_nowrap';
  1218. $bool_nowrap = (($default_function != $transform_function && function_exists($function_nowrap)) ? $function_nowrap($transform_options) : false);
  1219. // loic1: do not wrap if date field type
  1220. $nowrap = ((preg_match('@DATE|TIME@i', $meta->type) || $bool_nowrap) ? ' nowrap' : '');
  1221. $where_comparison = ' = \'' . PMA_sqlAddslashes($row[$i]) . '\'';
  1222. $vertical_display['data'][$row_no][$i] = '<td ' . PMA_prepare_row_data($mouse_events, $class, $condition_field, $analyzed_sql, $meta, $map, $row[$i], $transform_function, $default_function, $nowrap, $where_comparison, $transform_options);
  1223. } else {
  1224. $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '">&nbsp;</td>' . "\n";
  1225. }
  1226. }
  1227. // lem9: output stored cell
  1228. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  1229. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  1230. echo $vertical_display['data'][$row_no][$i];
  1231. }
  1232. if (isset($vertical_display['rowdata'][$i][$row_no])) {
  1233. $vertical_display['rowdata'][$i][$row_no] .= $vertical_display['data'][$row_no][$i];
  1234. } else {
  1235. $vertical_display['rowdata'][$i][$row_no] = $vertical_display['data'][$row_no][$i];
  1236. }
  1237. } // end for (2)
  1238. // 3. Displays the modify/delete links on the right if required
  1239. if ($GLOBALS['cfg']['ModifyDeleteAtRight']
  1240. && ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  1241. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped')) {
  1242. $doWriteModifyAt = 'right';
  1243. require './libraries/display_tbl_links.lib.php';
  1244. } // end if (3)
  1245. if ($_SESSION['userconf']['disp_direction'] == 'horizontal'
  1246. || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') {
  1247. ?>
  1248. </tr>
  1249. <?php
  1250. } // end if
  1251. // 4. Gather links of del_urls and edit_urls in an array for later
  1252. // output
  1253. if (!isset($vertical_display['edit'][$row_no])) {
  1254. $vertical_display['edit'][$row_no] = '';
  1255. $vertical_display['delete'][$row_no] = '';
  1256. $vertical_display['row_delete'][$row_no] = '';
  1257. }
  1258. $column_style_vertical = '';
  1259. if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) {
  1260. $column_style_vertical .= ' onmouseover="setVerticalPointer(this, ' . $row_no . ', \'over\', \'odd\', \'even\', \'hover\', \'marked\');"'
  1261. . ' onmouseout="setVerticalPointer(this, ' . $row_no . ', \'out\', \'odd\', \'even\', \'hover\', \'marked\');"';
  1262. }
  1263. $column_marker_vertical = '';
  1264. if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) {
  1265. $column_marker_vertical .= 'setVerticalPointer(this, ' . $row_no . ', \'click\', \'odd\', \'even\', \'hover\', \'marked\');';
  1266. }
  1267. if (!empty($del_url) && $is_display['del_lnk'] != 'kp') {
  1268. $vertical_display['row_delete'][$row_no] .= ' <td align="center" class="' . $class . '" ' . $column_style_vertical . '>' . "\n"
  1269. . ' <input type="checkbox" id="id_rows_to_delete' . $row_no . '[%_PMA_CHECKBOX_DIR_%]" name="rows_to_delete[' . $unique_condition_html . ']"'
  1270. . ' onclick="' . $column_marker_vertical . 'copyCheckboxesRange(\'rowsDeleteForm\', \'id_rows_to_delete' . $row_no . '\',\'[%_PMA_CHECKBOX_DIR_%]\');"'
  1271. . ' value="' . htmlspecialchars($del_query) . '" ' . (isset($GLOBALS['checkall']) ? 'checked="checked"' : '') . ' />' . "\n"
  1272. . ' </td>' . "\n";
  1273. } else {
  1274. unset($vertical_display['row_delete'][$row_no]);
  1275. }
  1276. if (isset($edit_url)) {
  1277. $vertical_display['edit'][$row_no] .= ' <td align="center" class="' . $class . '" ' . $column_style_vertical . '>' . "\n"
  1278. . PMA_linkOrButton($edit_url, $edit_str, array(), false)
  1279. . $bookmark_go
  1280. . ' </td>' . "\n";
  1281. } else {
  1282. unset($vertical_display['edit'][$row_no]);
  1283. }
  1284. if (isset($del_url)) {
  1285. $vertical_display['delete'][$row_no] .= ' <td align="center" class="' . $class . '" ' . $column_style_vertical . '>' . "\n"
  1286. . PMA_linkOrButton($del_url, $del_str, (isset($js_conf) ? $js_conf : ''), false)
  1287. . ' </td>' . "\n";
  1288. } else {
  1289. unset($vertical_display['delete'][$row_no]);
  1290. }
  1291. echo (($_SESSION['userconf']['disp_direction'] == 'horizontal' || $_SESSION['userconf']['disp_direction'] == 'horizontalflipped') ? "\n" : '');
  1292. $row_no++;
  1293. } // end while
  1294. return true;
  1295. } // end of the 'PMA_displayTableBody()' function
  1296. /**
  1297. * Do display the result table with the vertical direction mode.
  1298. * Credits for this feature goes to Garvin Hicking <hicking@faktor-e.de>.
  1299. *
  1300. * @return boolean always true
  1301. *
  1302. * @uses $_SESSION['userconf']['repeat_cells']
  1303. * @global array $vertical_display the information to display
  1304. *
  1305. * @access private
  1306. *
  1307. * @see PMA_displayTable()
  1308. */
  1309. function PMA_displayVerticalTable()
  1310. {
  1311. global $vertical_display;
  1312. // Displays "multi row delete" link at top if required
  1313. if ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && is_array($vertical_display['row_delete']) && (count($vertical_display['row_delete']) > 0 || !empty($vertical_display['textbtn']))) {
  1314. echo '<tr>' . "\n";
  1315. echo $vertical_display['textbtn'];
  1316. $foo_counter = 0;
  1317. foreach ($vertical_display['row_delete'] as $val) {
  1318. if (($foo_counter != 0) && ($_SESSION['userconf']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['userconf']['repeat_cells'])) {
  1319. echo '<th></th>' . "\n";
  1320. }
  1321. echo str_replace('[%_PMA_CHECKBOX_DIR_%]', '', $val);
  1322. $foo_counter++;
  1323. } // end while
  1324. echo '</tr>' . "\n";
  1325. } // end if
  1326. // Displays "edit" link at top if required
  1327. if ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && is_array($vertical_display['edit']) && (count($vertical_display['edit']) > 0 || !empty($vertical_display['textbtn']))) {
  1328. echo '<tr>' . "\n";
  1329. if (!is_array($vertical_display['row_delete'])) {
  1330. echo $vertical_display['textbtn'];
  1331. }
  1332. $foo_counter = 0;
  1333. foreach ($vertical_display['edit'] as $val) {
  1334. if (($foo_counter != 0) && ($_SESSION['userconf']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['userconf']['repeat_cells'])) {
  1335. echo ' <th></th>' . "\n";
  1336. }
  1337. echo $val;
  1338. $foo_counter++;
  1339. } // end while
  1340. echo '</tr>' . "\n";
  1341. } // end if
  1342. // Displays "delete" link at top if required
  1343. if ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && is_array($vertical_display['delete']) && (count($vertical_display['delete']) > 0 || !empty($vertical_display['textbtn']))) {
  1344. echo '<tr>' . "\n";
  1345. if (!is_array($vertical_display['edit']) && !is_array($vertical_display['row_delete'])) {
  1346. echo $vertical_display['textbtn'];
  1347. }
  1348. $foo_counter = 0;
  1349. foreach ($vertical_display['delete'] as $val) {
  1350. if (($foo_counter != 0) && ($_SESSION['userconf']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['userconf']['repeat_cells'])) {
  1351. echo '<th></th>' . "\n";
  1352. }
  1353. echo $val;
  1354. $foo_counter++;
  1355. } // end while
  1356. echo '</tr>' . "\n";
  1357. } // end if
  1358. // Displays data
  1359. foreach ($vertical_display['desc'] AS $key => $val) {
  1360. echo '<tr>' . "\n";
  1361. echo $val;
  1362. $foo_counter = 0;
  1363. foreach ($vertical_display['rowdata'][$key] as $subval) {
  1364. if (($foo_counter != 0) && ($_SESSION['userconf']['repeat_cells'] != 0) and !($foo_counter % $_SESSION['userconf']['repeat_cells'])) {
  1365. echo $val;
  1366. }
  1367. echo $subval;
  1368. $foo_counter++;
  1369. } // end while
  1370. echo '</tr>' . "\n";
  1371. } // end while
  1372. // Displays "multi row delete" link at bottom if required
  1373. if ($GLOBALS['cfg']['ModifyDeleteAtRight'] && is_array($vertical_display['row_delete']) && (count($vertical_display['row_delete']) > 0 || !empty($vertical_display['textbtn']))) {
  1374. echo '<tr>' . "\n";
  1375. echo $vertical_display['textbtn'];
  1376. $foo_counter = 0;
  1377. foreach ($vertical_display['row_delete'] as $val) {
  1378. if (($foo_counter != 0) && ($_SESSION['userconf']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['userconf']['repeat_cells'])) {
  1379. echo '<th></th>' . "\n";
  1380. }
  1381. echo str_replace('[%_PMA_CHECKBOX_DIR_%]', 'r', $val);
  1382. $foo_counter++;
  1383. } // end while
  1384. echo '</tr>' . "\n";
  1385. } // end if
  1386. // Displays "edit" link at bottom if required
  1387. if ($GLOBALS['cfg']['ModifyDeleteAtRight'] && is_array($vertical_display['edit']) && (count($vertical_display['edit']) > 0 || !empty($vertical_display['textbtn']))) {
  1388. echo '<tr>' . "\n";
  1389. if (!is_array($vertical_display['row_delete'])) {
  1390. echo $vertical_display['textbtn'];
  1391. }
  1392. $foo_counter = 0;
  1393. foreach ($vertical_display['edit'] as $val) {
  1394. if (($foo_counter != 0) && ($_SESSION['userconf']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['userconf']['repeat_cells'])) {
  1395. echo '<th></th>' . "\n";
  1396. }
  1397. echo $val;
  1398. $foo_counter++;
  1399. } // end while
  1400. echo '</tr>' . "\n";
  1401. } // end if
  1402. // Displays "delete" link at bottom if required
  1403. if ($GLOBALS['cfg']['ModifyDeleteAtRight'] && is_array($vertical_display['delete']) && (count($vertical_display['delete']) > 0 || !empty($vertical_display['textbtn']))) {
  1404. echo '<tr>' . "\n";
  1405. if (!is_array($vertical_display['edit']) && !is_array($vertical_display['row_delete'])) {
  1406. echo $vertical_display['textbtn'];
  1407. }
  1408. $foo_counter = 0;
  1409. foreach ($vertical_display['delete'] as $val) {
  1410. if (($foo_counter != 0) && ($_SESSION['userconf']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['userconf']['repeat_cells'])) {
  1411. echo '<th></th>' . "\n";
  1412. }
  1413. echo $val;
  1414. $foo_counter++;
  1415. } // end while
  1416. echo '</tr>' . "\n";
  1417. }
  1418. return true;
  1419. } // end of the 'PMA_displayVerticalTable' function
  1420. /**
  1421. *
  1422. * @uses $_SESSION['userconf']['disp_direction']
  1423. * @uses $_REQUEST['disp_direction']
  1424. * @uses $GLOBALS['cfg']['DefaultDisplay']
  1425. * @uses $_SESSION['userconf']['repeat_cells']
  1426. * @uses $_REQUEST['repeat_cells']
  1427. * @uses $GLOBALS['cfg']['RepeatCells']
  1428. * @uses $_SESSION['userconf']['max_rows']
  1429. * @uses $_REQUEST['session_max_rows']
  1430. * @uses $GLOBALS['cfg']['MaxRows']
  1431. * @uses $_SESSION['userconf']['pos']
  1432. * @uses $_REQUEST['pos']
  1433. * @uses $_SESSION['userconf']['display_text']
  1434. * @uses $_REQUEST['display_text']
  1435. * @uses $_SESSION['userconf']['relational_display']
  1436. * @uses $_REQUEST['relational_display']
  1437. * @uses $_SESSION['userconf']['display_binary']
  1438. * @uses $_REQUEST['display_binary']
  1439. * @uses $_SESSION['userconf']['display_blob']
  1440. * @uses $_REQUEST['display_blob']
  1441. * @uses PMA_isValid()
  1442. * @uses $GLOBALS['sql_query']
  1443. * @todo make maximum remembered queries configurable
  1444. * @todo move/split into SQL class!?
  1445. * @todo currently this is called twice unnecessary
  1446. * @todo ignore LIMIT and ORDER in query!?
  1447. */
  1448. function PMA_displayTable_checkConfigParams()
  1449. {
  1450. $sql_key = md5($GLOBALS['sql_query']);
  1451. $_SESSION['userconf']['query'][$sql_key]['sql'] = $GLOBALS['sql_query'];
  1452. if (PMA_isValid($_REQUEST['disp_direction'], array('horizontal', 'vertical', 'horizontalflipped'))) {
  1453. $_SESSION['userconf']['query'][$sql_key]['disp_direction'] = $_REQUEST['disp_direction'];
  1454. unset($_REQUEST['disp_direction']);
  1455. } elseif (empty($_SESSION['userconf']['query'][$sql_key]['disp_direction'])) {
  1456. $_SESSION['userconf']['query'][$sql_key]['disp_direction'] = $GLOBALS['cfg']['DefaultDisplay'];
  1457. }
  1458. if (PMA_isValid($_REQUEST['repeat_cells'], 'numeric')) {
  1459. $_SESSION['userconf']['query'][$sql_key]['repeat_cells'] = $_REQUEST['repeat_cells'];
  1460. unset($_REQUEST['repeat_cells']);
  1461. } elseif (empty($_SESSION['userconf']['query'][$sql_key]['repeat_cells'])) {
  1462. $_SESSION['userconf']['query'][$sql_key]['repeat_cells'] = $GLOBALS['cfg']['RepeatCells'];
  1463. }
  1464. if (PMA_isValid($_REQUEST['session_max_rows'], 'numeric') || $_REQUEST['session_max_rows'] == 'all') {
  1465. $_SESSION['userconf']['query'][$sql_key]['max_rows'] = $_REQUEST['session_max_rows'];
  1466. unset($_REQUEST['session_max_rows']);
  1467. } elseif (empty($_SESSION['userconf']['query'][$sql_key]['max_rows'])) {
  1468. $_SESSION['userconf']['query'][$sql_key]['max_rows'] = $GLOBALS['cfg']['MaxRows'];
  1469. }
  1470. if (PMA_isValid($_REQUEST['pos'], 'numeric')) {
  1471. $_SESSION['userconf']['query'][$sql_key]['pos'] = $_REQUEST['pos'];
  1472. unset($_REQUEST['pos']);
  1473. } elseif (empty($_SESSION['userconf']['query'][$sql_key]['pos'])) {
  1474. $_SESSION['userconf']['query'][$sql_key]['pos'] = 0;
  1475. }
  1476. if (PMA_isValid($_REQUEST['display_text'], array('P', 'F'))) {
  1477. $_SESSION['userconf']['query'][$sql_key]['display_text'] = $_REQUEST['display_text'];
  1478. unset($_REQUEST['display_text']);
  1479. } elseif (empty($_SESSION['userconf']['query'][$sql_key]['display_text'])) {
  1480. $_SESSION['userconf']['query'][$sql_key]['display_text'] = 'P';
  1481. }
  1482. if (PMA_isValid($_REQUEST['relational_display'], array('K', 'D'))) {
  1483. $_SESSION['userconf']['query'][$sql_key]['relational_display'] = $_REQUEST['relational_display'];
  1484. unset($_REQUEST['relational_display']);
  1485. } elseif (empty($_SESSION['userconf']['query'][$sql_key]['relational_display'])) {
  1486. $_SESSION['userconf']['query'][$sql_key]['relational_display'] = 'K';
  1487. }
  1488. if (isset($_REQUEST['display_binary'])) {
  1489. $_SESSION['userconf']['query'][$sql_key]['display_binary'] = true;
  1490. unset($_REQUEST['display_binary']);
  1491. } elseif (isset($_REQUEST['display_options_form'])) {
  1492. // we know that the checkbox was unchecked
  1493. unset($_SESSION['userconf']['query'][$sql_key]['display_binary']);
  1494. } else {
  1495. // selected by default because some operations like OPTIMIZE TABLE
  1496. // and all queries involving functions return "binary" contents,
  1497. // according to low-level field flags
  1498. $_SESSION['userconf']['query'][$sql_key]['display_binary'] = true;
  1499. }
  1500. if (isset($_REQUEST['display_blob'])) {
  1501. $_SESSION['userconf']['query'][$sql_key]['display_blob'] = true;
  1502. unset($_REQUEST['display_blob']);
  1503. } elseif (isset($_REQUEST['display_options_form'])) {
  1504. // we know that the checkbox was unchecked
  1505. unset($_SESSION['userconf']['query'][$sql_key]['display_blob']);
  1506. }
  1507. if (isset($_REQUEST['hide_transformation'])) {
  1508. $_SESSION['userconf']['query'][$sql_key]['hide_transformation'] = true;
  1509. unset($_REQUEST['hide_transformation']);
  1510. } elseif (isset($_REQUEST['display_options_form'])) {
  1511. // we know that the checkbox was unchecked
  1512. unset($_SESSION['userconf']['query'][$sql_key]['hide_transformation']);
  1513. }
  1514. // move current query to the last position, to be removed last
  1515. // so only least executed query will be removed if maximum remembered queries
  1516. // limit is reached
  1517. $tmp = $_SESSION['userconf']['query'][$sql_key];
  1518. unset($_SESSION['userconf']['query'][$sql_key]);
  1519. $_SESSION['userconf']['query'][$sql_key] = $tmp;
  1520. // do not exceed a maximum number of queries to remember
  1521. if (count($_SESSION['userconf']['query']) > 10) {
  1522. array_shift($_SESSION['userconf']['query']);
  1523. //echo 'deleting one element ...';
  1524. }
  1525. // populate query configuration
  1526. $_SESSION['userconf']['display_text'] = $_SESSION['userconf']['query'][$sql_key]['display_text'];
  1527. $_SESSION['userconf']['relational_display'] = $_SESSION['userconf']['query'][$sql_key]['relational_display'];
  1528. $_SESSION['userconf']['display_binary'] = isset($_SESSION['userconf']['query'][$sql_key]['display_binary']) ? true : false;
  1529. $_SESSION['userconf']['display_blob'] = isset($_SESSION['userconf']['query'][$sql_key]['display_blob']) ? true : false;
  1530. $_SESSION['userconf']['hide_transformation'] = isset($_SESSION['userconf']['query'][$sql_key]['hide_transformation']) ? true : false;
  1531. $_SESSION['userconf']['pos'] = $_SESSION['userconf']['query'][$sql_key]['pos'];
  1532. $_SESSION['userconf']['max_rows'] = $_SESSION['userconf']['query'][$sql_key]['max_rows'];
  1533. $_SESSION['userconf']['repeat_cells'] = $_SESSION['userconf']['query'][$sql_key]['repeat_cells'];
  1534. $_SESSION['userconf']['disp_direction'] = $_SESSION['userconf']['query'][$sql_key]['disp_direction'];
  1535. /*
  1536. * debugging
  1537. echo '<pre>';
  1538. var_dump($_SESSION['userconf']);
  1539. echo '</pre>';
  1540. */
  1541. }
  1542. /**
  1543. * Displays a table of results returned by a SQL query.
  1544. * This function is called by the "sql.php" script.
  1545. *
  1546. * @param integer the link id associated to the query which results have
  1547. * to be displayed
  1548. * @param array the display mode
  1549. * @param array the analyzed query
  1550. *
  1551. * @uses $_SESSION['userconf']['pos']
  1552. * @global string $db the database name
  1553. * @global string $table the table name
  1554. * @global string $goto the URL to go back in case of errors
  1555. * @global string $sql_query the current SQL query
  1556. * @global integer $num_rows the total number of rows returned by the
  1557. * SQL query
  1558. * @global integer $unlim_num_rows the total number of rows returned by the
  1559. * SQL query without any programmatically
  1560. * appended "LIMIT" clause
  1561. * @global array $fields_meta the list of fields properties
  1562. * @global integer $fields_cnt the total number of fields returned by
  1563. * the SQL query
  1564. * @global array $vertical_display informations used with vertical display
  1565. * mode
  1566. * @global array $highlight_columns column names to highlight
  1567. * @global array $cfgRelation the relation settings
  1568. *
  1569. * @access private
  1570. *
  1571. * @see PMA_showMessage(), PMA_setDisplayMode(),
  1572. * PMA_displayTableNavigation(), PMA_displayTableHeaders(),
  1573. * PMA_displayTableBody(), PMA_displayResultsOperations()
  1574. */
  1575. function PMA_displayTable(&$dt_result, &$the_disp_mode, $analyzed_sql)
  1576. {
  1577. global $db, $table, $goto;
  1578. global $sql_query, $num_rows, $unlim_num_rows, $fields_meta, $fields_cnt;
  1579. global $vertical_display, $highlight_columns;
  1580. global $cfgRelation;
  1581. global $showtable;
  1582. // why was this called here? (already called from sql.php)
  1583. //PMA_displayTable_checkConfigParams();
  1584. /**
  1585. * @todo move this to a central place
  1586. * @todo for other future table types
  1587. */
  1588. $is_innodb = (isset($showtable['Type']) && $showtable['Type'] == 'InnoDB');
  1589. if ($is_innodb
  1590. && ! isset($analyzed_sql[0]['queryflags']['union'])
  1591. && ! isset($analyzed_sql[0]['table_ref'][1]['table_name'])
  1592. && (empty($analyzed_sql[0]['where_clause'])
  1593. || $analyzed_sql[0]['where_clause'] == '1 ')) {
  1594. // "j u s t b r o w s i n g"
  1595. $pre_count = '~';
  1596. $after_count = PMA_showHint(PMA_sanitize($GLOBALS['strApproximateCount']), true);
  1597. } else {
  1598. $pre_count = '';
  1599. $after_count = '';
  1600. }
  1601. // 1. ----- Prepares the work -----
  1602. // 1.1 Gets the informations about which functionalities should be
  1603. // displayed
  1604. $total = '';
  1605. $is_display = PMA_setDisplayMode($the_disp_mode, $total);
  1606. // 1.2 Defines offsets for the next and previous pages
  1607. if ($is_display['nav_bar'] == '1') {
  1608. if ($_SESSION['userconf']['max_rows'] == 'all') {
  1609. $pos_next = 0;
  1610. $pos_prev = 0;
  1611. } else {
  1612. $pos_next = $_SESSION['userconf']['pos'] + $_SESSION['userconf']['max_rows'];
  1613. $pos_prev = $_SESSION['userconf']['pos'] - $_SESSION['userconf']['max_rows'];
  1614. if ($pos_prev < 0) {
  1615. $pos_prev = 0;
  1616. }
  1617. }
  1618. } // end if
  1619. // 1.3 Find the sort expression
  1620. // we need $sort_expression and $sort_expression_nodirection
  1621. // even if there are many table references
  1622. if (! empty($analyzed_sql[0]['order_by_clause'])) {
  1623. $sort_expression = trim(str_replace(' ', ' ', $analyzed_sql[0]['order_by_clause']));
  1624. /**
  1625. * Get rid of ASC|DESC
  1626. */
  1627. preg_match('@(.*)([[:space:]]*(ASC|DESC))@si', $sort_expression, $matches);
  1628. $sort_expression_nodirection = isset($matches[1]) ? trim($matches[1]) : $sort_expression;
  1629. $sort_direction = isset($matches[2]) ? trim($matches[2]) : '';
  1630. unset($matches);
  1631. } else {
  1632. $sort_expression = $sort_expression_nodirection = $sort_direction = '';
  1633. }
  1634. // 1.4 Prepares display of first and last value of the sorted column
  1635. if (! empty($sort_expression_nodirection)) {
  1636. list($sort_table, $sort_column) = explode('.', $sort_expression_nodirection);
  1637. $sort_table = PMA_unQuote($sort_table);
  1638. $sort_column = PMA_unQuote($sort_column);
  1639. // find the sorted column index in row result
  1640. // (this might be a multi-table query)
  1641. $sorted_column_index = false;
  1642. foreach($fields_meta as $key => $meta) {
  1643. if ($meta->table == $sort_table && $meta->name == $sort_column) {
  1644. $sorted_column_index = $key;
  1645. break;
  1646. }
  1647. }
  1648. if ($sorted_column_index !== false) {
  1649. // fetch first row of the result set
  1650. $row = PMA_DBI_fetch_row($dt_result);
  1651. $column_for_first_row = $row[$sorted_column_index];
  1652. // fetch last row of the result set
  1653. PMA_DBI_data_seek($dt_result, $num_rows - 1);
  1654. $row = PMA_DBI_fetch_row($dt_result);
  1655. $column_for_last_row = $row[$sorted_column_index];
  1656. // reset to first row for the loop in PMA_displayTableBody()
  1657. PMA_DBI_data_seek($dt_result, 0);
  1658. // we could also use here $sort_expression_nodirection
  1659. $sorted_column_message = ' [' . htmlspecialchars($sort_column) . ': <strong>' . htmlspecialchars($column_for_first_row) . ' - ' . htmlspecialchars($column_for_last_row) . '</strong>]';
  1660. unset($row, $column_for_first_row, $column_for_last_row);
  1661. }
  1662. unset($sorted_column_index, $sort_table, $sort_column);
  1663. }
  1664. // 2. ----- Displays the top of the page -----
  1665. // 2.1 Displays a messages with position informations
  1666. if ($is_display['nav_bar'] == '1' && isset($pos_next)) {
  1667. if (isset($unlim_num_rows) && $unlim_num_rows != $total) {
  1668. $selectstring = ', ' . $unlim_num_rows . ' ' . $GLOBALS['strSelectNumRows'];
  1669. } else {
  1670. $selectstring = '';
  1671. }
  1672. $last_shown_rec = ($_SESSION['userconf']['max_rows'] == 'all' || $pos_next > $total)
  1673. ? $total - 1
  1674. : $pos_next - 1;
  1675. if (PMA_Table::isView($db, $table)
  1676. && $total == $GLOBALS['cfg']['MaxExactCountViews']) {
  1677. $message = PMA_Message::notice('strViewHasAtLeast');
  1678. $message->addParam('[a@./Documentation.html#cfg_MaxExactCount@_blank]');
  1679. $message->addParam('[/a]');
  1680. $message_view_warning = PMA_showHint($message);
  1681. } else {
  1682. $message_view_warning = false;
  1683. }
  1684. $message = PMA_Message::success('strShowingRecords');
  1685. $message->addMessage($_SESSION['userconf']['pos']);
  1686. if ($message_view_warning) {
  1687. $message->addMessage('...', ' - ');
  1688. $message->addMessage($message_view_warning);
  1689. $message->addMessage('(');
  1690. } else {
  1691. $message->addMessage($last_shown_rec, ' - ');
  1692. $message->addMessage($pre_count . PMA_formatNumber($total, 0) . $after_count, ' (');
  1693. $message->addString('strTotal');
  1694. $message->addMessage($selectstring, '');
  1695. $message->addMessage(', ', '');
  1696. }
  1697. $messagge_qt = PMA_Message::notice('strQueryTime');
  1698. $messagge_qt->addParam($GLOBALS['querytime']);
  1699. $message->addMessage($messagge_qt, '');
  1700. $message->addMessage(')', '');
  1701. $message->addMessage(isset($sorted_column_message) ? $sorted_column_message : '', '');
  1702. PMA_showMessage($message, $sql_query, 'success');
  1703. } elseif (!isset($GLOBALS['printview']) || $GLOBALS['printview'] != '1') {
  1704. PMA_showMessage($GLOBALS['strSuccess'], $sql_query, 'success');
  1705. }
  1706. // 2.3 Displays the navigation bars
  1707. if (! strlen($table)) {
  1708. if (isset($analyzed_sql[0]['query_type'])
  1709. && $analyzed_sql[0]['query_type'] == 'SELECT') {
  1710. // table does not always contain a real table name,
  1711. // for example in MySQL 5.0.x, the query SHOW STATUS
  1712. // returns STATUS as a table name
  1713. $table = $fields_meta[0]->table;
  1714. } else {
  1715. $table = '';
  1716. }
  1717. }
  1718. if ($is_display['nav_bar'] == '1') {
  1719. PMA_displayTableNavigation($pos_next, $pos_prev, $sql_query);
  1720. echo "\n";
  1721. } elseif (!isset($GLOBALS['printview']) || $GLOBALS['printview'] != '1') {
  1722. echo "\n" . '<br /><br />' . "\n";
  1723. }
  1724. // 2b ----- Get field references from Database -----
  1725. // (see the 'relation' configuration variable)
  1726. // loic1, 2002-03-02: extended to php3
  1727. // initialize map
  1728. $map = array();
  1729. // find tables
  1730. $target=array();
  1731. if (isset($analyzed_sql[0]['table_ref']) && is_array($analyzed_sql[0]['table_ref'])) {
  1732. foreach ($analyzed_sql[0]['table_ref'] AS $table_ref_position => $table_ref) {
  1733. $target[] = $analyzed_sql[0]['table_ref'][$table_ref_position]['table_true_name'];
  1734. }
  1735. }
  1736. $tabs = '(\'' . join('\',\'', $target) . '\')';
  1737. if ($cfgRelation['displaywork']) {
  1738. if (! strlen($table)) {
  1739. $exist_rel = false;
  1740. } else {
  1741. $exist_rel = PMA_getForeigners($db, $table, '', 'both');
  1742. if ($exist_rel) {
  1743. foreach ($exist_rel AS $master_field => $rel) {
  1744. $display_field = PMA_getDisplayField($rel['foreign_db'], $rel['foreign_table']);
  1745. $map[$master_field] = array($rel['foreign_table'],
  1746. $rel['foreign_field'],
  1747. $display_field,
  1748. $rel['foreign_db']);
  1749. } // end while
  1750. } // end if
  1751. } // end if
  1752. } // end if
  1753. // end 2b
  1754. // 3. ----- Displays the results table -----
  1755. PMA_displayTableHeaders($is_display, $fields_meta, $fields_cnt, $analyzed_sql, $sort_expression, $sort_expression_nodirection, $sort_direction);
  1756. $url_query = '';
  1757. echo '<tbody>' . "\n";
  1758. PMA_displayTableBody($dt_result, $is_display, $map, $analyzed_sql);
  1759. // vertical output case
  1760. if ($_SESSION['userconf']['disp_direction'] == 'vertical') {
  1761. PMA_displayVerticalTable();
  1762. } // end if
  1763. unset($vertical_display);
  1764. echo '</tbody>' . "\n";
  1765. ?>
  1766. </table>
  1767. <?php
  1768. // 4. ----- Displays the link for multi-fields delete
  1769. if ($is_display['del_lnk'] == 'dr' && $is_display['del_lnk'] != 'kp') {
  1770. $delete_text = $is_display['del_lnk'] == 'dr' ? $GLOBALS['strDelete'] : $GLOBALS['strKill'];
  1771. $_url_params = array(
  1772. 'db' => $db,
  1773. 'table' => $table,
  1774. 'sql_query' => $sql_query,
  1775. 'goto' => $goto,
  1776. );
  1777. $uncheckall_url = 'sql.php' . PMA_generate_common_url($_url_params);
  1778. $_url_params['checkall'] = '1';
  1779. $checkall_url = 'sql.php' . PMA_generate_common_url($_url_params);
  1780. if ($_SESSION['userconf']['disp_direction'] == 'vertical') {
  1781. $checkall_params['onclick'] = 'if (setCheckboxes(\'rowsDeleteForm\', true)) return false;';
  1782. $uncheckall_params['onclick'] = 'if (setCheckboxes(\'rowsDeleteForm\', false)) return false;';
  1783. } else {
  1784. $checkall_params['onclick'] = 'if (markAllRows(\'rowsDeleteForm\')) return false;';
  1785. $uncheckall_params['onclick'] = 'if (unMarkAllRows(\'rowsDeleteForm\')) return false;';
  1786. }
  1787. $checkall_link = PMA_linkOrButton($checkall_url, $GLOBALS['strCheckAll'], $checkall_params, false);
  1788. $uncheckall_link = PMA_linkOrButton($uncheckall_url, $GLOBALS['strUncheckAll'], $uncheckall_params, false);
  1789. if ($_SESSION['userconf']['disp_direction'] != 'vertical') {
  1790. echo '<img class="selectallarrow" width="38" height="22"'
  1791. .' src="' . $GLOBALS['pmaThemeImage'] . 'arrow_' . $GLOBALS['text_dir'] . '.png' . '"'
  1792. .' alt="' . $GLOBALS['strWithChecked'] . '" />';
  1793. }
  1794. echo $checkall_link . "\n"
  1795. .' / ' . "\n"
  1796. .$uncheckall_link . "\n"
  1797. .'<i>' . $GLOBALS['strWithChecked'] . '</i>' . "\n";
  1798. PMA_buttonOrImage('submit_mult', 'mult_submit',
  1799. 'submit_mult_change', $GLOBALS['strChange'], 'b_edit.png');
  1800. PMA_buttonOrImage('submit_mult', 'mult_submit',
  1801. 'submit_mult_delete', $delete_text, 'b_drop.png');
  1802. if ($analyzed_sql[0]['querytype'] == 'SELECT') {
  1803. PMA_buttonOrImage('submit_mult', 'mult_submit',
  1804. 'submit_mult_export', $GLOBALS['strExport'],
  1805. 'b_tblexport.png');
  1806. }
  1807. echo "\n";
  1808. echo '<input type="hidden" name="sql_query"'
  1809. .' value="' . htmlspecialchars($sql_query) . '" />' . "\n";
  1810. echo '<input type="hidden" name="url_query"'
  1811. .' value="' . $GLOBALS['url_query'] . '" />' . "\n";
  1812. echo '</form>' . "\n";
  1813. }
  1814. // 5. ----- Displays the navigation bar at the bottom if required -----
  1815. if ($is_display['nav_bar'] == '1') {
  1816. echo '<br />' . "\n";
  1817. PMA_displayTableNavigation($pos_next, $pos_prev, $sql_query);
  1818. } elseif (!isset($GLOBALS['printview']) || $GLOBALS['printview'] != '1') {
  1819. echo "\n" . '<br /><br />' . "\n";
  1820. }
  1821. // 6. ----- Displays "Query results operations"
  1822. if (!isset($GLOBALS['printview']) || $GLOBALS['printview'] != '1') {
  1823. PMA_displayResultsOperations($the_disp_mode, $analyzed_sql);
  1824. }
  1825. } // end of the 'PMA_displayTable()' function
  1826. function default_function($buffer) {
  1827. $buffer = htmlspecialchars($buffer);
  1828. $buffer = str_replace("\011", ' &nbsp;&nbsp;&nbsp;',
  1829. str_replace(' ', ' &nbsp;', $buffer));
  1830. $buffer = preg_replace("@((\015\012)|(\015)|(\012))@", '<br />', $buffer);
  1831. return $buffer;
  1832. }
  1833. /**
  1834. * Displays operations that are available on results.
  1835. *
  1836. * @param array the display mode
  1837. * @param array the analyzed query
  1838. *
  1839. * @uses $_SESSION['userconf']['pos']
  1840. * @uses $_SESSION['userconf']['display_text']
  1841. * @global string $db the database name
  1842. * @global string $table the table name
  1843. * @global string $sql_query the current SQL query
  1844. * @global integer $unlim_num_rows the total number of rows returned by the
  1845. * SQL query without any programmatically
  1846. * appended "LIMIT" clause
  1847. *
  1848. * @access private
  1849. *
  1850. * @see PMA_showMessage(), PMA_setDisplayMode(),
  1851. * PMA_displayTableNavigation(), PMA_displayTableHeaders(),
  1852. * PMA_displayTableBody(), PMA_displayResultsOperations()
  1853. */
  1854. function PMA_displayResultsOperations($the_disp_mode, $analyzed_sql) {
  1855. global $db, $table, $sql_query, $unlim_num_rows;
  1856. $header_shown = FALSE;
  1857. $header = '<fieldset><legend>' . $GLOBALS['strQueryResultsOperations'] . '</legend>';
  1858. if ($the_disp_mode[6] == '1' || $the_disp_mode[9] == '1') {
  1859. // Displays "printable view" link if required
  1860. if ($the_disp_mode[9] == '1') {
  1861. if (!$header_shown) {
  1862. echo $header;
  1863. $header_shown = TRUE;
  1864. }
  1865. $_url_params = array(
  1866. 'db' => $db,
  1867. 'table' => $table,
  1868. 'printview' => '1',
  1869. 'sql_query' => $sql_query,
  1870. );
  1871. $url_query = PMA_generate_common_url($_url_params);
  1872. echo PMA_linkOrButton(
  1873. 'sql.php' . $url_query,
  1874. PMA_getIcon('b_print.png', $GLOBALS['strPrintView'], false, true),
  1875. '', true, true, 'print_view') . "\n";
  1876. if ($_SESSION['userconf']['display_text']) {
  1877. $_url_params['display_text'] = 'F';
  1878. echo PMA_linkOrButton(
  1879. 'sql.php' . PMA_generate_common_url($_url_params),
  1880. PMA_getIcon('b_print.png', $GLOBALS['strPrintViewFull'], false, true),
  1881. '', true, true, 'print_view') . "\n";
  1882. unset($_url_params['display_text']);
  1883. }
  1884. } // end displays "printable view"
  1885. }
  1886. // Export link
  1887. // (the url_query has extra parameters that won't be used to export)
  1888. // (the single_table parameter is used in display_export.lib.php
  1889. // to hide the SQL and the structure export dialogs)
  1890. // If the parser found a PROCEDURE clause
  1891. // (most probably PROCEDURE ANALYSE()) it makes no sense to
  1892. // display the Export link).
  1893. if (isset($analyzed_sql[0]) && $analyzed_sql[0]['querytype'] == 'SELECT' && !isset($printview) && ! isset($analyzed_sql[0]['queryflags']['procedure'])) {
  1894. if (isset($analyzed_sql[0]['table_ref'][0]['table_true_name']) && !isset($analyzed_sql[0]['table_ref'][1]['table_true_name'])) {
  1895. $_url_params['single_table'] = 'true';
  1896. }
  1897. if (!$header_shown) {
  1898. echo $header;
  1899. $header_shown = TRUE;
  1900. }
  1901. $_url_params['unlim_num_rows'] = $unlim_num_rows;
  1902. echo PMA_linkOrButton(
  1903. 'tbl_export.php' . PMA_generate_common_url($_url_params),
  1904. PMA_getIcon('b_tblexport.png', $GLOBALS['strExport'], false, true),
  1905. '', true, true, '') . "\n";
  1906. }
  1907. // CREATE VIEW
  1908. /**
  1909. *
  1910. * @todo detect privileges to create a view
  1911. * (but see 2006-01-19 note in display_create_table.lib.php,
  1912. * I think we cannot detect db-specific privileges reliably)
  1913. * Note: we don't display a Create view link if we found a PROCEDURE clause
  1914. */
  1915. if (!$header_shown) {
  1916. echo $header;
  1917. $header_shown = TRUE;
  1918. }
  1919. if (! isset($analyzed_sql[0]['queryflags']['procedure'])) {
  1920. echo PMA_linkOrButton(
  1921. 'view_create.php' . $url_query,
  1922. PMA_getIcon('b_views.png', 'CREATE VIEW', false, true),
  1923. '', true, true, '') . "\n";
  1924. }
  1925. if ($header_shown) {
  1926. echo '</fieldset><br />';
  1927. }
  1928. }
  1929. /**
  1930. * Verifies what to do with non-printable contents (binary or BLOB)
  1931. * in Browse mode.
  1932. *
  1933. * @uses is_null()
  1934. * @uses isset()
  1935. * @uses strlen()
  1936. * @uses PMA_formatByteDown()
  1937. * @uses strpos()
  1938. * @uses str_replace()
  1939. * @param string $category BLOB|BINARY
  1940. * @param string $content the binary content
  1941. * @param string $transform_function
  1942. * @param string $transform_options
  1943. * @param string $default_function
  1944. * @param object $meta the meta-information about this field
  1945. * @return mixed string or float
  1946. */
  1947. function PMA_handle_non_printable_contents($category, $content, $transform_function, $transform_options, $default_function, $meta) {
  1948. $result = '[' . $category;
  1949. if (is_null($content)) {
  1950. $result .= ' - NULL';
  1951. $size = 0;
  1952. } elseif (isset($content)) {
  1953. $size = strlen($content);
  1954. $display_size = PMA_formatByteDown($size, 3, 1);
  1955. $result .= ' - '. $display_size[0] . $display_size[1];
  1956. }
  1957. $result .= ']';
  1958. if (strpos($transform_function, 'octetstream')) {
  1959. $result = $content;
  1960. }
  1961. if ($size > 0) {
  1962. if ($default_function != $transform_function) {
  1963. $result = $transform_function($result, $transform_options, $meta);
  1964. } else {
  1965. $result = $default_function($result, array(), $meta);
  1966. if (stristr($meta->type, 'BLOB') && $_SESSION['userconf']['display_blob']) {
  1967. // in this case, restart from the original $content
  1968. $result = PMA_replace_binary_contents($content);
  1969. }
  1970. }
  1971. }
  1972. return($result);
  1973. }
  1974. /**
  1975. * Prepares the displayable content of a data cell in Browse mode,
  1976. * taking into account foreign key description field and transformations
  1977. *
  1978. * @uses is_array()
  1979. * @uses PMA_backquote()
  1980. * @uses PMA_DBI_try_query()
  1981. * @uses PMA_DBI_num_rows()
  1982. * @uses PMA_DBI_fetch_row()
  1983. * @uses $GLOBALS['strLinkNotFound']
  1984. * @uses PMA_DBI_free_result()
  1985. * @uses $GLOBALS['printview']
  1986. * @uses htmlspecialchars()
  1987. * @uses PMA_generate_common_url()
  1988. * @param string $mouse_events
  1989. * @param string $class
  1990. * @param string $condition_field
  1991. * @param string $analyzed_sql
  1992. * @param object $meta the meta-information about this field
  1993. * @param string $map
  1994. * @param string $data
  1995. * @param string $transform_function
  1996. * @param string $default_function
  1997. * @param string $nowrap
  1998. * @param string $where_comparison
  1999. * @return string formatted data
  2000. */
  2001. function PMA_prepare_row_data($mouse_events, $class, $condition_field, $analyzed_sql, $meta, $map, $data, $transform_function, $default_function, $nowrap, $where_comparison, $transform_options) {
  2002. // continue the <td> tag started before calling this function:
  2003. $result = $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . $nowrap . '">';
  2004. if (isset($analyzed_sql[0]['select_expr']) && is_array($analyzed_sql[0]['select_expr'])) {
  2005. foreach ($analyzed_sql[0]['select_expr'] AS $select_expr_position => $select_expr) {
  2006. $alias = $analyzed_sql[0]['select_expr'][$select_expr_position]['alias'];
  2007. if (isset($alias) && strlen($alias)) {
  2008. $true_column = $analyzed_sql[0]['select_expr'][$select_expr_position]['column'];
  2009. if ($alias == $meta->name) {
  2010. // this change in the parameter does not matter
  2011. // outside of the function
  2012. $meta->name = $true_column;
  2013. } // end if
  2014. } // end if
  2015. } // end foreach
  2016. } // end if
  2017. if (isset($map[$meta->name])) {
  2018. // Field to display from the foreign table?
  2019. if (isset($map[$meta->name][2]) && strlen($map[$meta->name][2])) {
  2020. $dispsql = 'SELECT ' . PMA_backquote($map[$meta->name][2])
  2021. . ' FROM ' . PMA_backquote($map[$meta->name][3])
  2022. . '.' . PMA_backquote($map[$meta->name][0])
  2023. . ' WHERE ' . PMA_backquote($map[$meta->name][1])
  2024. . $where_comparison;
  2025. $dispresult = PMA_DBI_try_query($dispsql, null, PMA_DBI_QUERY_STORE);
  2026. if ($dispresult && PMA_DBI_num_rows($dispresult) > 0) {
  2027. list($dispval) = PMA_DBI_fetch_row($dispresult, 0);
  2028. } else {
  2029. $dispval = $GLOBALS['strLinkNotFound'];
  2030. }
  2031. @PMA_DBI_free_result($dispresult);
  2032. } else {
  2033. $dispval = '';
  2034. } // end if... else...
  2035. if (isset($GLOBALS['printview']) && $GLOBALS['printview'] == '1') {
  2036. $result .= ($transform_function != $default_function ? $transform_function($data, $transform_options, $meta) : $transform_function($data, array(), $meta)) . ' <code>[-&gt;' . $dispval . ']</code>';
  2037. } else {
  2038. if ('K' == $_SESSION['userconf']['relational_display']) {
  2039. // user chose "relational key" in the display options, so
  2040. // the title contains the display field
  2041. $title = (! empty($dispval))? ' title="' . htmlspecialchars($dispval) . '"' : '';
  2042. } else {
  2043. $title = ' title="' . htmlspecialchars($data) . '"';
  2044. }
  2045. $_url_params = array(
  2046. 'db' => $map[$meta->name][3],
  2047. 'table' => $map[$meta->name][0],
  2048. 'pos' => '0',
  2049. 'sql_query' => 'SELECT * FROM '
  2050. . PMA_backquote($map[$meta->name][3]) . '.' . PMA_backquote($map[$meta->name][0])
  2051. . ' WHERE ' . PMA_backquote($map[$meta->name][1])
  2052. . $where_comparison,
  2053. );
  2054. $result .= '<a href="sql.php' . PMA_generate_common_url($_url_params)
  2055. . '"' . $title . '>';
  2056. if ($transform_function != $default_function) {
  2057. // always apply a transformation on the real data,
  2058. // not on the display field
  2059. $result .= $transform_function($data, $transform_options, $meta);
  2060. } else {
  2061. if ('D' == $_SESSION['userconf']['relational_display']) {
  2062. // user chose "relational display field" in the
  2063. // display options, so show display field in the cell
  2064. $result .= $transform_function($dispval, array(), $meta);
  2065. } else {
  2066. // otherwise display data in the cell
  2067. $result .= $transform_function($data, array(), $meta);
  2068. }
  2069. }
  2070. $result .= '</a>';
  2071. }
  2072. } else {
  2073. $result .= ($transform_function != $default_function ? $transform_function($data, $transform_options, $meta) : $transform_function($data, array(), $meta));
  2074. }
  2075. $result .= '</td>' . "\n";
  2076. return $result;
  2077. }
  2078. ?>