示例#1
0
/**
 * Displays the body of the results table
 *
 * @uses    $_SESSION['tmp_user_values']['disp_direction']
 * @uses    $_SESSION['tmp_user_values']['repeat_cells']
 * @uses    $_SESSION['tmp_user_values']['max_rows']
 * @uses    $_SESSION['tmp_user_values']['display_text']
 * @uses    $_SESSION['tmp_user_values']['display_binary']
 * @uses    $_SESSION['tmp_user_values']['display_binary_as_hex']
 * @uses    $_SESSION['tmp_user_values']['display_blob']
 * @param   integer  the link id associated to the query which results have
 *                   to be displayed
 * @param   array    which elements to display
 * @param   array    the list of relations
 * @param   array    the analyzed query
 *
 * @return  boolean  always true
 *
 * @global  string   $db                the database name
 * @global  string   $table             the table name
 * @global  string   $goto              the URL to go back in case of errors
 * @global  string   $sql_query         the SQL query
 * @global  array    $fields_meta       the list of fields properties
 * @global  integer  $fields_cnt        the total number of fields returned by
 *                                      the SQL query
 * @global  array    $vertical_display  informations used with vertical display
 *                                      mode
 * @global  array    $highlight_columns column names to highlight
 * @global  array    $row               current row data
 *
 * @access  private
 *
 * @see     PMA_displayTable()
 */
