PageRenderTime 56ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/phpMyAdmin/libraries/display_tbl.lib.php

https://bitbucket.org/izubizarreta/https-bitbucket.org-bityvip
PHP | 3032 lines | 2005 code | 296 blank | 731 comment | 805 complexity | b1192d9b97f18248da9ad85cef982a2c MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.0, JSON, GPL-2.0, BSD-3-Clause, LGPL-2.1, MIT

Large files files are truncated, but you can click here to view the full file

  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. * @package PhpMyAdmin
  7. */
  8. /**
  9. *
  10. */
  11. require_once './libraries/Index.class.php';
  12. /**
  13. * Defines the display mode to use for the results of a SQL query
  14. *
  15. * It uses a synthetic string that contains all the required informations.
  16. * In this string:
  17. * - the first two characters stand for the action to do while
  18. * clicking on the "edit" link (e.g. 'ur' for update a row, 'nn' for no
  19. * edit link...);
  20. * - the next two characters stand for the action to do while
  21. * clicking on the "delete" link (e.g. 'kp' for kill a process, 'nn' for
  22. * no delete link...);
  23. * - the next characters are boolean values (1/0) and respectively stand
  24. * for sorting links, navigation bar, "insert a new row" link, the
  25. * bookmark feature, the expand/collapse text/blob fields button and
  26. * the "display printable view" option.
  27. * Of course '0'/'1' means the feature won't/will be enabled.
  28. *
  29. * @param string &$the_disp_mode the synthetic value for display_mode (see a few
  30. * lines above for explanations)
  31. * @param integer &$the_total the total number of rows returned by the SQL query
  32. * without any programmatically appended "LIMIT" clause
  33. * (just a copy of $unlim_num_rows if it exists, else
  34. * computed inside this function)
  35. *
  36. * @return array an array with explicit indexes for all the display
  37. * elements
  38. *
  39. * @global string the database name
  40. * @global string the table name
  41. * @global integer the total number of rows returned by the SQL query
  42. * without any programmatically appended "LIMIT" clause
  43. * @global array the properties of the fields returned by the query
  44. * @global string the URL to return to in case of error in a SQL
  45. * statement
  46. *
  47. * @access private
  48. *
  49. * @see PMA_displayTable()
  50. */
  51. function PMA_setDisplayMode(&$the_disp_mode, &$the_total)
  52. {
  53. global $db, $table;
  54. global $unlim_num_rows, $fields_meta;
  55. global $err_url;
  56. // 1. Initializes the $do_display array
  57. $do_display = array();
  58. $do_display['edit_lnk'] = $the_disp_mode[0] . $the_disp_mode[1];
  59. $do_display['del_lnk'] = $the_disp_mode[2] . $the_disp_mode[3];
  60. $do_display['sort_lnk'] = (string) $the_disp_mode[4];
  61. $do_display['nav_bar'] = (string) $the_disp_mode[5];
  62. $do_display['ins_row'] = (string) $the_disp_mode[6];
  63. $do_display['bkm_form'] = (string) $the_disp_mode[7];
  64. $do_display['text_btn'] = (string) $the_disp_mode[8];
  65. $do_display['pview_lnk'] = (string) $the_disp_mode[9];
  66. // 2. Display mode is not "false for all elements" -> updates the
  67. // display mode
  68. if ($the_disp_mode != 'nnnn000000') {
  69. if (isset($GLOBALS['printview']) && $GLOBALS['printview'] == '1') {
  70. // 2.0 Print view -> set all elements to false!
  71. $do_display['edit_lnk'] = 'nn'; // no edit link
  72. $do_display['del_lnk'] = 'nn'; // no delete link
  73. $do_display['sort_lnk'] = (string) '0';
  74. $do_display['nav_bar'] = (string) '0';
  75. $do_display['ins_row'] = (string) '0';
  76. $do_display['bkm_form'] = (string) '0';
  77. $do_display['text_btn'] = (string) '0';
  78. $do_display['pview_lnk'] = (string) '0';
  79. } elseif ($GLOBALS['is_count'] || $GLOBALS['is_analyse']
  80. || $GLOBALS['is_maint'] || $GLOBALS['is_explain']
  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. $do_display['edit_lnk'] = 'nn'; // no edit link
  86. $do_display['del_lnk'] = 'nn'; // no delete link
  87. $do_display['sort_lnk'] = (string) '0';
  88. $do_display['nav_bar'] = (string) '0';
  89. $do_display['ins_row'] = (string) '0';
  90. $do_display['bkm_form'] = (string) '1';
  91. if ($GLOBALS['is_maint']) {
  92. $do_display['text_btn'] = (string) '1';
  93. } else {
  94. $do_display['text_btn'] = (string) '0';
  95. }
  96. $do_display['pview_lnk'] = (string) '1';
  97. } elseif ($GLOBALS['is_show']) {
  98. // 2.2 Statement is a "SHOW..."
  99. /**
  100. * 2.2.1
  101. * @todo defines edit/delete links depending on show statement
  102. */
  103. $tmp = preg_match('@^SHOW[[:space:]]+(VARIABLES|(FULL[[:space:]]+)?PROCESSLIST|STATUS|TABLE|GRANTS|CREATE|LOGS|DATABASES|FIELDS)@i', $GLOBALS['sql_query'], $which);
  104. if (isset($which[1]) && strpos(' ' . strtoupper($which[1]), 'PROCESSLIST') > 0) {
  105. $do_display['edit_lnk'] = 'nn'; // no edit link
  106. $do_display['del_lnk'] = 'kp'; // "kill process" type edit link
  107. } else {
  108. // Default case -> no links
  109. $do_display['edit_lnk'] = 'nn'; // no edit link
  110. $do_display['del_lnk'] = 'nn'; // no delete link
  111. }
  112. // 2.2.2 Other settings
  113. $do_display['sort_lnk'] = (string) '0';
  114. $do_display['nav_bar'] = (string) '0';
  115. $do_display['ins_row'] = (string) '0';
  116. $do_display['bkm_form'] = (string) '1';
  117. $do_display['text_btn'] = (string) '1';
  118. $do_display['pview_lnk'] = (string) '1';
  119. } else {
  120. // 2.3 Other statements (ie "SELECT" ones) -> updates
  121. // $do_display['edit_lnk'], $do_display['del_lnk'] and
  122. // $do_display['text_btn'] (keeps other default values)
  123. $prev_table = $fields_meta[0]->table;
  124. $do_display['text_btn'] = (string) '1';
  125. for ($i = 0; $i < $GLOBALS['fields_cnt']; $i++) {
  126. $is_link = ($do_display['edit_lnk'] != 'nn'
  127. || $do_display['del_lnk'] != 'nn'
  128. || $do_display['sort_lnk'] != '0'
  129. || $do_display['ins_row'] != '0');
  130. // 2.3.2 Displays edit/delete/sort/insert links?
  131. if ($is_link
  132. && ($fields_meta[$i]->table == '' || $fields_meta[$i]->table != $prev_table)
  133. ) {
  134. $do_display['edit_lnk'] = 'nn'; // don't display links
  135. $do_display['del_lnk'] = 'nn';
  136. /**
  137. * @todo May be problematic with same fields names in two joined table.
  138. */
  139. // $do_display['sort_lnk'] = (string) '0';
  140. $do_display['ins_row'] = (string) '0';
  141. if ($do_display['text_btn'] == '1') {
  142. break;
  143. }
  144. } // end if (2.3.2)
  145. // 2.3.3 Always display print view link
  146. $do_display['pview_lnk'] = (string) '1';
  147. $prev_table = $fields_meta[$i]->table;
  148. } // end for
  149. } // end if..elseif...else (2.1 -> 2.3)
  150. } // end if (2)
  151. // 3. Gets the total number of rows if it is unknown
  152. if (isset($unlim_num_rows) && $unlim_num_rows != '') {
  153. $the_total = $unlim_num_rows;
  154. } elseif (($do_display['nav_bar'] == '1' || $do_display['sort_lnk'] == '1')
  155. && (strlen($db) && !empty($table))) {
  156. $the_total = PMA_Table::countRecords($db, $table);
  157. }
  158. // 4. If navigation bar or sorting fields names URLs should be
  159. // displayed but there is only one row, change these settings to
  160. // false
  161. if ($do_display['nav_bar'] == '1' || $do_display['sort_lnk'] == '1') {
  162. // - Do not display sort links if less than 2 rows.
  163. // - For a VIEW we (probably) did not count the number of rows
  164. // so don't test this number here, it would remove the possibility
  165. // of sorting VIEW results.
  166. if (isset($unlim_num_rows) && $unlim_num_rows < 2 && ! PMA_Table::isView($db, $table)) {
  167. // force display of navbar for vertical/horizontal display-choice.
  168. // $do_display['nav_bar'] = (string) '0';
  169. $do_display['sort_lnk'] = (string) '0';
  170. }
  171. } // end if (3)
  172. // 5. Updates the synthetic var
  173. $the_disp_mode = join('', $do_display);
  174. return $do_display;
  175. } // end of the 'PMA_setDisplayMode()' function
  176. /**
  177. * Return true if we are executing a query in the form of
  178. * "SELECT * FROM <a table> ..."
  179. *
  180. * @return boolean
  181. */
  182. function PMA_isSelect()
  183. {
  184. // global variables set from sql.php
  185. global $is_count, $is_export, $is_func, $is_analyse;
  186. global $analyzed_sql;
  187. return ! ($is_count || $is_export || $is_func || $is_analyse)
  188. && count($analyzed_sql[0]['select_expr']) == 0
  189. && isset($analyzed_sql[0]['queryflags']['select_from'])
  190. && count($analyzed_sql[0]['table_ref']) == 1;
  191. }
  192. /**
  193. * Displays a navigation button
  194. *
  195. * @param string $caption iconic caption for button
  196. * @param string $title text for button
  197. * @param integer $pos position for next query
  198. * @param string $html_sql_query query ready for display
  199. * @param string $onsubmit optional onsubmit clause
  200. * @param string $input_for_real_end optional hidden field for special treatment
  201. * @param string $onclick optional onclick clause
  202. *
  203. * @return nothing
  204. *
  205. * @global string $db the database name
  206. * @global string $table the table name
  207. * @global string $goto the URL to go back in case of errors
  208. *
  209. * @access private
  210. *
  211. * @see PMA_displayTableNavigation()
  212. */
  213. function PMA_displayTableNavigationOneButton($caption, $title, $pos, $html_sql_query, $onsubmit = '', $input_for_real_end = '', $onclick = '')
  214. {
  215. global $db, $table, $goto;
  216. $caption_output = '';
  217. // for true or 'both'
  218. if ($GLOBALS['cfg']['NavigationBarIconic']) {
  219. $caption_output .= $caption;
  220. }
  221. // for false or 'both'
  222. if (false === $GLOBALS['cfg']['NavigationBarIconic'] || 'both' === $GLOBALS['cfg']['NavigationBarIconic']) {
  223. $caption_output .= '&nbsp;' . $title;
  224. }
  225. $title_output = ' title="' . $title . '"';
  226. ?>
  227. <td>
  228. <form action="sql.php" method="post" <?php echo $onsubmit; ?>>
  229. <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
  230. <input type="hidden" name="sql_query" value="<?php echo $html_sql_query; ?>" />
  231. <input type="hidden" name="pos" value="<?php echo $pos; ?>" />
  232. <input type="hidden" name="goto" value="<?php echo $goto; ?>" />
  233. <?php echo $input_for_real_end; ?>
  234. <input type="submit" name="navig" <?php echo ($GLOBALS['cfg']['AjaxEnable'] ? ' class="ajax" ' : '' ); ?> value="<?php echo $caption_output; ?>"<?php echo $title_output . $onclick; ?> />
  235. </form>
  236. </td>
  237. <?php
  238. } // end function PMA_displayTableNavigationOneButton()
  239. /**
  240. * Displays a navigation bar to browse among the results of a SQL query
  241. *
  242. * @param integer $pos_next the offset for the "next" page
  243. * @param integer $pos_prev the offset for the "previous" page
  244. * @param string $sql_query the URL-encoded query
  245. * @param string $id_for_direction_dropdown the id for the direction dropdown
  246. *
  247. * @return nothing
  248. *
  249. * @global string $db the database name
  250. * @global string $table the table name
  251. * @global string $goto the URL to go back in case of errors
  252. * @global integer $num_rows the total number of rows returned by the
  253. * SQL query
  254. * @global integer $unlim_num_rows the total number of rows returned by the
  255. * SQL any programmatically appended "LIMIT" clause
  256. * @global boolean $is_innodb whether its InnoDB or not
  257. * @global array $showtable table definitions
  258. *
  259. * @access private
  260. *
  261. * @see PMA_displayTable()
  262. */
  263. function PMA_displayTableNavigation($pos_next, $pos_prev, $sql_query, $id_for_direction_dropdown)
  264. {
  265. global $db, $table, $goto;
  266. global $num_rows, $unlim_num_rows;
  267. global $is_innodb;
  268. global $showtable;
  269. // here, using htmlentities() would cause problems if the query
  270. // contains accented characters
  271. $html_sql_query = htmlspecialchars($sql_query);
  272. /**
  273. * @todo move this to a central place
  274. * @todo for other future table types
  275. */
  276. $is_innodb = (isset($showtable['Type']) && $showtable['Type'] == 'InnoDB');
  277. ?>
  278. <!-- Navigation bar -->
  279. <table border="0" cellpadding="0" cellspacing="0" class="navigation">
  280. <tr>
  281. <td class="navigation_separator"></td>
  282. <?php
  283. // Move to the beginning or to the previous page
  284. if ($_SESSION['tmp_user_values']['pos'] && $_SESSION['tmp_user_values']['max_rows'] != 'all') {
  285. PMA_displayTableNavigationOneButton('&lt;&lt;', _pgettext('First page', 'Begin'), 0, $html_sql_query);
  286. PMA_displayTableNavigationOneButton('&lt;', _pgettext('Previous page', 'Previous'), $pos_prev, $html_sql_query);
  287. } // end move back
  288. $nbTotalPage = 1;
  289. //page redirection
  290. // (unless we are showing all records)
  291. if ('all' != $_SESSION['tmp_user_values']['max_rows']) { //if1
  292. $pageNow = @floor($_SESSION['tmp_user_values']['pos'] / $_SESSION['tmp_user_values']['max_rows']) + 1;
  293. $nbTotalPage = @ceil($unlim_num_rows / $_SESSION['tmp_user_values']['max_rows']);
  294. if ($nbTotalPage > 1) { //if2
  295. ?>
  296. <td>
  297. <?php
  298. $_url_params = array(
  299. 'db' => $db,
  300. 'table' => $table,
  301. 'sql_query' => $sql_query,
  302. 'goto' => $goto,
  303. );
  304. //<form> to keep the form alignment of button < and <<
  305. // and also to know what to execute when the selector changes
  306. echo '<form action="sql.php' . PMA_generate_common_url($_url_params). '" method="post">';
  307. echo PMA_pageselector(
  308. $_SESSION['tmp_user_values']['max_rows'],
  309. $pageNow,
  310. $nbTotalPage,
  311. 200,
  312. 5,
  313. 5,
  314. 20,
  315. 10
  316. );
  317. ?>
  318. </form>
  319. </td>
  320. <?php
  321. } //_if2
  322. } //_if1
  323. // Display the "Show all" button if allowed
  324. if (($num_rows < $unlim_num_rows) && ($GLOBALS['cfg']['ShowAll'] || ($GLOBALS['cfg']['MaxRows'] * 5 >= $unlim_num_rows))) {
  325. echo "\n";
  326. ?>
  327. <td>
  328. <form action="sql.php" method="post">
  329. <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
  330. <input type="hidden" name="sql_query" value="<?php echo $html_sql_query; ?>" />
  331. <input type="hidden" name="pos" value="0" />
  332. <input type="hidden" name="session_max_rows" value="all" />
  333. <input type="hidden" name="goto" value="<?php echo $goto; ?>" />
  334. <input type="submit" name="navig" value="<?php echo __('Show all'); ?>" />
  335. </form>
  336. </td>
  337. <?php
  338. } // end show all
  339. // Move to the next page or to the last one
  340. if (($_SESSION['tmp_user_values']['pos'] + $_SESSION['tmp_user_values']['max_rows'] < $unlim_num_rows)
  341. && $num_rows >= $_SESSION['tmp_user_values']['max_rows']
  342. && $_SESSION['tmp_user_values']['max_rows'] != 'all'
  343. ) {
  344. // display the Next button
  345. PMA_displayTableNavigationOneButton(
  346. '&gt;',
  347. _pgettext('Next page', 'Next'),
  348. $pos_next,
  349. $html_sql_query
  350. );
  351. // prepare some options for the End button
  352. if ($is_innodb && $unlim_num_rows > $GLOBALS['cfg']['MaxExactCount']) {
  353. $input_for_real_end = '<input id="real_end_input" type="hidden" name="find_real_end" value="1" />';
  354. // no backquote around this message
  355. $onclick = '';
  356. } else {
  357. $input_for_real_end = $onclick = '';
  358. }
  359. // display the End button
  360. PMA_displayTableNavigationOneButton(
  361. '&gt;&gt;',
  362. _pgettext('Last page', 'End'),
  363. @((ceil($unlim_num_rows / $_SESSION['tmp_user_values']['max_rows'])- 1) * $_SESSION['tmp_user_values']['max_rows']),
  364. $html_sql_query,
  365. 'onsubmit="return ' . (($_SESSION['tmp_user_values']['pos'] + $_SESSION['tmp_user_values']['max_rows'] < $unlim_num_rows && $num_rows >= $_SESSION['tmp_user_values']['max_rows']) ? 'true' : 'false') . '"',
  366. $input_for_real_end,
  367. $onclick
  368. );
  369. } // end move toward
  370. // show separator if pagination happen
  371. if ($nbTotalPage > 1) {
  372. echo '<td><div class="navigation_separator">|</div></td>';
  373. }
  374. ?>
  375. <td>
  376. <div class="save_edited hide">
  377. <input type="submit" value="<?php echo __('Save edited data'); ?>" />
  378. <div class="navigation_separator">|</div>
  379. </div>
  380. </td>
  381. <td>
  382. <div class="restore_column hide">
  383. <input type="submit" value="<?php echo __('Restore column order'); ?>" />
  384. <div class="navigation_separator">|</div>
  385. </div>
  386. </td>
  387. <?php // if displaying a VIEW, $unlim_num_rows could be zero because
  388. // of $cfg['MaxExactCountViews']; in this case, avoid passing
  389. // the 5th parameter to checkFormElementInRange()
  390. // (this means we can't validate the upper limit ?>
  391. <td class="navigation_goto">
  392. <form action="sql.php" method="post"
  393. onsubmit="return (checkFormElementInRange(this, 'session_max_rows', '<?php echo str_replace('\'', '\\\'', __('%d is not valid row number.')); ?>', 1) &amp;&amp; checkFormElementInRange(this, 'pos', '<?php echo str_replace('\'', '\\\'', __('%d is not valid row number.')); ?>', 0<?php echo $unlim_num_rows > 0 ? ',' . $unlim_num_rows - 1 : ''; ?>))">
  394. <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
  395. <input type="hidden" name="sql_query" value="<?php echo $html_sql_query; ?>" />
  396. <input type="hidden" name="goto" value="<?php echo $goto; ?>" />
  397. <input type="submit" name="navig" <?php echo ($GLOBALS['cfg']['AjaxEnable'] ? ' class="ajax"' : ''); ?> value="<?php echo __('Show'); ?> :" />
  398. <?php echo __('Start row') . ': ' . "\n"; ?>
  399. <input type="text" name="pos" size="3" value="<?php echo (($pos_next >= $unlim_num_rows) ? 0 : $pos_next); ?>" class="textfield" onfocus="this.select()" />
  400. <?php echo __('Number of rows') . ': ' . "\n"; ?>
  401. <input type="text" name="session_max_rows" size="3" value="<?php echo (($_SESSION['tmp_user_values']['max_rows'] != 'all') ? $_SESSION['tmp_user_values']['max_rows'] : $GLOBALS['cfg']['MaxRows']); ?>" class="textfield" onfocus="this.select()" />
  402. <?php
  403. if ($GLOBALS['cfg']['ShowDisplayDirection']) {
  404. // Display mode (horizontal/vertical and repeat headers)
  405. echo __('Mode') . ': ' . "\n";
  406. $choices = array(
  407. 'horizontal' => __('horizontal'),
  408. 'horizontalflipped' => __('horizontal (rotated headers)'),
  409. 'vertical' => __('vertical'));
  410. echo PMA_generate_html_dropdown('disp_direction', $choices, $_SESSION['tmp_user_values']['disp_direction'], $id_for_direction_dropdown);
  411. unset($choices);
  412. }
  413. printf(
  414. __('Headers every %s rows'),
  415. '<input type="text" size="3" name="repeat_cells" value="' . $_SESSION['tmp_user_values']['repeat_cells'] . '" class="textfield" />'
  416. );
  417. echo "\n";
  418. ?>
  419. </form>
  420. </td>
  421. <td class="navigation_separator"></td>
  422. </tr>
  423. </table>
  424. <?php
  425. } // end of the 'PMA_displayTableNavigation()' function
  426. /**
  427. * Displays the headers of the results table
  428. *
  429. * @param array &$is_display which elements to display
  430. * @param array &$fields_meta the list of fields properties
  431. * @param integer $fields_cnt the total number of fields returned by the SQL query
  432. * @param array $analyzed_sql the analyzed query
  433. * @param string $sort_expression sort expression
  434. * @param string $sort_expression_nodirection sort expression without direction
  435. * @param string $sort_direction sort direction
  436. *
  437. * @return boolean $clause_is_unique
  438. *
  439. * @global string $db the database name
  440. * @global string $table the table name
  441. * @global string $goto the URL to go back in case of errors
  442. * @global string $sql_query the SQL query
  443. * @global integer $num_rows the total number of rows returned by the
  444. * SQL query
  445. * @global array $vertical_display informations used with vertical display
  446. * mode
  447. *
  448. * @access private
  449. *
  450. * @see PMA_displayTable()
  451. */
  452. function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $analyzed_sql = '', $sort_expression, $sort_expression_nodirection, $sort_direction)
  453. {
  454. global $db, $table, $goto;
  455. global $sql_query, $num_rows;
  456. global $vertical_display, $highlight_columns;
  457. // required to generate sort links that will remember whether the
  458. // "Show all" button has been clicked
  459. $sql_md5 = md5($GLOBALS['sql_query']);
  460. $session_max_rows = $_SESSION['tmp_user_values']['query'][$sql_md5]['max_rows'];
  461. if ($analyzed_sql == '') {
  462. $analyzed_sql = array();
  463. }
  464. // can the result be sorted?
  465. if ($is_display['sort_lnk'] == '1') {
  466. // Just as fallback
  467. $unsorted_sql_query = $sql_query;
  468. if (isset($analyzed_sql[0]['unsorted_query'])) {
  469. $unsorted_sql_query = $analyzed_sql[0]['unsorted_query'];
  470. }
  471. // Handles the case of multiple clicks on a column's header
  472. // which would add many spaces before "ORDER BY" in the
  473. // generated query.
  474. $unsorted_sql_query = trim($unsorted_sql_query);
  475. // sorting by indexes, only if it makes sense (only one table ref)
  476. if (isset($analyzed_sql)
  477. && isset($analyzed_sql[0])
  478. && isset($analyzed_sql[0]['querytype'])
  479. && $analyzed_sql[0]['querytype'] == 'SELECT'
  480. && isset($analyzed_sql[0]['table_ref'])
  481. && count($analyzed_sql[0]['table_ref']) == 1
  482. ) {
  483. // grab indexes data:
  484. $indexes = PMA_Index::getFromTable($table, $db);
  485. // do we have any index?
  486. if ($indexes) {
  487. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal'
  488. || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped'
  489. ) {
  490. $span = $fields_cnt;
  491. if ($is_display['edit_lnk'] != 'nn') {
  492. $span++;
  493. }
  494. if ($is_display['del_lnk'] != 'nn') {
  495. $span++;
  496. }
  497. if ($is_display['del_lnk'] != 'kp' && $is_display['del_lnk'] != 'nn') {
  498. $span++;
  499. }
  500. } else {
  501. $span = $num_rows + floor($num_rows/$_SESSION['tmp_user_values']['repeat_cells']) + 1;
  502. }
  503. echo '<form action="sql.php" method="post">' . "\n";
  504. echo PMA_generate_common_hidden_inputs($db, $table);
  505. echo __('Sort by key') . ': <select name="sql_query" class="autosubmit">' . "\n";
  506. $used_index = false;
  507. $local_order = (isset($sort_expression) ? $sort_expression : '');
  508. foreach ($indexes as $index) {
  509. $asc_sort = '`' . implode('` ASC, `', array_keys($index->getColumns())) . '` ASC';
  510. $desc_sort = '`' . implode('` DESC, `', array_keys($index->getColumns())) . '` DESC';
  511. $used_index = $used_index || $local_order == $asc_sort || $local_order == $desc_sort;
  512. if (preg_match('@(.*)([[:space:]](LIMIT (.*)|PROCEDURE (.*)|FOR UPDATE|LOCK IN SHARE MODE))@is', $unsorted_sql_query, $my_reg)) {
  513. $unsorted_sql_query_first_part = $my_reg[1];
  514. $unsorted_sql_query_second_part = $my_reg[2];
  515. } else {
  516. $unsorted_sql_query_first_part = $unsorted_sql_query;
  517. $unsorted_sql_query_second_part = '';
  518. }
  519. echo '<option value="'
  520. . htmlspecialchars($unsorted_sql_query_first_part . "\n" . ' ORDER BY ' . $asc_sort . $unsorted_sql_query_second_part)
  521. . '"' . ($local_order == $asc_sort ? ' selected="selected"' : '')
  522. . '>' . htmlspecialchars($index->getName()) . ' ('
  523. . __('Ascending') . ')</option>';
  524. echo '<option value="'
  525. . htmlspecialchars($unsorted_sql_query_first_part . "\n" . ' ORDER BY ' . $desc_sort . $unsorted_sql_query_second_part)
  526. . '"' . ($local_order == $desc_sort ? ' selected="selected"' : '')
  527. . '>' . htmlspecialchars($index->getName()) . ' ('
  528. . __('Descending') . ')</option>';
  529. }
  530. echo '<option value="' . htmlspecialchars($unsorted_sql_query) . '"' . ($used_index ? '' : ' selected="selected"') . '>' . __('None') . '</option>';
  531. echo '</select>' . "\n";
  532. echo '<noscript><input type="submit" value="' . __('Go') . '" /></noscript>';
  533. echo '</form>' . "\n";
  534. }
  535. }
  536. }
  537. // Output data needed for grid editing
  538. echo '<input id="save_cells_at_once" type="hidden" value="' . $GLOBALS['cfg']['SaveCellsAtOnce'] . '" />';
  539. echo '<div class="common_hidden_inputs">';
  540. echo PMA_generate_common_hidden_inputs($db, $table);
  541. echo '</div>';
  542. // Output data needed for column reordering and show/hide column
  543. if (PMA_isSelect()) {
  544. // generate the column order, if it is set
  545. $pmatable = new PMA_Table($GLOBALS['table'], $GLOBALS['db']);
  546. $col_order = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_ORDER);
  547. if ($col_order) {
  548. echo '<input id="col_order" type="hidden" value="' . implode(',', $col_order) . '" />';
  549. }
  550. $col_visib = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_VISIB);
  551. if ($col_visib) {
  552. echo '<input id="col_visib" type="hidden" value="' . implode(',', $col_visib) . '" />';
  553. }
  554. // generate table create time
  555. if (! PMA_Table::isView($GLOBALS['table'], $GLOBALS['db'])) {
  556. echo '<input id="table_create_time" type="hidden" value="' .
  557. PMA_Table::sGetStatusInfo($GLOBALS['db'], $GLOBALS['table'], 'Create_time') . '" />';
  558. }
  559. }
  560. $vertical_display['emptypre'] = 0;
  561. $vertical_display['emptyafter'] = 0;
  562. $vertical_display['textbtn'] = '';
  563. // Display options (if we are not in print view)
  564. if (! (isset($GLOBALS['printview']) && $GLOBALS['printview'] == '1')) {
  565. echo '<form method="post" action="sql.php" name="displayOptionsForm" id="displayOptionsForm"';
  566. if ($GLOBALS['cfg']['AjaxEnable']) {
  567. echo ' class="ajax" ';
  568. }
  569. echo '>';
  570. $url_params = array(
  571. 'db' => $db,
  572. 'table' => $table,
  573. 'sql_query' => $sql_query,
  574. 'goto' => $goto,
  575. 'display_options_form' => 1
  576. );
  577. echo PMA_generate_common_hidden_inputs($url_params);
  578. echo '<br />';
  579. PMA_generate_slider_effect('displayoptions', __('Options'));
  580. echo '<fieldset>';
  581. echo '<div class="formelement">';
  582. $choices = array(
  583. 'P' => __('Partial texts'),
  584. 'F' => __('Full texts')
  585. );
  586. PMA_display_html_radio('display_text', $choices, $_SESSION['tmp_user_values']['display_text']);
  587. echo '</div>';
  588. // prepare full/partial text button or link
  589. $url_params_full_text = array(
  590. 'db' => $db,
  591. 'table' => $table,
  592. 'sql_query' => $sql_query,
  593. 'goto' => $goto,
  594. 'full_text_button' => 1
  595. );
  596. if ($_SESSION['tmp_user_values']['display_text']=='F') {
  597. // currently in fulltext mode so show the opposite link
  598. $tmp_image_file = $GLOBALS['pmaThemeImage'] . 's_partialtext.png';
  599. $tmp_txt = __('Partial texts');
  600. $url_params_full_text['display_text'] = 'P';
  601. } else {
  602. $tmp_image_file = $GLOBALS['pmaThemeImage'] . 's_fulltext.png';
  603. $tmp_txt = __('Full texts');
  604. $url_params_full_text['display_text'] = 'F';
  605. }
  606. $tmp_image = '<img class="fulltext" src="' . $tmp_image_file . '" alt="' . $tmp_txt . '" title="' . $tmp_txt . '" />';
  607. $tmp_url = 'sql.php' . PMA_generate_common_url($url_params_full_text);
  608. $full_or_partial_text_link = PMA_linkOrButton($tmp_url, $tmp_image, array(), false);
  609. unset($tmp_image_file, $tmp_txt, $tmp_url, $tmp_image);
  610. if ($GLOBALS['cfgRelation']['relwork'] && $GLOBALS['cfgRelation']['displaywork']) {
  611. echo '<div class="formelement">';
  612. $choices = array(
  613. 'K' => __('Relational key'),
  614. 'D' => __('Relational display column')
  615. );
  616. PMA_display_html_radio('relational_display', $choices, $_SESSION['tmp_user_values']['relational_display']);
  617. echo '</div>';
  618. }
  619. echo '<div class="formelement">';
  620. PMA_display_html_checkbox('display_binary', __('Show binary contents'), ! empty($_SESSION['tmp_user_values']['display_binary']), false);
  621. echo '<br />';
  622. PMA_display_html_checkbox('display_blob', __('Show BLOB contents'), ! empty($_SESSION['tmp_user_values']['display_blob']), false);
  623. echo '<br />';
  624. PMA_display_html_checkbox('display_binary_as_hex', __('Show binary contents as HEX'), ! empty($_SESSION['tmp_user_values']['display_binary_as_hex']), false);
  625. echo '</div>';
  626. // I would have preferred to name this "display_transformation".
  627. // This is the only way I found to be able to keep this setting sticky
  628. // per SQL query, and at the same time have a default that displays
  629. // the transformations.
  630. echo '<div class="formelement">';
  631. PMA_display_html_checkbox('hide_transformation', __('Hide browser transformation'), ! empty($_SESSION['tmp_user_values']['hide_transformation']), false);
  632. echo '</div>';
  633. if (! PMA_DRIZZLE) {
  634. echo '<div class="formelement">';
  635. $choices = array(
  636. 'GEOM' => __('Geometry'),
  637. 'WKT' => __('Well Known Text'),
  638. 'WKB' => __('Well Known Binary')
  639. );
  640. PMA_display_html_radio('geometry_display', $choices, $_SESSION['tmp_user_values']['geometry_display']);
  641. echo '</div>';
  642. }
  643. echo '<div class="clearfloat"></div>';
  644. echo '</fieldset>';
  645. echo '<fieldset class="tblFooters">';
  646. echo '<input type="submit" value="' . __('Go') . '" />';
  647. echo '</fieldset>';
  648. echo '</div>';
  649. echo '</form>';
  650. }
  651. // Start of form for multi-rows edit/delete/export
  652. if ($is_display['del_lnk'] == 'dr' || $is_display['del_lnk'] == 'kp') {
  653. echo '<form method="post" action="tbl_row_action.php" name="resultsForm" id="resultsForm"';
  654. if ($GLOBALS['cfg']['AjaxEnable']) {
  655. echo ' class="ajax" ';
  656. }
  657. echo '>' . "\n";
  658. echo PMA_generate_common_hidden_inputs($db, $table, 1);
  659. echo '<input type="hidden" name="goto" value="sql.php" />' . "\n";
  660. }
  661. echo '<table id="table_results" class="data';
  662. if ($GLOBALS['cfg']['AjaxEnable']) {
  663. echo ' ajax';
  664. }
  665. echo '">' . "\n";
  666. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal'
  667. || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped'
  668. ) {
  669. echo '<thead><tr>' . "\n";
  670. }
  671. // 1. Displays the full/partial text button (part 1)...
  672. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal'
  673. || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped'
  674. ) {
  675. $colspan = ($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn')
  676. ? ' colspan="4"'
  677. : '';
  678. } else {
  679. $rowspan = ($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn')
  680. ? ' rowspan="4"'
  681. : '';
  682. }
  683. // ... before the result table
  684. if (($is_display['edit_lnk'] == 'nn' && $is_display['del_lnk'] == 'nn')
  685. && $is_display['text_btn'] == '1'
  686. ) {
  687. $vertical_display['emptypre'] = ($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn') ? 4 : 0;
  688. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal'
  689. || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped'
  690. ) {
  691. ?>
  692. <th colspan="<?php echo $fields_cnt; ?>"></th>
  693. </tr>
  694. <tr>
  695. <?php
  696. // end horizontal/horizontalflipped mode
  697. } else {
  698. ?>
  699. <tr>
  700. <th colspan="<?php echo $num_rows + floor($num_rows/$_SESSION['tmp_user_values']['repeat_cells']) + 1; ?>"></th>
  701. </tr>
  702. <?php
  703. } // end vertical mode
  704. }
  705. // ... at the left column of the result table header if possible
  706. // and required
  707. elseif (($GLOBALS['cfg']['RowActionLinks'] == 'left' || $GLOBALS['cfg']['RowActionLinks'] == 'both')
  708. && $is_display['text_btn'] == '1'
  709. ) {
  710. $vertical_display['emptypre'] = ($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn') ? 4 : 0;
  711. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal'
  712. || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped'
  713. ) {
  714. ?>
  715. <th <?php echo $colspan; ?>><?php echo $full_or_partial_text_link;?></th>
  716. <?php
  717. // end horizontal/horizontalflipped mode
  718. } else {
  719. $vertical_display['textbtn'] = ' <th ' . $rowspan . ' valign="middle">' . "\n"
  720. . ' ' . "\n"
  721. . ' </th>' . "\n";
  722. } // end vertical mode
  723. }
  724. // ... elseif no button, displays empty(ies) col(s) if required
  725. elseif (($GLOBALS['cfg']['RowActionLinks'] == 'left' || $GLOBALS['cfg']['RowActionLinks'] == 'both')
  726. && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn')) {
  727. $vertical_display['emptypre'] = ($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn') ? 4 : 0;
  728. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal'
  729. || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped'
  730. ) {
  731. ?>
  732. <td<?php echo $colspan; ?>></td>
  733. <?php
  734. // end horizontal/horizontalfipped mode
  735. } else {
  736. $vertical_display['textbtn'] = ' <td' . $rowspan . '></td>' . "\n";
  737. } // end vertical mode
  738. }
  739. // ... elseif display an empty column if the actions links are disabled to match the rest of the table
  740. elseif ($GLOBALS['cfg']['RowActionLinks'] == 'none'
  741. && ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped')
  742. ) {
  743. echo '<th></th>';
  744. }
  745. // 2. Displays the fields' name
  746. // 2.0 If sorting links should be used, checks if the query is a "JOIN"
  747. // statement (see 2.1.3)
  748. // 2.0.1 Prepare Display column comments if enabled ($GLOBALS['cfg']['ShowBrowseComments']).
  749. // Do not show comments, if using horizontalflipped mode, because of space usage
  750. if ($GLOBALS['cfg']['ShowBrowseComments']
  751. && $_SESSION['tmp_user_values']['disp_direction'] != 'horizontalflipped'
  752. ) {
  753. $comments_map = array();
  754. if (isset($analyzed_sql[0]) && is_array($analyzed_sql[0])) {
  755. foreach ($analyzed_sql[0]['table_ref'] as $tbl) {
  756. $tb = $tbl['table_true_name'];
  757. $comments_map[$tb] = PMA_getComments($db, $tb);
  758. unset($tb);
  759. }
  760. }
  761. }
  762. if ($GLOBALS['cfgRelation']['commwork'] && $GLOBALS['cfgRelation']['mimework'] && $GLOBALS['cfg']['BrowseMIME'] && ! $_SESSION['tmp_user_values']['hide_transformation']) {
  763. include_once './libraries/transformations.lib.php';
  764. $GLOBALS['mime_map'] = PMA_getMIME($db, $table);
  765. }
  766. // See if we have to highlight any header fields of a WHERE query.
  767. // Uses SQL-Parser results.
  768. $highlight_columns = array();
  769. if (isset($analyzed_sql) && isset($analyzed_sql[0])
  770. && isset($analyzed_sql[0]['where_clause_identifiers'])
  771. ) {
  772. $wi = 0;
  773. if (isset($analyzed_sql[0]['where_clause_identifiers']) && is_array($analyzed_sql[0]['where_clause_identifiers'])) {
  774. foreach ($analyzed_sql[0]['where_clause_identifiers'] AS $wci_nr => $wci) {
  775. $highlight_columns[$wci] = 'true';
  776. }
  777. }
  778. }
  779. if (PMA_isSelect()) {
  780. // prepare to get the column order, if available
  781. $pmatable = new PMA_Table($GLOBALS['table'], $GLOBALS['db']);
  782. $col_order = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_ORDER);
  783. $col_visib = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_VISIB);
  784. } else {
  785. $col_order = false;
  786. $col_visib = false;
  787. }
  788. for ($j = 0; $j < $fields_cnt; $j++) {
  789. // assign $i with appropriate column order
  790. $i = $col_order ? $col_order[$j] : $j;
  791. // See if this column should get highlight because it's used in the
  792. // where-query.
  793. if (isset($highlight_columns[$fields_meta[$i]->name]) || isset($highlight_columns[PMA_backquote($fields_meta[$i]->name)])) {
  794. $condition_field = true;
  795. } else {
  796. $condition_field = false;
  797. }
  798. // 2.0 Prepare comment-HTML-wrappers for each row, if defined/enabled.
  799. if (isset($comments_map)
  800. && isset($comments_map[$fields_meta[$i]->table])
  801. && isset($comments_map[$fields_meta[$i]->table][$fields_meta[$i]->name])
  802. ) {
  803. $comments = '<span class="tblcomment">' . htmlspecialchars($comments_map[$fields_meta[$i]->table][$fields_meta[$i]->name]) . '</span>';
  804. } else {
  805. $comments = '';
  806. }
  807. // 2.1 Results can be sorted
  808. if ($is_display['sort_lnk'] == '1') {
  809. // 2.1.1 Checks if the table name is required; it's the case
  810. // for a query with a "JOIN" statement and if the column
  811. // isn't aliased, or in queries like
  812. // SELECT `1`.`master_field` , `2`.`master_field`
  813. // FROM `PMA_relation` AS `1` , `PMA_relation` AS `2`
  814. if (isset($fields_meta[$i]->table) && strlen($fields_meta[$i]->table)) {
  815. $sort_tbl = PMA_backquote($fields_meta[$i]->table) . '.';
  816. } else {
  817. $sort_tbl = '';
  818. }
  819. // 2.1.2 Checks if the current column is used to sort the
  820. // results
  821. // the orgname member does not exist for all MySQL versions
  822. // but if found, it's the one on which to sort
  823. $name_to_use_in_sort = $fields_meta[$i]->name;
  824. $is_orgname = false;
  825. if (isset($fields_meta[$i]->orgname) && strlen($fields_meta[$i]->orgname)) {
  826. $name_to_use_in_sort = $fields_meta[$i]->orgname;
  827. $is_orgname = true;
  828. }
  829. // $name_to_use_in_sort might contain a space due to
  830. // formatting of function expressions like "COUNT(name )"
  831. // so we remove the space in this situation
  832. $name_to_use_in_sort = str_replace(' )', ')', $name_to_use_in_sort);
  833. if (empty($sort_expression)) {
  834. $is_in_sort = false;
  835. } else {
  836. // Field name may be preceded by a space, or any number
  837. // of characters followed by a dot (tablename.fieldname)
  838. // so do a direct comparison for the sort expression;
  839. // this avoids problems with queries like
  840. // "SELECT id, count(id)..." and clicking to sort
  841. // on id or on count(id).
  842. // Another query to test this:
  843. // SELECT p.*, FROM_UNIXTIME(p.temps) FROM mytable AS p
  844. // (and try clicking on each column's header twice)
  845. if (! empty($sort_tbl)
  846. && strpos($sort_expression_nodirection, $sort_tbl) === false
  847. && strpos($sort_expression_nodirection, '(') === false
  848. ) {
  849. $sort_expression_nodirection = $sort_tbl . $sort_expression_nodirection;
  850. }
  851. $is_in_sort = (str_replace('`', '', $sort_tbl) . $name_to_use_in_sort == str_replace('`', '', $sort_expression_nodirection) ? true : false);
  852. }
  853. // 2.1.3 Check the field name for a bracket.
  854. // If it contains one, it's probably a function column
  855. // like 'COUNT(`field`)'
  856. // It still might be a column name of a view. See bug #3383711
  857. // Check is_orgname.
  858. if (strpos($name_to_use_in_sort, '(') !== false && ! $is_orgname) {
  859. $sort_order = "\n" . 'ORDER BY ' . $name_to_use_in_sort . ' ';
  860. } else {
  861. $sort_order = "\n" . 'ORDER BY ' . $sort_tbl . PMA_backquote($name_to_use_in_sort) . ' ';
  862. }
  863. unset($name_to_use_in_sort);
  864. unset($is_orgname);
  865. // 2.1.4 Do define the sorting URL
  866. if (! $is_in_sort) {
  867. // patch #455484 ("Smart" order)
  868. $GLOBALS['cfg']['Order'] = strtoupper($GLOBALS['cfg']['Order']);
  869. if ($GLOBALS['cfg']['Order'] === 'SMART') {
  870. $sort_order .= (preg_match('@time|date@i', $fields_meta[$i]->type)) ? 'DESC' : 'ASC';
  871. } else {
  872. $sort_order .= $GLOBALS['cfg']['Order'];
  873. }
  874. $order_img = '';
  875. } elseif ('DESC' == $sort_direction) {
  876. $sort_order .= ' ASC';
  877. $order_img = ' ' . PMA_getImage('s_desc.png', __('Descending'), array('class' => "soimg$i", 'title' => ''));
  878. $order_img .= ' ' . PMA_getImage('s_asc.png', __('Ascending'), array('class' => "soimg$i hide", 'title' => ''));
  879. } else {
  880. $sort_order .= ' DESC';
  881. $order_img = ' ' . PMA_getImage('s_asc.png', __('Ascending'), array('class' => "soimg$i", 'title' => ''));
  882. $order_img .= ' ' . PMA_getImage('s_desc.png', __('Descending'), array('class' => "soimg$i hide", 'title' => ''));
  883. }
  884. if (preg_match('@(.*)([[:space:]](LIMIT (.*)|PROCEDURE (.*)|FOR UPDATE|LOCK IN SHARE MODE))@is', $unsorted_sql_query, $regs3)) {
  885. $sorted_sql_query = $regs3[1] . $sort_order . $regs3[2];
  886. } else {
  887. $sorted_sql_query = $unsorted_sql_query . $sort_order;
  888. }
  889. $_url_params = array(
  890. 'db' => $db,
  891. 'table' => $table,
  892. 'sql_query' => $sorted_sql_query,
  893. 'session_max_rows' => $session_max_rows
  894. );
  895. $order_url = 'sql.php' . PMA_generate_common_url($_url_params);
  896. // 2.1.5 Displays the sorting URL
  897. // enable sort order swapping for image
  898. $order_link_params = array();
  899. if (isset($order_img) && $order_img!='') {
  900. if (strstr($order_img, 'asc')) {
  901. $order_link_params['onmouseover'] = "$('.soimg$i').toggle()";
  902. $order_link_params['onmouseout'] = "$('.soimg$i').toggle()";
  903. } elseif (strstr($order_img, 'desc')) {
  904. $order_link_params['onmouseover'] = "$('.soimg$i').toggle()";
  905. $order_link_params['onmouseout'] = "$('.soimg$i').toggle()";
  906. }
  907. }
  908. if ($GLOBALS['cfg']['HeaderFlipType'] == 'auto') {
  909. if (PMA_USR_BROWSER_AGENT == 'IE') {
  910. $GLOBALS['cfg']['HeaderFlipType'] = 'css';
  911. } else {
  912. $GLOBALS['cfg']['HeaderFlipType'] = 'fake';
  913. }
  914. }
  915. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped'
  916. && $GLOBALS['cfg']['HeaderFlipType'] == 'css'
  917. ) {
  918. $order_link_params['style'] = 'direction: ltr; writing-mode: tb-rl;';
  919. }
  920. $order_link_params['title'] = __('Sort');
  921. $order_link_content = ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'fake' ? PMA_flipstring(htmlspecialchars($fields_meta[$i]->name), "<br />\n") : htmlspecialchars($fields_meta[$i]->name));
  922. $order_link = PMA_linkOrButton($order_url, $order_link_content . $order_img, $order_link_params, false, true);
  923. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal'
  924. || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped'
  925. ) {
  926. echo '<th';
  927. $th_class = array();
  928. $th_class[] = 'draggable';
  929. if ($col_visib && !$col_visib[$j]) {
  930. $th_class[] = 'hide';
  931. }
  932. if ($condition_field) {
  933. $th_class[] = 'condition';
  934. }
  935. $th_class[] = 'column_heading';
  936. if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) {
  937. $th_class[] = 'pointer';
  938. }
  939. if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) {
  940. $th_class[] = 'marker';
  941. }
  942. echo ' class="' . implode(' ', $th_class) . '"';
  943. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
  944. echo ' valign="bottom"';
  945. }
  946. echo '>' . $order_link . $comments . '</th>';
  947. }
  948. $vertical_display['desc'][] = ' <th '
  949. . 'class="draggable'
  950. . ($condition_field ? ' condition' : '')
  951. . '">' . "\n"
  952. . $order_link . $comments . ' </th>' . "\n";
  953. } // end if (2.1)
  954. // 2.2 Results can't be sorted
  955. else {
  956. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal'
  957. || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped'
  958. ) {
  959. echo '<th';
  960. $th_class = array();
  961. $th_class[] = 'draggable';
  962. if ($col_visib && !$col_visib[$j]) {
  963. $th_class[] = 'hide';
  964. }
  965. if ($condition_field) {
  966. $th_class[] = 'condition';
  967. }
  968. echo ' class="' . implode(' ', $th_class) . '"';
  969. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
  970. echo ' valign="bottom"';
  971. }
  972. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped'
  973. && $GLOBALS['cfg']['HeaderFlipType'] == 'css'
  974. ) {
  975. echo ' style="direction: ltr; writing-mode: tb-rl;"';
  976. }
  977. echo '>';
  978. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped'
  979. && $GLOBALS['cfg']['HeaderFlipType'] == 'fake'
  980. ) {
  981. echo PMA_flipstring(htmlspecialchars($fields_meta[$i]->name), '<br />');
  982. } else {
  983. echo htmlspecialchars($fields_meta[$i]->name);
  984. }
  985. echo "\n" . $comments . '</th>';
  986. }
  987. $vertical_display['desc'][] = ' <th '
  988. . 'class="draggable'
  989. . ($condition_field ? ' condition"' : '')
  990. . '">' . "\n"
  991. . ' ' . htmlspecialchars($fields_meta[$i]->name) . "\n"
  992. . $comments . ' </th>';
  993. } // end else (2.2)
  994. } // end for
  995. // 3. Displays the needed checkboxes at the right
  996. // column of the result table header if possible and required...
  997. if (($GLOBALS['cfg']['RowActionLinks'] == 'right' || $GLOBALS['cfg']['RowActionLinks'] == 'both')
  998. && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn')
  999. && $is_display['text_btn'] == '1'
  1000. ) {
  1001. $vertical_display['emptyafter'] = ($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn') ? 4 : 1;
  1002. if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal'
  1003. || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped'
  1004. ) {
  1005. echo "\n";
  1006. ?>
  1007. <th <?php echo $colspan; ?>><?php echo $full_or_partial_text_link;?>
  1008. </th>
  1009. <?php
  1010. // end horizontal/horizontalflipped mode
  1011. } else {
  1012. $vertical_display['textbtn'] = ' <th ' . $rowspan . ' valign="middle">' . "\n"

Large files files are truncated, but you can click here to view the full file