function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql)
{
    global $db, $table, $goto;
    global $sql_query, $fields_meta, $fields_cnt;
    global $vertical_display, $highlight_columns;
    global $row;
    // mostly because of browser transformations, to make the row-data accessible in a plugin
    $url_sql_query = $sql_query;
    // query without conditions to shorten URLs when needed, 200 is just
    // guess, it should depend on remaining URL length
    if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['querytype']) && $analyzed_sql[0]['querytype'] == 'SELECT' && strlen($sql_query) > 200) {
        $url_sql_query = 'SELECT ';
        if (isset($analyzed_sql[0]['queryflags']['distinct'])) {
            $url_sql_query .= ' DISTINCT ';
        }
        $url_sql_query .= $analyzed_sql[0]['select_expr_clause'];
        if (!empty($analyzed_sql[0]['from_clause'])) {
            $url_sql_query .= ' FROM ' . $analyzed_sql[0]['from_clause'];
        }
    }
    if (!is_array($map)) {
        $map = array();
    }
    $row_no = 0;
    $vertical_display['edit'] = array();
    $vertical_display['delete'] = array();
    $vertical_display['data'] = array();
    $vertical_display['row_delete'] = array();
    // Correction University of Virginia 19991216 in the while below
    // Previous code assumed that all tables have keys, specifically that
    // the phpMyAdmin GUI should support row delete/edit only for such
    // tables.
    // Although always using keys is arguably the prescribed way of
    // defining a relational table, it is not required. This will in
    // particular be violated by the novice.
    // We want to encourage phpMyAdmin usage by such novices. So the code
    // below has been changed to conditionally work as before when the
    // table being displayed has one or more keys; but to display
    // delete/edit options correctly for tables without keys.
    $odd_row = true;
    while ($row = PMA_DBI_fetch_row($dt_result)) {
        // lem9: "vertical display" mode stuff
        if ($row_no != 0 && $_SESSION['tmp_user_values']['repeat_cells'] != 0 && !($row_no % $_SESSION['tmp_user_values']['repeat_cells']) && ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped')) {
            echo '<tr>' . "\n";
            if ($vertical_display['emptypre'] > 0) {
                echo '    <th colspan="' . $vertical_display['emptypre'] . '">' . "\n" . '        &nbsp;</th>' . "\n";
            }
            foreach ($vertical_display['desc'] as $val) {
                echo $val;
            }
            if ($vertical_display['emptyafter'] > 0) {
                echo '    <th colspan="' . $vertical_display['emptyafter'] . '">' . "\n" . '        &nbsp;</th>' . "\n";
            }
            echo '</tr>' . "\n";
        }
        // end if
        $class = $odd_row ? 'odd' : 'even';
        $odd_row = !$odd_row;
        if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
            // loic1: pointer code part
            echo '    <tr class="' . $class . '">' . "\n";
            $class = '';
        }
        // 1. Prepares the row
        // 1.1 Results from a "SELECT" statement -> builds the
        //     WHERE clause to use in links (a unique key if possible)
        /**
         * @todo $where_clause could be empty, for example a table
         *       with only one field and it's a BLOB; in this case,
         *       avoid to display the delete and edit links
         */
        list($where_clause, $clause_is_unique) = PMA_getUniqueCondition($dt_result, $fields_cnt, $fields_meta, $row);
        $where_clause_html = urlencode($where_clause);
        // 1.2 Defines the URLs for the modify/delete link(s)
        if ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn') {
            // We need to copy the value or else the == 'both' check will always return true
            if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') {
                $iconic_spacer = '<div class="nowrap">';
            } else {
                $iconic_spacer = '';
            }
            // 1.2.1 Modify link(s)
            if ($is_display['edit_lnk'] == 'ur') {
                // update row case
                $_url_params = array('db' => $db, 'table' => $table, 'where_clause' => $where_clause, 'clause_is_unique' => $clause_is_unique, 'sql_query' => $url_sql_query, 'goto' => 'sql.php');
                $edit_url = 'tbl_change.php' . PMA_generate_common_url($_url_params);
                $edit_str = PMA_getIcon('b_edit.png', $GLOBALS['strEdit'], true);
            }
            // end if (1.2.1)
            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])) {
                $_url_params = array('db' => $row[1], 'id_bookmark' => $row[0], 'action_bookmark' => '0', 'action_bookmark_all' => '1', 'SQL' => $GLOBALS['strExecuteBookmarked']);
                $bookmark_go = '<a href="import.php' . PMA_generate_common_url($_url_params) . ' " title="' . $GLOBALS['strExecuteBookmarked'] . '">';
                $bookmark_go .= PMA_getIcon('b_bookmark.png', $GLOBALS['strExecuteBookmarked'], true);
                $bookmark_go .= '</a>';
            } else {
                $bookmark_go = '';
            }
            // 1.2.2 Delete/Kill link(s)
            if ($is_display['del_lnk'] == 'dr') {
                // delete row case
                $_url_params = array('db' => $db, 'table' => $table, 'sql_query' => $url_sql_query, 'zero_rows' => $GLOBALS['strDeleted'], 'goto' => empty($goto) ? 'tbl_sql.php' : $goto);
                $lnk_goto = 'sql.php' . PMA_generate_common_url($_url_params, 'text');
                $del_query = 'DELETE FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table) . ' WHERE ' . $where_clause . ($clause_is_unique ? '' : ' LIMIT 1');
                $_url_params = array('db' => $db, 'table' => $table, 'sql_query' => $del_query, 'zero_rows' => $GLOBALS['strDeleted'], 'goto' => $lnk_goto);
                $del_url = 'sql.php' . PMA_generate_common_url($_url_params);
                $js_conf = 'DELETE FROM ' . PMA_jsFormat($db) . '.' . PMA_jsFormat($table) . ' WHERE ' . PMA_jsFormat($where_clause, false) . ($clause_is_unique ? '' : ' LIMIT 1');
                $del_str = PMA_getIcon('b_drop.png', $GLOBALS['strDelete'], true);
            } elseif ($is_display['del_lnk'] == 'kp') {
                // kill process case
                $_url_params = array('db' => $db, 'table' => $table, 'sql_query' => $url_sql_query, 'goto' => 'main.php');
                $lnk_goto = 'sql.php' . PMA_generate_common_url($_url_params, 'text');
                $_url_params = array('db' => 'mysql', 'sql_query' => 'KILL ' . $row[0], 'goto' => $lnk_goto);
                $del_url = 'sql.php' . PMA_generate_common_url($_url_params);
                $del_query = 'KILL ' . $row[0];
                $js_conf = 'KILL ' . $row[0];
                $del_str = PMA_getIcon('b_drop.png', $GLOBALS['strKill'], true);
            }
            // end if (1.2.2)
            // 1.3 Displays the links at left if required
            if ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped')) {
                $doWriteModifyAt = 'left';
                require './libraries/display_tbl_links.lib.php';
            }
            // end if (1.3)
        }
        // end if (1)
        // 2. Displays the rows' values
        for ($i = 0; $i < $fields_cnt; ++$i) {
            $meta = $fields_meta[$i];
            $pointer = $i;
            // garvin: See if this column should get highlight because it's used in the
            //  where-query.
            if (isset($highlight_columns) && (isset($highlight_columns[$meta->name]) || isset($highlight_columns[PMA_backquote($meta->name)]))) {
                $condition_field = true;
            } else {
                $condition_field = false;
            }
            $mouse_events = '';
            if ($_SESSION['tmp_user_values']['disp_direction'] == 'vertical' && (!isset($GLOBALS['printview']) || $GLOBALS['printview'] != '1')) {
                if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) {
                    $mouse_events .= ' onmouseover="setVerticalPointer(this, ' . $row_no . ', \'over\', \'odd\', \'even\', \'hover\', \'marked\');"' . ' onmouseout="setVerticalPointer(this, ' . $row_no . ', \'out\', \'odd\', \'even\', \'hover\', \'marked\');" ';
                }
                if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) {
                    $mouse_events .= ' onmousedown="setVerticalPointer(this, ' . $row_no . ', \'click\', \'odd\', \'even\', \'hover\', \'marked\'); setCheckboxColumn(\'id_rows_to_delete' . $row_no . '\');" ';
                } else {
                    $mouse_events .= ' onmousedown="setCheckboxColumn(\'id_rows_to_delete' . $row_no . '\');" ';
                }
            }
            // end if
            // garvin: Wrap MIME-transformations. [MIME]
            $default_function = 'default_function';
            // default_function
            $transform_function = $default_function;
            $transform_options = array();
            if ($GLOBALS['cfgRelation']['mimework'] && $GLOBALS['cfg']['BrowseMIME']) {
                if (isset($GLOBALS['mime_map'][$meta->name]['mimetype']) && isset($GLOBALS['mime_map'][$meta->name]['transformation']) && !empty($GLOBALS['mime_map'][$meta->name]['transformation'])) {
                    $include_file = $GLOBALS['mime_map'][$meta->name]['transformation'];
                    if (file_exists('./libraries/transformations/' . $include_file)) {
                        $transformfunction_name = str_replace('.inc.php', '', $GLOBALS['mime_map'][$meta->name]['transformation']);
                        require_once './libraries/transformations/' . $include_file;
                        if (function_exists('PMA_transformation_' . $transformfunction_name)) {
                            $transform_function = 'PMA_transformation_' . $transformfunction_name;
                            $transform_options = PMA_transformation_getOptions(isset($GLOBALS['mime_map'][$meta->name]['transformation_options']) ? $GLOBALS['mime_map'][$meta->name]['transformation_options'] : '');
                            $meta->mimetype = str_replace('_', '/', $GLOBALS['mime_map'][$meta->name]['mimetype']);
                        }
                    }
                    // end if file_exists
                }
                // end if transformation is set
            }
            // end if mime/transformation works.
            $_url_params = array('db' => $db, 'table' => $table, 'where_clause' => $where_clause, 'transform_key' => $meta->name);
            if (!empty($sql_query)) {
                $_url_params['sql_query'] = $url_sql_query;
            }
            $transform_options['wrapper_link'] = PMA_generate_common_url($_url_params);
            // n u m e r i c
            if ($meta->numeric == 1) {
                // lem9: if two fields have the same name (this is possible
                //       with self-join queries, for example), using $meta->name
                //       will show both fields NULL even if only one is NULL,
                //       so use the $pointer
                if (!isset($row[$i]) || is_null($row[$i])) {
                    $vertical_display['data'][$row_no][$i] = '    <td align="right"' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"><i>NULL</i></td>' . "\n";
                } elseif ($row[$i] != '') {
                    $nowrap = ' nowrap';
                    $where_comparison = ' = ' . $row[$i];
                    $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);
                } else {
                    $vertical_display['data'][$row_no][$i] = '    <td align="right"' . $mouse_events . ' class="' . $class . ' nowrap' . ($condition_field ? ' condition' : '') . '">&nbsp;</td>' . "\n";
                }
                //  b l o b
            } elseif (stristr($meta->type, 'BLOB')) {
                // loic1 : PMA_mysql_fetch_fields returns BLOB in place of
                // TEXT fields type so we have to ensure it's really a BLOB
                $field_flags = PMA_DBI_field_flags($dt_result, $i);
                if (stristr($field_flags, 'BINARY')) {
                    // rajk - for blobstreaming
                    $bs_reference_exists = $allBSTablesExist = FALSE;
                    // load PMA configuration
                    $PMA_Config = $_SESSION['PMA_Config'];
                    // if PMA configuration exists
                    if ($PMA_Config) {
                        // load BS variables
                        $pluginsExist = $PMA_Config->get('BLOBSTREAMING_PLUGINS_EXIST');
                        // if BS plugins exist
                        if ($pluginsExist) {
                            // load BS databases
                            $bs_tables = $PMA_Config->get('BLOBSTREAMABLE_DATABASES');
                            // if BS db array and specified db string not empty and valid
                            if (!empty($bs_tables) && strlen($db) > 0) {
                                $bs_tables = $bs_tables[$db];
                                if (isset($bs_tables)) {
                                    $allBSTablesExist = TRUE;
                                    // check if BS tables exist for given database
                                    foreach ($bs_tables as $table_key => $bs_tbl) {
                                        if (!$bs_tables[$table_key]['Exists']) {
                                            $allBSTablesExist = FALSE;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    // if necessary BS tables exist
                    if ($allBSTablesExist) {
                        $bs_reference_exists = PMA_BS_ReferenceExists($row[$i], $db);
                    }
                    // if valid BS reference exists
                    if ($bs_reference_exists) {
                        $blobtext = PMA_BS_CreateReferenceLink($row[$i], $db);
                    } else {
                        $blobtext = PMA_handle_non_printable_contents('BLOB', isset($row[$i]) ? $row[$i] : '', $transform_function, $transform_options, $default_function, $meta);
                    }
                    $vertical_display['data'][$row_no][$i] = '    <td align="left"' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '">' . $blobtext . '</td>';
                    unset($blobtext);
                    // not binary:
                } else {
                    if (!isset($row[$i]) || is_null($row[$i])) {
                        $vertical_display['data'][$row_no][$i] = '    <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"><i>NULL</i></td>' . "\n";
                    } elseif ($row[$i] != '') {
                        // garvin: if a transform function for blob is set, none of these replacements will be made
                        if (PMA_strlen($row[$i]) > $GLOBALS['cfg']['LimitChars'] && $_SESSION['tmp_user_values']['display_text'] == 'P') {
                            $row[$i] = PMA_substr($row[$i], 0, $GLOBALS['cfg']['LimitChars']) . '...';
                        }
                        // loic1: displays all space characters, 4 space
                        // characters for tabulations and <cr>/<lf>
                        $row[$i] = $default_function != $transform_function ? $transform_function($row[$i], $transform_options, $meta) : $default_function($row[$i], array(), $meta);
                        $vertical_display['data'][$row_no][$i] = '    <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '">' . $row[$i] . '</td>' . "\n";
                    } else {
                        $vertical_display['data'][$row_no][$i] = '    <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '">&nbsp;</td>' . "\n";
                    }
                }
                // n o t   n u m e r i c   a n d   n o t   B L O B
            } else {
                if (!isset($row[$i]) || is_null($row[$i])) {
                    $vertical_display['data'][$row_no][$i] = '    <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"><i>NULL</i></td>' . "\n";
                } elseif ($row[$i] != '') {
                    // loic1: support blanks in the key
                    $relation_id = $row[$i];
                    // nijel: Cut all fields to $GLOBALS['cfg']['LimitChars']
                    // lem9: (unless it's a link-type transformation)
                    if (PMA_strlen($row[$i]) > $GLOBALS['cfg']['LimitChars'] && $_SESSION['tmp_user_values']['display_text'] == 'P' && !strpos($transform_function, 'link') === true) {
                        $row[$i] = PMA_substr($row[$i], 0, $GLOBALS['cfg']['LimitChars']) . '...';
                    }
                    // loic1: displays special characters from binaries
                    $field_flags = PMA_DBI_field_flags($dt_result, $i);
                    if (isset($meta->_type) && $meta->_type === MYSQLI_TYPE_BIT) {
                        $row[$i] = PMA_printable_bit_value($row[$i], $meta->length);
                    } elseif (stristr($field_flags, 'BINARY') && $meta->type == 'string') {
                        if ($_SESSION['tmp_user_values']['display_binary'] || isset($GLOBALS['is_analyse']) && $GLOBALS['is_analyse']) {
                            // user asked to see the real contents of BINARY
                            // fields, or we detected a PROCEDURE ANALYSE in
                            // the query (results are reported as being
                            // binary strings)
                            if ($_SESSION['tmp_user_values']['display_binary_as_hex']) {
                                $row[$i] = bin2hex($row[$i]);
                            } else {
                                $row[$i] = htmlspecialchars(PMA_replace_binary_contents($row[$i]));
                            }
                        } else {
                            // we show the BINARY message and field's size
                            // (or maybe use a transformation)
                            $row[$i] = PMA_handle_non_printable_contents('BINARY', $row[$i], $transform_function, $transform_options, $default_function, $meta);
                        }
                    }
                    // garvin: transform functions may enable no-wrapping:
                    $function_nowrap = $transform_function . '_nowrap';
                    $bool_nowrap = $default_function != $transform_function && function_exists($function_nowrap) ? $function_nowrap($transform_options) : false;
                    // loic1: do not wrap if date field type
                    $nowrap = preg_match('@DATE|TIME@i', $meta->type) || $bool_nowrap ? ' nowrap' : '';
                    $where_comparison = ' = \'' . PMA_sqlAddslashes($row[$i]) . '\'';
                    $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);
                } else {
                    $vertical_display['data'][$row_no][$i] = '    <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '">&nbsp;</td>' . "\n";
                }
            }
            // lem9: output stored cell
            if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
                echo $vertical_display['data'][$row_no][$i];
            }
            if (isset($vertical_display['rowdata'][$i][$row_no])) {
                $vertical_display['rowdata'][$i][$row_no] .= $vertical_display['data'][$row_no][$i];
            } else {
                $vertical_display['rowdata'][$i][$row_no] = $vertical_display['data'][$row_no][$i];
            }
        }
        // end for (2)
        // 3. Displays the modify/delete links on the right if required
        if ($GLOBALS['cfg']['ModifyDeleteAtRight'] && ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped')) {
            $doWriteModifyAt = 'right';
            require './libraries/display_tbl_links.lib.php';
        }
        // end if (3)
        if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
            ?>
</tr>
            <?php 
        }
        // end if
        // 4. Gather links of del_urls and edit_urls in an array for later
        //    output
        if (!isset($vertical_display['edit'][$row_no])) {
            $vertical_display['edit'][$row_no] = '';
            $vertical_display['delete'][$row_no] = '';
            $vertical_display['row_delete'][$row_no] = '';
        }
        $column_style_vertical = '';
        if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) {
            $column_style_vertical .= ' onmouseover="setVerticalPointer(this, ' . $row_no . ', \'over\', \'odd\', \'even\', \'hover\', \'marked\');"' . ' onmouseout="setVerticalPointer(this, ' . $row_no . ', \'out\', \'odd\', \'even\', \'hover\', \'marked\');"';
        }
        $column_marker_vertical = '';
        if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) {
            $column_marker_vertical .= 'setVerticalPointer(this, ' . $row_no . ', \'click\', \'odd\', \'even\', \'hover\', \'marked\');';
        }
        if (!empty($del_url) && $is_display['del_lnk'] != 'kp') {
            $vertical_display['row_delete'][$row_no] .= '    <td align="center" class="' . $class . '" ' . $column_style_vertical . '>' . "\n" . '        <input type="checkbox" id="id_rows_to_delete' . $row_no . '[%_PMA_CHECKBOX_DIR_%]" name="rows_to_delete[' . $where_clause_html . ']"' . ' onclick="' . $column_marker_vertical . 'copyCheckboxesRange(\'rowsDeleteForm\', \'id_rows_to_delete' . $row_no . '\',\'[%_PMA_CHECKBOX_DIR_%]\');"' . ' value="' . htmlspecialchars($del_query) . '" ' . (isset($GLOBALS['checkall']) ? 'checked="checked"' : '') . ' />' . "\n" . '    </td>' . "\n";
        } else {
            unset($vertical_display['row_delete'][$row_no]);
        }
        if (isset($edit_url)) {
            $vertical_display['edit'][$row_no] .= '    <td align="center" class="' . $class . '" ' . $column_style_vertical . '>' . "\n" . PMA_linkOrButton($edit_url, $edit_str, array(), false) . $bookmark_go . '    </td>' . "\n";
        } else {
            unset($vertical_display['edit'][$row_no]);
        }
        if (isset($del_url)) {
            $vertical_display['delete'][$row_no] .= '    <td align="center" class="' . $class . '" ' . $column_style_vertical . '>' . "\n" . PMA_linkOrButton($del_url, $del_str, isset($js_conf) ? $js_conf : '', false) . '    </td>' . "\n";
        } else {
            unset($vertical_display['delete'][$row_no]);
        }
        echo $_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' ? "\n" : '';
        $row_no++;
    }
    // end while
    // this is needed by PMA_displayTable() to generate the proper param
    // in the multi-edit and multi-delete form
    return $clause_is_unique;
}
示例#2
0
/**
 * Displays a table of results returned by a SQL query.
 * This function is called by the "sql.php" script.
 *
 * @param   integer the link id associated to the query which results have
 *                  to be displayed
 * @param   array   the display mode
 * @param   array   the analyzed query
 *
 * @uses    $_SESSION['tmp_user_values']['pos']
 * @global  string   $db                the database name
 * @global  string   $table             the table name
 * @global  string   $goto              the URL to go back in case of errors
 * @global  string   $sql_query         the current SQL query
 * @global  integer  $num_rows          the total number of rows returned by the
 *                                      SQL query
 * @global  integer  $unlim_num_rows    the total number of rows returned by the
 *                                      SQL query without any programmatically
 *                                      appended "LIMIT" clause
 * @global  array    $fields_meta       the list of fields properties
 * @global  integer  $fields_cnt        the total number of fields returned by
 *                                      the SQL query
 * @global  array    $vertical_display  informations used with vertical display
 *                                      mode
 * @global  array    $highlight_columns column names to highlight
 * @global  array    $cfgRelation       the relation settings
 *
 * @access  private
 *
 * @see     PMA_showMessage(), PMA_setDisplayMode(),
 *          PMA_displayTableNavigation(), PMA_displayTableHeaders(),
 *          PMA_displayTableBody(), PMA_displayResultsOperations()
 */
function PMA_displayTable(&$dt_result, &$the_disp_mode, $analyzed_sql)
{
    global $db, $table, $goto;
    global $sql_query, $num_rows, $unlim_num_rows, $fields_meta, $fields_cnt;
    global $vertical_display, $highlight_columns;
    global $cfgRelation;
    global $showtable;
    // why was this called here? (already called from sql.php)
    //PMA_displayTable_checkConfigParams();
    /**
     * @todo move this to a central place
     * @todo for other future table types
     */
    $is_innodb = isset($showtable['Type']) && $showtable['Type'] == 'InnoDB';
    if ($is_innodb && !isset($analyzed_sql[0]['queryflags']['union']) && !isset($analyzed_sql[0]['table_ref'][1]['table_name']) && (empty($analyzed_sql[0]['where_clause']) || $analyzed_sql[0]['where_clause'] == '1 ')) {
        // "j u s t   b r o w s i n g"
        $pre_count = '~';
        $after_count = PMA_showHint(PMA_sanitize(__('May be approximate. See [a@./Documentation.html#faq3_11@Documentation]FAQ 3.11[/a]')));
    } else {
        $pre_count = '';
        $after_count = '';
    }
    // 1. ----- Prepares the work -----
    // 1.1 Gets the informations about which functionalities should be
    //     displayed
    $total = '';
    $is_display = PMA_setDisplayMode($the_disp_mode, $total);
    // 1.2 Defines offsets for the next and previous pages
    if ($is_display['nav_bar'] == '1') {
        if ($_SESSION['tmp_user_values']['max_rows'] == 'all') {
            $pos_next = 0;
            $pos_prev = 0;
        } else {
            $pos_next = $_SESSION['tmp_user_values']['pos'] + $_SESSION['tmp_user_values']['max_rows'];
            $pos_prev = $_SESSION['tmp_user_values']['pos'] - $_SESSION['tmp_user_values']['max_rows'];
            if ($pos_prev < 0) {
                $pos_prev = 0;
            }
        }
    }
    // end if
    // 1.3 Find the sort expression
    // we need $sort_expression and $sort_expression_nodirection
    // even if there are many table references
    if (!empty($analyzed_sql[0]['order_by_clause'])) {
        $sort_expression = trim(str_replace('  ', ' ', $analyzed_sql[0]['order_by_clause']));
        /**
         * Get rid of ASC|DESC
         */
        preg_match('@(.*)([[:space:]]*(ASC|DESC))@si', $sort_expression, $matches);
        $sort_expression_nodirection = isset($matches[1]) ? trim($matches[1]) : $sort_expression;
        $sort_direction = isset($matches[2]) ? trim($matches[2]) : '';
        unset($matches);
    } else {
        $sort_expression = $sort_expression_nodirection = $sort_direction = '';
    }
    // 1.4 Prepares display of first and last value of the sorted column
    if (!empty($sort_expression_nodirection)) {
        if (strpos($sort_expression_nodirection, '.') === false) {
            $sort_table = $table;
            $sort_column = $sort_expression_nodirection;
        } else {
            list($sort_table, $sort_column) = explode('.', $sort_expression_nodirection);
        }
        $sort_table = PMA_unQuote($sort_table);
        $sort_column = PMA_unQuote($sort_column);
        // find the sorted column index in row result
        // (this might be a multi-table query)
        $sorted_column_index = false;
        foreach ($fields_meta as $key => $meta) {
            if ($meta->table == $sort_table && $meta->name == $sort_column) {
                $sorted_column_index = $key;
                break;
            }
        }
        if ($sorted_column_index !== false) {
            // fetch first row of the result set
            $row = PMA_DBI_fetch_row($dt_result);
            // initializing default arguments
            $default_function = 'default_function';
            $transform_function = $default_function;
            $transform_options = array();
            // check for non printable sorted row data
            $meta = $fields_meta[$sorted_column_index];
            if (stristr($meta->type, 'BLOB') || $meta->type == 'geometry') {
                $column_for_first_row = PMA_handle_non_printable_contents($meta->type, $row[$sorted_column_index], $transform_function, $transform_options, $default_function, $meta, NULL);
            } else {
                $column_for_first_row = $row[$sorted_column_index];
            }
            $column_for_first_row = strtoupper(substr($column_for_first_row, 0, $GLOBALS['cfg']['LimitChars']));
            // fetch last row of the result set
            PMA_DBI_data_seek($dt_result, $num_rows - 1);
            $row = PMA_DBI_fetch_row($dt_result);
            // check for non printable sorted row data
            $meta = $fields_meta[$sorted_column_index];
            if (stristr($meta->type, 'BLOB') || $meta->type == 'geometry') {
                $column_for_last_row = PMA_handle_non_printable_contents($meta->type, $row[$sorted_column_index], $transform_function, $transform_options, $default_function, $meta, NULL);
            } else {
                $column_for_last_row = $row[$sorted_column_index];
            }
            $column_for_last_row = strtoupper(substr($column_for_last_row, 0, $GLOBALS['cfg']['LimitChars']));
            // reset to first row for the loop in PMA_displayTableBody()
            PMA_DBI_data_seek($dt_result, 0);
            // we could also use here $sort_expression_nodirection
            $sorted_column_message = ' [' . htmlspecialchars($sort_column) . ': <strong>' . htmlspecialchars($column_for_first_row) . ' - ' . htmlspecialchars($column_for_last_row) . '</strong>]';
            unset($row, $column_for_first_row, $column_for_last_row, $meta, $default_function, $transform_function, $transform_options);
        }
        unset($sorted_column_index, $sort_table, $sort_column);
    }
    // 2. ----- Displays the top of the page -----
    // 2.1 Displays a messages with position informations
    if ($is_display['nav_bar'] == '1' && isset($pos_next)) {
        if (isset($unlim_num_rows) && $unlim_num_rows != $total) {
            $selectstring = ', ' . $unlim_num_rows . ' ' . __('in query');
        } else {
            $selectstring = '';
        }
        $last_shown_rec = $_SESSION['tmp_user_values']['max_rows'] == 'all' || $pos_next > $total ? $total - 1 : $pos_next - 1;
        if (PMA_Table::isView($db, $table) && $total == $GLOBALS['cfg']['MaxExactCountViews']) {
            $message = PMA_Message::notice(__('This view has at least this number of rows. Please refer to %sdocumentation%s.'));
            $message->addParam('[a@./Documentation.html#cfg_MaxExactCount@_blank]');
            $message->addParam('[/a]');
            $message_view_warning = PMA_showHint($message);
        } else {
            $message_view_warning = false;
        }
        $message = PMA_Message::success(__('Showing rows'));
        $message->addMessage($_SESSION['tmp_user_values']['pos']);
        if ($message_view_warning) {
            $message->addMessage('...', ' - ');
            $message->addMessage($message_view_warning);
            $message->addMessage('(');
        } else {
            $message->addMessage($last_shown_rec, ' - ');
            $message->addMessage(' (');
            $message->addMessage($pre_count . PMA_formatNumber($total, 0));
            $message->addString(__('total'));
            if (!empty($after_count)) {
                $message->addMessage($after_count);
            }
            $message->addMessage($selectstring, '');
            $message->addMessage(', ', '');
        }
        $messagge_qt = PMA_Message::notice(__('Query took %01.4f sec'));
        $messagge_qt->addParam($GLOBALS['querytime']);
        $message->addMessage($messagge_qt, '');
        $message->addMessage(')', '');
        $message->addMessage(isset($sorted_column_message) ? $sorted_column_message : '', '');
        PMA_showMessage($message, $sql_query, 'success');
    } elseif (!isset($GLOBALS['printview']) || $GLOBALS['printview'] != '1') {
        PMA_showMessage(__('Your SQL query has been executed successfully'), $sql_query, 'success');
    }
    // 2.3 Displays the navigation bars
    if (!strlen($table)) {
        if (isset($analyzed_sql[0]['query_type']) && $analyzed_sql[0]['query_type'] == 'SELECT') {
            // table does not always contain a real table name,
            // for example in MySQL 5.0.x, the query SHOW STATUS
            // returns STATUS as a table name
            $table = $fields_meta[0]->table;
        } else {
            $table = '';
        }
    }
    if ($is_display['nav_bar'] == '1') {
        PMA_displayTableNavigation($pos_next, $pos_prev, $sql_query, 'top_direction_dropdown');
        echo "\n";
    } elseif (!isset($GLOBALS['printview']) || $GLOBALS['printview'] != '1') {
        echo "\n" . '<br /><br />' . "\n";
    }
    // 2b ----- Get field references from Database -----
    // (see the 'relation' configuration variable)
    // initialize map
    $map = array();
    // find tables
    $target = array();
    if (isset($analyzed_sql[0]['table_ref']) && is_array($analyzed_sql[0]['table_ref'])) {
        foreach ($analyzed_sql[0]['table_ref'] as $table_ref_position => $table_ref) {
            $target[] = $analyzed_sql[0]['table_ref'][$table_ref_position]['table_true_name'];
        }
    }
    $tabs = '(\'' . join('\',\'', $target) . '\')';
    if (!strlen($table)) {
        $exist_rel = false;
    } else {
        // To be able to later display a link to the related table,
        // we verify both types of relations: either those that are
        // native foreign keys or those defined in the phpMyAdmin
        // configuration storage. If no PMA storage, we won't be able
        // to use the "column to display" notion (for example show
        // the name related to a numeric id).
        $exist_rel = PMA_getForeigners($db, $table, '', 'both');
        if ($exist_rel) {
            foreach ($exist_rel as $master_field => $rel) {
                $display_field = PMA_getDisplayField($rel['foreign_db'], $rel['foreign_table']);
                $map[$master_field] = array($rel['foreign_table'], $rel['foreign_field'], $display_field, $rel['foreign_db']);
            }
            // end while
        }
        // end if
    }
    // end if
    // end 2b
    // 3. ----- Displays the results table -----
    PMA_displayTableHeaders($is_display, $fields_meta, $fields_cnt, $analyzed_sql, $sort_expression, $sort_expression_nodirection, $sort_direction);
    $url_query = '';
    echo '<tbody>' . "\n";
    $clause_is_unique = PMA_displayTableBody($dt_result, $is_display, $map, $analyzed_sql);
    // vertical output case
    if ($_SESSION['tmp_user_values']['disp_direction'] == 'vertical') {
        PMA_displayVerticalTable();
    }
    // end if
    unset($vertical_display);
    echo '</tbody>' . "\n";
    ?>
</table>

    <?php 
    // 4. ----- Displays the link for multi-fields edit and delete
    if ($is_display['del_lnk'] == 'dr' && $is_display['del_lnk'] != 'kp') {
        $delete_text = $is_display['del_lnk'] == 'dr' ? __('Delete') : __('Kill');
        $_url_params = array('db' => $db, 'table' => $table, 'sql_query' => $sql_query, 'goto' => $goto);
        $uncheckall_url = 'sql.php' . PMA_generate_common_url($_url_params);
        $_url_params['checkall'] = '1';
        $checkall_url = 'sql.php' . PMA_generate_common_url($_url_params);
        if ($_SESSION['tmp_user_values']['disp_direction'] == 'vertical') {
            $checkall_params['onclick'] = 'if (setCheckboxes(\'rowsDeleteForm\', true)) return false;';
            $uncheckall_params['onclick'] = 'if (setCheckboxes(\'rowsDeleteForm\', false)) return false;';
        } else {
            $checkall_params['onclick'] = 'if (markAllRows(\'rowsDeleteForm\')) return false;';
            $uncheckall_params['onclick'] = 'if (unMarkAllRows(\'rowsDeleteForm\')) return false;';
        }
        $checkall_link = PMA_linkOrButton($checkall_url, __('Check All'), $checkall_params, false);
        $uncheckall_link = PMA_linkOrButton($uncheckall_url, __('Uncheck All'), $uncheckall_params, false);
        if ($_SESSION['tmp_user_values']['disp_direction'] != 'vertical') {
            echo '<img class="selectallarrow" width="38" height="22"' . ' src="' . $GLOBALS['pmaThemeImage'] . 'arrow_' . $GLOBALS['text_dir'] . '.png' . '"' . ' alt="' . __('With selected:') . '" />';
        }
        echo $checkall_link . "\n" . ' / ' . "\n" . $uncheckall_link . "\n" . '<i>' . __('With selected:') . '</i>' . "\n";
        PMA_buttonOrImage('submit_mult', 'mult_submit', 'submit_mult_change', __('Change'), 'b_edit.png', 'edit');
        PMA_buttonOrImage('submit_mult', 'mult_submit', 'submit_mult_delete', $delete_text, 'b_drop.png', 'delete');
        if (isset($analyzed_sql[0]) && $analyzed_sql[0]['querytype'] == 'SELECT') {
            PMA_buttonOrImage('submit_mult', 'mult_submit', 'submit_mult_export', __('Export'), 'b_tblexport.png', 'export');
        }
        echo "\n";
        echo '<input type="hidden" name="sql_query"' . ' value="' . htmlspecialchars($sql_query) . '" />' . "\n";
        if (!empty($GLOBALS['url_query'])) {
            echo '<input type="hidden" name="url_query"' . ' value="' . $GLOBALS['url_query'] . '" />' . "\n";
        }
        echo '<input type="hidden" name="clause_is_unique"' . ' value="' . $clause_is_unique . '" />' . "\n";
        echo '</form>' . "\n";
    }
    // 5. ----- Displays the navigation bar at the bottom if required -----
    if ($is_display['nav_bar'] == '1') {
        echo '<br />' . "\n";
        PMA_displayTableNavigation($pos_next, $pos_prev, $sql_query, 'bottom_direction_dropdown');
    } elseif (!isset($GLOBALS['printview']) || $GLOBALS['printview'] != '1') {
        echo "\n" . '<br /><br />' . "\n";
    }
    // 6. ----- Displays "Query results operations"
    if (!isset($GLOBALS['printview']) || $GLOBALS['printview'] != '1') {
        PMA_displayResultsOperations($the_disp_mode, $analyzed_sql);
    }
}