Example #1
0
/**
 * Displays the headers of the results table
 *
 * @param   array    which elements to display
 * @param   array    the list of fields properties
 * @param   integer  the total number of fields returned by the sql query
 * @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  boolean  $dontlimitchars   whether to limit the number of displayed
 *                                     characters of text type fields or not
 * @global  string   $sql_query        the sql query
 * @global  integer  $num_rows         the total number of rows returned by the
 *                                     sql query
 * @global  integer  $pos              the current position in results
 * @global  integer  $session_max_rows the maximum number of rows per page
 * @global  array    $vertical_display informations used with vertical display
 *                                     mode
 * @global  string   $disp_direction   the display mode
 *                                     (horizontal/vertical/horizontalflipped)
 * @global  integer  $repeat_cellsthe  number of row to display between two
 *                                     table headers
 *
 * @access  private
 *
 * @see     PMA_displayTable()
 */
function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $analyzed_sql = '')
{
    global $db, $table, $goto, $dontlimitchars;
    global $sql_query, $num_rows, $pos, $session_max_rows;
    global $vertical_display, $disp_direction, $repeat_cells, $highlight_columns;
    if ($analyzed_sql == '') {
        $analyzed_sql = array();
    }
    // can the result be sorted?
    if ($is_display['sort_lnk'] == '1') {
        // Just as fallback
        $unsorted_sql_query = $sql_query;
        if (isset($analyzed_sql[0]['unsorted_query'])) {
            $unsorted_sql_query = $analyzed_sql[0]['unsorted_query'];
        }
        // we need $sort_expression and $sort_expression_nodir
        // even if there are many table references
        $sort_expression = trim(str_replace('  ', ' ', $analyzed_sql[0]['order_by_clause']));
        // Get rid of ASC|DESC (TODO: analyzer)
        preg_match('@(.*)([[:space:]]*(ASC|DESC))@si', $sort_expression, $matches);
        $sort_expression_nodir = isset($matches[1]) ? trim($matches[1]) : $sort_expression;
        // sorting by indexes, only if it makes sense (only one table ref)
        if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['querytype']) && $analyzed_sql[0]['querytype'] == 'SELECT' && isset($analyzed_sql[0]['table_ref']) && count($analyzed_sql[0]['table_ref']) == 1) {
            // grab indexes data:
            PMA_DBI_select_db($db);
            if (!defined('PMA_IDX_INCLUDED')) {
                $ret_keys = PMA_get_indexes($table);
            }
            $prev_index = '';
            foreach ($ret_keys as $row) {
                if ($row['Key_name'] != $prev_index) {
                    $indexes[] = $row['Key_name'];
                    $prev_index = $row['Key_name'];
                }
                $indexes_info[$row['Key_name']]['Sequences'][] = $row['Seq_in_index'];
                $indexes_info[$row['Key_name']]['Non_unique'] = $row['Non_unique'];
                if (isset($row['Cardinality'])) {
                    $indexes_info[$row['Key_name']]['Cardinality'] = $row['Cardinality'];
                }
                //    I don't know what does the following column mean....
                //    $indexes_info[$row['Key_name']]['Packed']          = $row['Packed'];
                $indexes_info[$row['Key_name']]['Comment'] = isset($row['Comment']) ? $row['Comment'] : '';
                $indexes_info[$row['Key_name']]['Index_type'] = isset($row['Index_type']) ? $row['Index_type'] : '';
                $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name'] = $row['Column_name'];
                if (isset($row['Sub_part'])) {
                    $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part'] = $row['Sub_part'];
                }
            }
            // end while
            // do we have any index?
            if (isset($indexes_data)) {
                if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
                    $span = $fields_cnt;
                    if ($is_display['edit_lnk'] != 'nn') {
                        $span++;
                    }
                    if ($is_display['del_lnk'] != 'nn') {
                        $span++;
                    }
                    if ($is_display['del_lnk'] != 'kp' && $is_display['del_lnk'] != 'nn') {
                        $span++;
                    }
                } else {
                    $span = $num_rows + floor($num_rows / $repeat_cells) + 1;
                }
                echo '<form action="sql.php" method="post">' . "\n";
                echo PMA_generate_common_hidden_inputs($db, $table, 5);
                echo '<input type="hidden" name="pos" value="' . $pos . '" />' . "\n";
                echo '<input type="hidden" name="session_max_rows" value="' . $session_max_rows . '" />' . "\n";
                echo '<input type="hidden" name="disp_direction" value="' . $disp_direction . '" />' . "\n";
                echo '<input type="hidden" name="repeat_cells" value="' . $repeat_cells . '" />' . "\n";
                echo '<input type="hidden" name="dontlimitchars" value="' . $dontlimitchars . '" />' . "\n";
                echo $GLOBALS['strSortByKey'] . ': <select name="sql_query">' . "\n";
                $used_index = false;
                $local_order = isset($sort_expression) ? $sort_expression : '';
                foreach ($indexes_data as $key => $val) {
                    $asc_sort = '';
                    $desc_sort = '';
                    foreach ($val as $key2 => $val2) {
                        $asc_sort .= PMA_backquote($val2['Column_name']) . ' ASC , ';
                        $desc_sort .= PMA_backquote($val2['Column_name']) . ' DESC , ';
                    }
                    $asc_sort = substr($asc_sort, 0, -3);
                    $desc_sort = substr($desc_sort, 0, -3);
                    $used_index = $used_index || $local_order == $asc_sort || $local_order == $desc_sort;
                    echo '<option value="' . htmlspecialchars($unsorted_sql_query . ' ORDER BY ' . $asc_sort) . '"' . ($local_order == $asc_sort ? ' selected="selected"' : '') . '>' . htmlspecialchars($key) . ' (' . $GLOBALS['strAscending'] . ')</option>';
                    echo "\n";
                    echo '<option value="' . htmlspecialchars($unsorted_sql_query . ' ORDER BY ' . $desc_sort) . '"' . ($local_order == $desc_sort ? ' selected="selected"' : '') . '>' . htmlspecialchars($key) . ' (' . $GLOBALS['strDescending'] . ')</option>';
                    echo "\n";
                }
                echo '<option value="' . htmlspecialchars($unsorted_sql_query) . '"' . ($used_index ? '' : ' selected="selected"') . '>' . $GLOBALS['strNone'] . '</option>';
                echo "\n";
                echo '</select>' . "\n";
                echo '<input type="submit" value="' . $GLOBALS['strGo'] . '" />';
                echo "\n";
                echo '</form>' . "\n";
            }
        }
    }
    $vertical_display['emptypre'] = 0;
    $vertical_display['emptyafter'] = 0;
    $vertical_display['textbtn'] = '';
    // Start of form for multi-rows delete
    if ($is_display['del_lnk'] == 'dr' || $is_display['del_lnk'] == 'kp') {
        echo '<form method="post" action="tbl_row_action.php" name="rowsDeleteForm" id="rowsDeleteForm">' . "\n";
        echo PMA_generate_common_hidden_inputs($db, $table, 1);
        echo '<input type="hidden" name="disp_direction"   value="' . $disp_direction . '" />' . "\n";
        echo '<input type="hidden" name="repeat_cells"     value="' . $repeat_cells . '" />' . "\n";
        echo '<input type="hidden" name="dontlimitchars"   value="' . $dontlimitchars . '" />' . "\n";
        echo '<input type="hidden" name="pos"              value="' . $pos . '" />' . "\n";
        echo '<input type="hidden" name="session_max_rows" value="' . $session_max_rows . '" />' . "\n";
        echo '<input type="hidden" name="goto"             value="sql.php" />' . "\n";
    }
    echo '<table id="table_results" class="data">' . "\n";
    if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
        echo '<thead><tr>' . "\n";
    }
    // 1. Displays the full/partial text button (part 1)...
    if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
        $colspan = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? ' colspan="3"' : '';
    } else {
        $rowspan = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? ' rowspan="3"' : '';
    }
    $text_url = 'sql.php?' . PMA_generate_common_url($db, $table) . '&amp;sql_query=' . urlencode($sql_query) . '&amp;session_max_rows=' . $session_max_rows . '&amp;pos=' . $pos . '&amp;disp_direction=' . $disp_direction . '&amp;repeat_cells=' . $repeat_cells . '&amp;goto=' . $goto . '&amp;dontlimitchars=' . ($dontlimitchars ? 0 : 1);
    $text_message = '<img class="fulltext" src="' . $GLOBALS['pmaThemeImage'] . 's_' . ($dontlimitchars ? 'partialtext' : 'fulltext') . '.png" width="50" height="20" alt="' . ($dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText']) . '" title="' . ($dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText']) . '" />';
    $text_link = PMA_linkOrButton($text_url, $text_message, array(), false);
    //     ... before the result table
    if ($is_display['edit_lnk'] == 'nn' && $is_display['del_lnk'] == 'nn' && $is_display['text_btn'] == '1') {
        $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 0;
        if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
            ?>
    <th colspan="<?php 
            echo $fields_cnt;
            ?>
"><?php 
            echo $text_link;
            ?>
</th>
</tr>
<tr>
            <?php 
        } else {
            ?>
<tr>
    <th colspan="<?php 
            echo $num_rows + floor($num_rows / $repeat_cells) + 1;
            ?>
">
        <?php 
            echo $text_link;
            ?>
</th>
</tr>
            <?php 
        }
        // end vertical mode
    } elseif ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && $is_display['text_btn'] == '1') {
        $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 0;
        if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
            ?>
    <th <?php 
            echo $colspan;
            ?>
><?php 
            echo $text_link;
            ?>
</th>
            <?php 
        } else {
            $vertical_display['textbtn'] = '    <th ' . $rowspan . ' valign="middle">' . "\n" . '        ' . $text_link . "\n" . '    </th>' . "\n";
        }
        // end vertical mode
    } elseif ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn')) {
        $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 0;
        if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
            ?>
    <td<?php 
            echo $colspan;
            ?>
></td>
            <?php 
        } else {
            $vertical_display['textbtn'] = '    <td' . $rowspan . '></td>' . "\n";
        }
        // end vertical mode
    }
    // 2. Displays the fields' name
    // 2.0 If sorting links should be used, checks if the query is a "JOIN"
    //     statement (see 2.1.3)
    // 2.0.1 Prepare Display column comments if enabled ($GLOBALS['cfg']['ShowBrowseComments']).
    //       Do not show comments, if using horizontalflipped mode, because of space usage
    if ($GLOBALS['cfg']['ShowBrowseComments'] && ($GLOBALS['cfgRelation']['commwork'] || PMA_MYSQL_INT_VERSION >= 40100) && $disp_direction != 'horizontalflipped') {
        $comments_map = array();
        if (isset($analyzed_sql[0]) && is_array($analyzed_sql[0])) {
            foreach ($analyzed_sql[0]['table_ref'] as $tbl) {
                $tb = $tbl['table_true_name'];
                $comments_map[$tb] = PMA_getComments($db, $tb);
                unset($tb);
            }
        }
    }
    if ($GLOBALS['cfgRelation']['commwork'] && $GLOBALS['cfgRelation']['mimework'] && $GLOBALS['cfg']['BrowseMIME']) {
        require_once './libraries/transformations.lib.php';
        $GLOBALS['mime_map'] = PMA_getMIME($db, $table);
    }
    if ($is_display['sort_lnk'] == '1') {
        //$is_join = preg_match('@(.*)[[:space:]]+FROM[[:space:]]+.*[[:space:]]+JOIN@im', $sql_query, $select_stt);
        $is_join = isset($analyzed_sql[0]['queryflags']['join']) ? true : false;
        $select_expr = $analyzed_sql[0]['select_expr_clause'];
    } else {
        $is_join = false;
    }
    // garvin: See if we have to highlight any header fields of a WHERE query.
    //  Uses SQL-Parser results.
    $highlight_columns = array();
    if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['where_clause_identifiers'])) {
        $wi = 0;
        if (isset($analyzed_sql[0]['where_clause_identifiers']) && is_array($analyzed_sql[0]['where_clause_identifiers'])) {
            foreach ($analyzed_sql[0]['where_clause_identifiers'] as $wci_nr => $wci) {
                $highlight_columns[$wci] = 'true';
            }
        }
    }
    for ($i = 0; $i < $fields_cnt; $i++) {
        // garvin: See if this column should get highlight because it's used in the
        //  where-query.
        if (isset($highlight_columns[$fields_meta[$i]->name]) || isset($highlight_columns[PMA_backquote($fields_meta[$i]->name)])) {
            $condition_field = true;
        } else {
            $condition_field = false;
        }
        // 2.0 Prepare comment-HTML-wrappers for each row, if defined/enabled.
        if (isset($comments_map) && isset($comments_map[$fields_meta[$i]->table]) && isset($comments_map[$fields_meta[$i]->table][$fields_meta[$i]->name])) {
            $comments = '<span class="tblcomment">' . htmlspecialchars($comments_map[$fields_meta[$i]->table][$fields_meta[$i]->name]) . '</span>';
        } else {
            $comments = '';
        }
        // 2.1 Results can be sorted
        if ($is_display['sort_lnk'] == '1') {
            // 2.1.1 Checks if the table name is required; it's the case
            //       for a query with a "JOIN" statement and if the column
            //       isn't aliased, or in queries like
            //       SELECT `1`.`master_field` , `2`.`master_field`
            //       FROM `PMA_relation` AS `1` , `PMA_relation` AS `2`
            /**
             * we prefer always using table if existing
             * and second this code does not correctly check $fields_meta[$i]->table
            if (($is_join
                && !preg_match('~([^[:space:],]|`[^`]`)[[:space:]]+(as[[:space:]]+)?' . strtr($fields_meta[$i]->name, array('[' => '\\[', '~' => '\\~', '\\' => '\\\\')) . '~i', $select_expr, $parts))
               || (isset($analyzed_sql[0]['select_expr'][$i]['expr'])
                   && isset($analyzed_sql[0]['select_expr'][$i]['column'])
                   && $analyzed_sql[0]['select_expr'][$i]['expr'] !=
                   $analyzed_sql[0]['select_expr'][$i]['column']
                  && isset($fields_meta[$i]->table) && strlen($fields_meta[$i]->table))) {
            */
            if (isset($fields_meta[$i]->table) && strlen($fields_meta[$i]->table)) {
                $sort_tbl = PMA_backquote($fields_meta[$i]->table) . '.';
            } else {
                $sort_tbl = '';
            }
            // 2.1.2 Checks if the current column is used to sort the
            //       results
            if (empty($sort_expression)) {
                $is_in_sort = false;
            } else {
                // field name may be preceded by a space, or any number
                // of characters followed by a dot (tablename.fieldname)
                // so do a direct comparison
                // for the sort expression (avoids problems with queries
                // like "SELECT id, count(id)..." and clicking to sort
                // on id or on count(id))
                $is_in_sort = $sort_tbl . PMA_backquote($fields_meta[$i]->name) == $sort_expression_nodir ? true : false;
            }
            // 2.1.3 Check the field name for backquotes.
            //       If it contains some, it's probably a function column
            //       like 'COUNT(`field`)'
            if (strpos($fields_meta[$i]->name, '`') !== false) {
                $sort_order = ' ORDER BY ' . PMA_backquote($fields_meta[$i]->name) . ' ';
            } else {
                $sort_order = ' ORDER BY ' . $sort_tbl . PMA_backquote($fields_meta[$i]->name) . ' ';
            }
            // 2.1.4 Do define the sorting url
            if (!$is_in_sort) {
                // loic1: patch #455484 ("Smart" order)
                $GLOBALS['cfg']['Order'] = strtoupper($GLOBALS['cfg']['Order']);
                if ($GLOBALS['cfg']['Order'] == 'SMART') {
                    $GLOBALS['cfg']['Order'] = preg_match('@time|date@i', $fields_meta[$i]->type) ? 'DESC' : 'ASC';
                }
                $sort_order .= $GLOBALS['cfg']['Order'];
                $order_img = '';
            } elseif (preg_match('@[[:space:]]ASC$@i', $sort_expression)) {
                $sort_order .= ' DESC';
                $order_img = ' <img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 's_asc.png" width="11" height="9" alt="' . $GLOBALS['strAscending'] . '" title="' . $GLOBALS['strAscending'] . '" id="soimg' . $i . '" />';
            } elseif (preg_match('@[[:space:]]DESC$@i', $sort_expression)) {
                $sort_order .= ' ASC';
                $order_img = ' <img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 's_desc.png" width="11" height="9" alt="' . $GLOBALS['strDescending'] . '" title="' . $GLOBALS['strDescending'] . '" id="soimg' . $i . '" />';
            } else {
                $sort_order .= ' DESC';
                $order_img = ' <img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 's_asc.png" width="11" height="9" alt="' . $GLOBALS['strAscending'] . '" title="' . $GLOBALS['strAscending'] . '" id="soimg' . $i . '" />';
            }
            if (preg_match('@(.*)([[:space:]](LIMIT (.*)|PROCEDURE (.*)|FOR UPDATE|LOCK IN SHARE MODE))@i', $unsorted_sql_query, $regs3)) {
                $sorted_sql_query = $regs3[1] . $sort_order . $regs3[2];
            } else {
                $sorted_sql_query = $unsorted_sql_query . $sort_order;
            }
            $url_query = PMA_generate_common_url($db, $table) . '&amp;pos=' . $pos . '&amp;session_max_rows=' . $session_max_rows . '&amp;disp_direction=' . $disp_direction . '&amp;repeat_cells=' . $repeat_cells . '&amp;dontlimitchars=' . $dontlimitchars . '&amp;sql_query=' . urlencode($sorted_sql_query);
            $order_url = 'sql.php?' . $url_query;
            // 2.1.5 Displays the sorting url
            // added 20004-06-09: Michael Keck <*****@*****.**>
            //                    enable sord order swapping for image
            $order_link_params = array();
            if (isset($order_img) && $order_img != '') {
                if (strstr($order_img, 'asc')) {
                    $order_link_params['onmouseover'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_desc.png\'; }';
                    $order_link_params['onmouseout'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_asc.png\'; }';
                } elseif (strstr($order_img, 'desc')) {
                    $order_link_params['onmouseover'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_asc.png\'; }';
                    $order_link_params['onmouseout'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_desc.png\'; }';
                }
            }
            if ($disp_direction == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'css') {
                $order_link_params['style'] = 'direction: ltr; writing-mode: tb-rl;';
            }
            $order_link_params['title'] = $GLOBALS['strSort'];
            $order_link_content = $disp_direction == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'fake' ? PMA_flipstring(htmlspecialchars($fields_meta[$i]->name), "<br />\n") : htmlspecialchars($fields_meta[$i]->name);
            $order_link = PMA_linkOrButton($order_url, $order_link_content . $order_img, $order_link_params, false, true);
            if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
                echo '<th';
                if ($condition_field) {
                    echo ' class="condition"';
                }
                if ($disp_direction == 'horizontalflipped') {
                    echo ' valign="bottom"';
                }
                echo '>' . $order_link . $comments . '</th>';
            }
            $vertical_display['desc'][] = '    <th ' . ($condition_field ? ' class="condition"' : '') . '>' . "\n" . $order_link . $comments . '    </th>' . "\n";
        } else {
            if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
                echo '<th';
                if ($condition_field) {
                    echo ' class="condition"';
                }
                if ($disp_direction == 'horizontalflipped') {
                    echo ' valign="bottom"';
                }
                if ($disp_direction == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'css') {
                    echo ' style="direction: ltr; writing-mode: tb-rl;"';
                }
                echo '>';
                if ($disp_direction == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'fake') {
                    echo PMA_flipstring(htmlspecialchars($fields_meta[$i]->name), '<br />');
                } else {
                    echo htmlspecialchars($fields_meta[$i]->name);
                }
                echo "\n" . $comments . '</th>';
            }
            $vertical_display['desc'][] = '    <th ' . ($condition_field ? ' class="condition"' : '') . '>' . "\n" . '        ' . htmlspecialchars($fields_meta[$i]->name) . "\n" . $comments . '    </th>';
        }
        // end else (2.2)
    }
    // end for
    // 3. Displays the full/partial text button (part 2) at the right
    //    column of the result table header if possible and required...
    if ($GLOBALS['cfg']['ModifyDeleteAtRight'] && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn') && $is_display['text_btn'] == '1') {
        $vertical_display['emptyafter'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 1;
        if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
            echo "\n";
            ?>
<th <?php 
            echo $colspan;
            ?>
>
    <?php 
            echo $text_link;
            ?>
</th>
            <?php 
        } else {
            $vertical_display['textbtn'] = '    <th ' . $rowspan . ' valign="middle">' . "\n" . '        ' . $text_link . "\n" . '    </th>' . "\n";
        }
        // end vertical mode
    } elseif ($GLOBALS['cfg']['ModifyDeleteAtRight'] && ($is_display['edit_lnk'] == 'nn' && $is_display['del_lnk'] == 'nn') && !$GLOBALS['is_header_sent']) {
        $vertical_display['emptyafter'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 1;
        if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
            echo "\n";
            ?>
<td<?php 
            echo $colspan;
            ?>
></td>
            <?php 
        } else {
            $vertical_display['textbtn'] = '    <td' . $rowspan . '></td>' . "\n";
        }
        // end vertical mode
    }
    if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
        ?>
</tr>
</thead>
        <?php 
    }
    return true;
}
Example #2
0
/**
 * Displays the headers 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']
 * @param   array    which elements to display
 * @param   array    the list of fields properties
 * @param   integer  the total number of fields returned by the SQL query
 * @param   array    the analyzed query
 *
 * @return  boolean  $clause_is_unique 
 *
 * @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  integer  $num_rows         the total number of rows returned by the
 *                                     SQL query
 * @global  array    $vertical_display informations used with vertical display
 *                                     mode
 *
 * @access  private
 *
 * @see     PMA_displayTable()
 */
function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $analyzed_sql = '', $sort_expression, $sort_expression_nodirection, $sort_direction)
{
    global $db, $table, $goto;
    global $sql_query, $num_rows;
    global $vertical_display, $highlight_columns;
    if ($analyzed_sql == '') {
        $analyzed_sql = array();
    }
    // can the result be sorted?
    if ($is_display['sort_lnk'] == '1') {
        // Just as fallback
        $unsorted_sql_query = $sql_query;
        if (isset($analyzed_sql[0]['unsorted_query'])) {
            $unsorted_sql_query = $analyzed_sql[0]['unsorted_query'];
        }
        // Handles the case of multiple clicks on a column's header
        // which would add many spaces before "ORDER BY" in the
        // generated query.
        $unsorted_sql_query = trim($unsorted_sql_query);
        // sorting by indexes, only if it makes sense (only one table ref)
        if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['querytype']) && $analyzed_sql[0]['querytype'] == 'SELECT' && isset($analyzed_sql[0]['table_ref']) && count($analyzed_sql[0]['table_ref']) == 1) {
            // grab indexes data:
            $indexes = PMA_Index::getFromTable($table, $db);
            // do we have any index?
            if ($indexes) {
                if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
                    $span = $fields_cnt;
                    if ($is_display['edit_lnk'] != 'nn') {
                        $span++;
                    }
                    if ($is_display['del_lnk'] != 'nn') {
                        $span++;
                    }
                    if ($is_display['del_lnk'] != 'kp' && $is_display['del_lnk'] != 'nn') {
                        $span++;
                    }
                } else {
                    $span = $num_rows + floor($num_rows / $_SESSION['tmp_user_values']['repeat_cells']) + 1;
                }
                echo '<form action="sql.php" method="post">' . "\n";
                echo PMA_generate_common_hidden_inputs($db, $table);
                echo $GLOBALS['strSortByKey'] . ': <select name="sql_query" onchange="this.form.submit();">' . "\n";
                $used_index = false;
                $local_order = isset($sort_expression) ? $sort_expression : '';
                foreach ($indexes as $index) {
                    $asc_sort = '`' . implode('` ASC, `', array_keys($index->getColumns())) . '` ASC';
                    $desc_sort = '`' . implode('` DESC, `', array_keys($index->getColumns())) . '` DESC';
                    $used_index = $used_index || $local_order == $asc_sort || $local_order == $desc_sort;
                    echo '<option value="' . htmlspecialchars($unsorted_sql_query . ' ORDER BY ' . $asc_sort) . '"' . ($local_order == $asc_sort ? ' selected="selected"' : '') . '>' . htmlspecialchars($index->getName()) . ' (' . $GLOBALS['strAscending'] . ')</option>';
                    echo '<option value="' . htmlspecialchars($unsorted_sql_query . ' ORDER BY ' . $desc_sort) . '"' . ($local_order == $desc_sort ? ' selected="selected"' : '') . '>' . htmlspecialchars($index->getName()) . ' (' . $GLOBALS['strDescending'] . ')</option>';
                }
                echo '<option value="' . htmlspecialchars($unsorted_sql_query) . '"' . ($used_index ? '' : ' selected="selected"') . '>' . $GLOBALS['strNone'] . '</option>';
                echo '</select>' . "\n";
                echo '<noscript><input type="submit" value="' . $GLOBALS['strGo'] . '" /></noscript>';
                echo '</form>' . "\n";
            }
        }
    }
    $vertical_display['emptypre'] = 0;
    $vertical_display['emptyafter'] = 0;
    $vertical_display['textbtn'] = '';
    // Display options (if we are not in print view)
    if (!(isset($GLOBALS['printview']) && $GLOBALS['printview'] == '1')) {
        echo '<form method="post" action="sql.php" name="displayOptionsForm" id="displayOptionsForm">';
        $url_params = array('db' => $db, 'table' => $table, 'sql_query' => $sql_query, 'goto' => $goto, 'display_options_form' => 1);
        echo PMA_generate_common_hidden_inputs($url_params);
        echo '<br />';
        PMA_generate_slider_effect('displayoptions', $GLOBALS['strOptions']);
        echo '<fieldset>';
        echo '<div class="formelement">';
        $choices = array('P' => $GLOBALS['strPartialText'], 'F' => $GLOBALS['strFullText']);
        PMA_display_html_radio('display_text', $choices, $_SESSION['tmp_user_values']['display_text']);
        echo '</div>';
        // prepare full/partial text button or link
        if ($_SESSION['tmp_user_values']['display_text'] == 'F') {
            // currently in fulltext mode so show the opposite link
            $tmp_image_file = $GLOBALS['pmaThemeImage'] . 's_partialtext.png';
            $tmp_txt = $GLOBALS['strPartialText'];
            $url_params['display_text'] = 'P';
        } else {
            $tmp_image_file = $GLOBALS['pmaThemeImage'] . 's_fulltext.png';
            $tmp_txt = $GLOBALS['strFullText'];
            $url_params['display_text'] = 'F';
        }
        $tmp_image = '<img class="fulltext" width="50" height="20"  src="' . $tmp_image_file . '" alt="' . $tmp_txt . '" title="' . $tmp_txt . '" />';
        $tmp_url = 'sql.php' . PMA_generate_common_url($url_params);
        $full_or_partial_text_link = PMA_linkOrButton($tmp_url, $tmp_image, array(), false);
        unset($tmp_image_file, $tmp_txt, $tmp_url, $tmp_image);
        if ($GLOBALS['cfgRelation']['relwork'] && $GLOBALS['cfgRelation']['displaywork']) {
            echo '<div class="formelement">';
            $choices = array('K' => $GLOBALS['strRelationalKey'], 'D' => $GLOBALS['strRelationalDisplayField']);
            PMA_display_html_radio('relational_display', $choices, $_SESSION['tmp_user_values']['relational_display']);
            echo '</div>';
        }
        echo '<div class="formelement">';
        PMA_display_html_checkbox('display_binary', $GLOBALS['strShowBinaryContents'], !empty($_SESSION['tmp_user_values']['display_binary']), false);
        echo '<br />';
        PMA_display_html_checkbox('display_blob', $GLOBALS['strShowBLOBContents'], !empty($_SESSION['tmp_user_values']['display_blob']), false);
        echo '<br />';
        PMA_display_html_checkbox('display_binary_as_hex', $GLOBALS['strShowBinaryContentsAsHex'], !empty($_SESSION['tmp_user_values']['display_binary_as_hex']), false);
        echo '</div>';
        // I would have preferred to name this "display_transformation".
        // This is the only way I found to be able to keep this setting sticky
        // per SQL query, and at the same time have a default that displays
        // the transformations.
        echo '<div class="formelement">';
        PMA_display_html_checkbox('hide_transformation', $GLOBALS['strHide'] . ' ' . $GLOBALS['strMIME_transformation'], !empty($_SESSION['tmp_user_values']['hide_transformation']), false);
        echo '</div>';
        echo '<div class="clearfloat"></div>';
        echo '</fieldset>';
        echo '<fieldset class="tblFooters">';
        echo '<input type="submit" value="' . $GLOBALS['strGo'] . '" />';
        echo '</fieldset>';
        echo '</div>';
        echo '</form>';
    }
    // Start of form for multi-rows edit/delete/export
    if ($is_display['del_lnk'] == 'dr' || $is_display['del_lnk'] == 'kp') {
        echo '<form method="post" action="tbl_row_action.php" name="rowsDeleteForm" id="rowsDeleteForm">' . "\n";
        echo PMA_generate_common_hidden_inputs($db, $table, 1);
        echo '<input type="hidden" name="goto"             value="sql.php" />' . "\n";
    }
    echo '<table id="table_results" class="data">' . "\n";
    if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
        echo '<thead><tr>' . "\n";
    }
    // 1. Displays the full/partial text button (part 1)...
    if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
        $colspan = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? ' colspan="3"' : '';
    } else {
        $rowspan = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? ' rowspan="3"' : '';
    }
    //     ... before the result table
    if ($is_display['edit_lnk'] == 'nn' && $is_display['del_lnk'] == 'nn' && $is_display['text_btn'] == '1') {
        $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 0;
        if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
            ?>
    <th colspan="<?php 
            echo $fields_cnt;
            ?>
"></th>
</tr>
<tr>
            <?php 
        } else {
            ?>
<tr>
    <th colspan="<?php 
            echo $num_rows + floor($num_rows / $_SESSION['tmp_user_values']['repeat_cells']) + 1;
            ?>
"></th>
</tr>
            <?php 
        }
        // end vertical mode
    } elseif ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && $is_display['text_btn'] == '1') {
        $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 0;
        if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
            ?>
                <th <?php 
            echo $colspan;
            ?>
><?php 
            echo $full_or_partial_text_link;
            ?>
</th>
            <?php 
        } else {
            $vertical_display['textbtn'] = '    <th ' . $rowspan . ' valign="middle">' . "\n" . '        ' . "\n" . '    </th>' . "\n";
        }
        // end vertical mode
    } elseif ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn')) {
        $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 0;
        if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
            ?>
    <td<?php 
            echo $colspan;
            ?>
></td>
            <?php 
        } else {
            $vertical_display['textbtn'] = '    <td' . $rowspan . '></td>' . "\n";
        }
        // end vertical mode
    }
    // 2. Displays the fields' name
    // 2.0 If sorting links should be used, checks if the query is a "JOIN"
    //     statement (see 2.1.3)
    // 2.0.1 Prepare Display column comments if enabled ($GLOBALS['cfg']['ShowBrowseComments']).
    //       Do not show comments, if using horizontalflipped mode, because of space usage
    if ($GLOBALS['cfg']['ShowBrowseComments'] && $_SESSION['tmp_user_values']['disp_direction'] != 'horizontalflipped') {
        $comments_map = array();
        if (isset($analyzed_sql[0]) && is_array($analyzed_sql[0])) {
            foreach ($analyzed_sql[0]['table_ref'] as $tbl) {
                $tb = $tbl['table_true_name'];
                $comments_map[$tb] = PMA_getComments($db, $tb);
                unset($tb);
            }
        }
    }
    if ($GLOBALS['cfgRelation']['commwork'] && $GLOBALS['cfgRelation']['mimework'] && $GLOBALS['cfg']['BrowseMIME'] && !$_SESSION['tmp_user_values']['hide_transformation']) {
        require_once './libraries/transformations.lib.php';
        $GLOBALS['mime_map'] = PMA_getMIME($db, $table);
    }
    if ($is_display['sort_lnk'] == '1') {
        $select_expr = $analyzed_sql[0]['select_expr_clause'];
    }
    // garvin: See if we have to highlight any header fields of a WHERE query.
    //  Uses SQL-Parser results.
    $highlight_columns = array();
    if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['where_clause_identifiers'])) {
        $wi = 0;
        if (isset($analyzed_sql[0]['where_clause_identifiers']) && is_array($analyzed_sql[0]['where_clause_identifiers'])) {
            foreach ($analyzed_sql[0]['where_clause_identifiers'] as $wci_nr => $wci) {
                $highlight_columns[$wci] = 'true';
            }
        }
    }
    for ($i = 0; $i < $fields_cnt; $i++) {
        // garvin: See if this column should get highlight because it's used in the
        //  where-query.
        if (isset($highlight_columns[$fields_meta[$i]->name]) || isset($highlight_columns[PMA_backquote($fields_meta[$i]->name)])) {
            $condition_field = true;
        } else {
            $condition_field = false;
        }
        // 2.0 Prepare comment-HTML-wrappers for each row, if defined/enabled.
        if (isset($comments_map) && isset($comments_map[$fields_meta[$i]->table]) && isset($comments_map[$fields_meta[$i]->table][$fields_meta[$i]->name])) {
            $comments = '<span class="tblcomment">' . htmlspecialchars($comments_map[$fields_meta[$i]->table][$fields_meta[$i]->name]) . '</span>';
        } else {
            $comments = '';
        }
        // 2.1 Results can be sorted
        if ($is_display['sort_lnk'] == '1') {
            // 2.1.1 Checks if the table name is required; it's the case
            //       for a query with a "JOIN" statement and if the column
            //       isn't aliased, or in queries like
            //       SELECT `1`.`master_field` , `2`.`master_field`
            //       FROM `PMA_relation` AS `1` , `PMA_relation` AS `2`
            if (isset($fields_meta[$i]->table) && strlen($fields_meta[$i]->table)) {
                $sort_tbl = PMA_backquote($fields_meta[$i]->table) . '.';
            } else {
                $sort_tbl = '';
            }
            // 2.1.2 Checks if the current column is used to sort the
            //       results
            // the orgname member does not exist for all MySQL versions
            // but if found, it's the one on which to sort
            $name_to_use_in_sort = $fields_meta[$i]->name;
            if (isset($fields_meta[$i]->orgname) && strlen($fields_meta[$i]->orgname)) {
                $name_to_use_in_sort = $fields_meta[$i]->orgname;
            }
            // $name_to_use_in_sort might contain a space due to
            // formatting of function expressions like "COUNT(name )"
            // so we remove the space in this situation
            $name_to_use_in_sort = str_replace(' )', ')', $name_to_use_in_sort);
            if (empty($sort_expression)) {
                $is_in_sort = false;
            } else {
                // Field name may be preceded by a space, or any number
                // of characters followed by a dot (tablename.fieldname)
                // so do a direct comparison for the sort expression;
                // this avoids problems with queries like
                // "SELECT id, count(id)..." and clicking to sort
                // on id or on count(id).
                // Another query to test this:
                // SELECT p.*, FROM_UNIXTIME(p.temps) FROM mytable AS p
                // (and try clicking on each column's header twice)
                if (!empty($sort_tbl) && strpos($sort_expression_nodirection, $sort_tbl) === false && strpos($sort_expression_nodirection, '(') === false) {
                    $sort_expression_nodirection = $sort_tbl . $sort_expression_nodirection;
                }
                $is_in_sort = str_replace('`', '', $sort_tbl) . $name_to_use_in_sort == str_replace('`', '', $sort_expression_nodirection) ? true : false;
            }
            // 2.1.3 Check the field name for a bracket.
            //       If it contains one, it's probably a function column
            //       like 'COUNT(`field`)'
            if (strpos($name_to_use_in_sort, '(') !== false) {
                $sort_order = ' ORDER BY ' . $name_to_use_in_sort . ' ';
            } else {
                $sort_order = ' ORDER BY ' . $sort_tbl . PMA_backquote($name_to_use_in_sort) . ' ';
            }
            unset($name_to_use_in_sort);
            // 2.1.4 Do define the sorting URL
            if (!$is_in_sort) {
                // loic1: patch #455484 ("Smart" order)
                $GLOBALS['cfg']['Order'] = strtoupper($GLOBALS['cfg']['Order']);
                if ($GLOBALS['cfg']['Order'] === 'SMART') {
                    $sort_order .= preg_match('@time|date@i', $fields_meta[$i]->type) ? 'DESC' : 'ASC';
                } else {
                    $sort_order .= $GLOBALS['cfg']['Order'];
                }
                $order_img = '';
            } elseif ('DESC' == $sort_direction) {
                $sort_order .= ' ASC';
                $order_img = ' <img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 's_desc.png" width="11" height="9" alt="' . $GLOBALS['strDescending'] . '" title="' . $GLOBALS['strDescending'] . '" id="soimg' . $i . '" />';
            } else {
                $sort_order .= ' DESC';
                $order_img = ' <img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 's_asc.png" width="11" height="9" alt="' . $GLOBALS['strAscending'] . '" title="' . $GLOBALS['strAscending'] . '" id="soimg' . $i . '" />';
            }
            if (preg_match('@(.*)([[:space:]](LIMIT (.*)|PROCEDURE (.*)|FOR UPDATE|LOCK IN SHARE MODE))@i', $unsorted_sql_query, $regs3)) {
                $sorted_sql_query = $regs3[1] . $sort_order . $regs3[2];
            } else {
                $sorted_sql_query = $unsorted_sql_query . $sort_order;
            }
            $_url_params = array('db' => $db, 'table' => $table, 'sql_query' => $sorted_sql_query);
            $order_url = 'sql.php' . PMA_generate_common_url($_url_params);
            // 2.1.5 Displays the sorting URL
            // added 20004-06-09: Michael Keck <*****@*****.**>
            //                    enable sort order swapping for image
            $order_link_params = array();
            if (isset($order_img) && $order_img != '') {
                if (strstr($order_img, 'asc')) {
                    $order_link_params['onmouseover'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_desc.png\'; }';
                    $order_link_params['onmouseout'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_asc.png\'; }';
                } elseif (strstr($order_img, 'desc')) {
                    $order_link_params['onmouseover'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_asc.png\'; }';
                    $order_link_params['onmouseout'] = 'if(document.getElementById(\'soimg' . $i . '\')){ document.getElementById(\'soimg' . $i . '\').src=\'' . $GLOBALS['pmaThemeImage'] . 's_desc.png\'; }';
                }
            }
            if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'css') {
                $order_link_params['style'] = 'direction: ltr; writing-mode: tb-rl;';
            }
            $order_link_params['title'] = $GLOBALS['strSort'];
            $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);
            $order_link = PMA_linkOrButton($order_url, $order_link_content . $order_img, $order_link_params, false, true);
            if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
                echo '<th';
                if ($condition_field) {
                    echo ' class="condition"';
                }
                if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
                    echo ' valign="bottom"';
                }
                echo '>' . $order_link . $comments . '</th>';
            }
            $vertical_display['desc'][] = '    <th ' . ($condition_field ? ' class="condition"' : '') . '>' . "\n" . $order_link . $comments . '    </th>' . "\n";
        } else {
            if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
                echo '<th';
                if ($condition_field) {
                    echo ' class="condition"';
                }
                if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
                    echo ' valign="bottom"';
                }
                if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'css') {
                    echo ' style="direction: ltr; writing-mode: tb-rl;"';
                }
                echo '>';
                if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'fake') {
                    echo PMA_flipstring(htmlspecialchars($fields_meta[$i]->name), '<br />');
                } else {
                    echo htmlspecialchars($fields_meta[$i]->name);
                }
                echo "\n" . $comments . '</th>';
            }
            $vertical_display['desc'][] = '    <th ' . ($condition_field ? ' class="condition"' : '') . '>' . "\n" . '        ' . htmlspecialchars($fields_meta[$i]->name) . "\n" . $comments . '    </th>';
        }
        // end else (2.2)
    }
    // end for
    // 3. Displays the needed checkboxes at the right
    //    column of the result table header if possible and required...
    if ($GLOBALS['cfg']['ModifyDeleteAtRight'] && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn') && $is_display['text_btn'] == '1') {
        $vertical_display['emptyafter'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 1;
        if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
            echo "\n";
            ?>
        <th <?php 
            echo $colspan;
            ?>
><?php 
            echo $full_or_partial_text_link;
            ?>
</th>
            <?php 
        } else {
            $vertical_display['textbtn'] = '    <th ' . $rowspan . ' valign="middle">' . "\n" . '        ' . "\n" . '    </th>' . "\n";
        }
        // end vertical mode
    } elseif ($GLOBALS['cfg']['ModifyDeleteAtRight'] && ($is_display['edit_lnk'] == 'nn' && $is_display['del_lnk'] == 'nn') && !$GLOBALS['is_header_sent']) {
        $vertical_display['emptyafter'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 1;
        if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
            echo "\n";
            ?>
<td<?php 
            echo $colspan;
            ?>
></td>
            <?php 
        } else {
            $vertical_display['textbtn'] = '    <td' . $rowspan . '></td>' . "\n";
        }
        // end vertical mode
    }
    if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
        ?>
</tr>
</thead>
        <?php 
    }
    return true;
}
Example #3
0
/**
 * Displays the headers of the results table
 *
 * @param array   &$is_display                 which elements to display
 * @param array   &$fields_meta                the list of fields properties
 * @param integer $fields_cnt                  the total number of fields returned by the SQL query
 * @param array   $analyzed_sql                the analyzed query
 * @param string  $sort_expression             sort expression
 * @param string  $sort_expression_nodirection sort expression without direction
 * @param string  $sort_direction              sort direction
 *
 * @return  boolean  $clause_is_unique
 *
 * @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  integer  $num_rows         the total number of rows returned by the
 *                                     SQL query
 * @global  array    $vertical_display informations used with vertical display
 *                                     mode
 *
 * @access  private
 *
 * @see     PMA_displayTable()
 */
function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $analyzed_sql = '', $sort_expression, $sort_expression_nodirection, $sort_direction)
{
    global $db, $table, $goto;
    global $sql_query, $num_rows;
    global $vertical_display, $highlight_columns;
    // required to generate sort links that will remember whether the
    // "Show all" button has been clicked
    $sql_md5 = md5($GLOBALS['sql_query']);
    $session_max_rows = $_SESSION['tmp_user_values']['query'][$sql_md5]['max_rows'];
    if ($analyzed_sql == '') {
        $analyzed_sql = array();
    }
    // can the result be sorted?
    if ($is_display['sort_lnk'] == '1') {
        // Just as fallback
        $unsorted_sql_query = $sql_query;
        if (isset($analyzed_sql[0]['unsorted_query'])) {
            $unsorted_sql_query = $analyzed_sql[0]['unsorted_query'];
        }
        // Handles the case of multiple clicks on a column's header
        // which would add many spaces before "ORDER BY" in the
        // generated query.
        $unsorted_sql_query = trim($unsorted_sql_query);
        // sorting by indexes, only if it makes sense (only one table ref)
        if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['querytype']) && $analyzed_sql[0]['querytype'] == 'SELECT' && isset($analyzed_sql[0]['table_ref']) && count($analyzed_sql[0]['table_ref']) == 1) {
            // grab indexes data:
            $indexes = PMA_Index::getFromTable($table, $db);
            // do we have any index?
            if ($indexes) {
                if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
                    $span = $fields_cnt;
                    if ($is_display['edit_lnk'] != 'nn') {
                        $span++;
                    }
                    if ($is_display['del_lnk'] != 'nn') {
                        $span++;
                    }
                    if ($is_display['del_lnk'] != 'kp' && $is_display['del_lnk'] != 'nn') {
                        $span++;
                    }
                } else {
                    $span = $num_rows + floor($num_rows / $_SESSION['tmp_user_values']['repeat_cells']) + 1;
                }
                echo '<form action="sql.php" method="post">' . "\n";
                echo PMA_generate_common_hidden_inputs($db, $table);
                echo __('Sort by key') . ': <select name="sql_query" class="autosubmit">' . "\n";
                $used_index = false;
                $local_order = isset($sort_expression) ? $sort_expression : '';
                foreach ($indexes as $index) {
                    $asc_sort = '`' . implode('` ASC, `', array_keys($index->getColumns())) . '` ASC';
                    $desc_sort = '`' . implode('` DESC, `', array_keys($index->getColumns())) . '` DESC';
                    $used_index = $used_index || $local_order == $asc_sort || $local_order == $desc_sort;
                    if (preg_match('@(.*)([[:space:]](LIMIT (.*)|PROCEDURE (.*)|FOR UPDATE|LOCK IN SHARE MODE))@is', $unsorted_sql_query, $my_reg)) {
                        $unsorted_sql_query_first_part = $my_reg[1];
                        $unsorted_sql_query_second_part = $my_reg[2];
                    } else {
                        $unsorted_sql_query_first_part = $unsorted_sql_query;
                        $unsorted_sql_query_second_part = '';
                    }
                    echo '<option value="' . htmlspecialchars($unsorted_sql_query_first_part . "\n" . ' ORDER BY ' . $asc_sort . $unsorted_sql_query_second_part) . '"' . ($local_order == $asc_sort ? ' selected="selected"' : '') . '>' . htmlspecialchars($index->getName()) . ' (' . __('Ascending') . ')</option>';
                    echo '<option value="' . htmlspecialchars($unsorted_sql_query_first_part . "\n" . ' ORDER BY ' . $desc_sort . $unsorted_sql_query_second_part) . '"' . ($local_order == $desc_sort ? ' selected="selected"' : '') . '>' . htmlspecialchars($index->getName()) . ' (' . __('Descending') . ')</option>';
                }
                echo '<option value="' . htmlspecialchars($unsorted_sql_query) . '"' . ($used_index ? '' : ' selected="selected"') . '>' . __('None') . '</option>';
                echo '</select>' . "\n";
                echo '<noscript><input type="submit" value="' . __('Go') . '" /></noscript>';
                echo '</form>' . "\n";
            }
        }
    }
    // Output data needed for grid editing
    echo '<input id="save_cells_at_once" type="hidden" value="' . $GLOBALS['cfg']['SaveCellsAtOnce'] . '" />';
    echo '<div class="common_hidden_inputs">';
    echo PMA_generate_common_hidden_inputs($db, $table);
    echo '</div>';
    // Output data needed for column reordering and show/hide column
    if (PMA_isSelect()) {
        // generate the column order, if it is set
        $pmatable = new PMA_Table($GLOBALS['table'], $GLOBALS['db']);
        $col_order = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_ORDER);
        if ($col_order) {
            echo '<input id="col_order" type="hidden" value="' . implode(',', $col_order) . '" />';
        }
        $col_visib = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_VISIB);
        if ($col_visib) {
            echo '<input id="col_visib" type="hidden" value="' . implode(',', $col_visib) . '" />';
        }
        // generate table create time
        if (!PMA_Table::isView($GLOBALS['table'], $GLOBALS['db'])) {
            echo '<input id="table_create_time" type="hidden" value="' . PMA_Table::sGetStatusInfo($GLOBALS['db'], $GLOBALS['table'], 'Create_time') . '" />';
        }
    }
    $vertical_display['emptypre'] = 0;
    $vertical_display['emptyafter'] = 0;
    $vertical_display['textbtn'] = '';
    // Display options (if we are not in print view)
    if (!(isset($GLOBALS['printview']) && $GLOBALS['printview'] == '1')) {
        echo '<form method="post" action="sql.php" name="displayOptionsForm" id="displayOptionsForm"';
        if ($GLOBALS['cfg']['AjaxEnable']) {
            echo ' class="ajax" ';
        }
        echo '>';
        $url_params = array('db' => $db, 'table' => $table, 'sql_query' => $sql_query, 'goto' => $goto, 'display_options_form' => 1);
        echo PMA_generate_common_hidden_inputs($url_params);
        echo '<br />';
        PMA_generate_slider_effect('displayoptions', __('Options'));
        echo '<fieldset>';
        echo '<div class="formelement">';
        $choices = array('P' => __('Partial texts'), 'F' => __('Full texts'));
        PMA_display_html_radio('display_text', $choices, $_SESSION['tmp_user_values']['display_text']);
        echo '</div>';
        // prepare full/partial text button or link
        $url_params_full_text = array('db' => $db, 'table' => $table, 'sql_query' => $sql_query, 'goto' => $goto, 'full_text_button' => 1);
        if ($_SESSION['tmp_user_values']['display_text'] == 'F') {
            // currently in fulltext mode so show the opposite link
            $tmp_image_file = $GLOBALS['pmaThemeImage'] . 's_partialtext.png';
            $tmp_txt = __('Partial texts');
            $url_params_full_text['display_text'] = 'P';
        } else {
            $tmp_image_file = $GLOBALS['pmaThemeImage'] . 's_fulltext.png';
            $tmp_txt = __('Full texts');
            $url_params_full_text['display_text'] = 'F';
        }
        $tmp_image = '<img class="fulltext" src="' . $tmp_image_file . '" alt="' . $tmp_txt . '" title="' . $tmp_txt . '" />';
        $tmp_url = 'sql.php' . PMA_generate_common_url($url_params_full_text);
        $full_or_partial_text_link = PMA_linkOrButton($tmp_url, $tmp_image, array(), false);
        unset($tmp_image_file, $tmp_txt, $tmp_url, $tmp_image);
        if ($GLOBALS['cfgRelation']['relwork'] && $GLOBALS['cfgRelation']['displaywork']) {
            echo '<div class="formelement">';
            $choices = array('K' => __('Relational key'), 'D' => __('Relational display column'));
            PMA_display_html_radio('relational_display', $choices, $_SESSION['tmp_user_values']['relational_display']);
            echo '</div>';
        }
        echo '<div class="formelement">';
        PMA_display_html_checkbox('display_binary', __('Show binary contents'), !empty($_SESSION['tmp_user_values']['display_binary']), false);
        echo '<br />';
        PMA_display_html_checkbox('display_blob', __('Show BLOB contents'), !empty($_SESSION['tmp_user_values']['display_blob']), false);
        echo '<br />';
        PMA_display_html_checkbox('display_binary_as_hex', __('Show binary contents as HEX'), !empty($_SESSION['tmp_user_values']['display_binary_as_hex']), false);
        echo '</div>';
        // I would have preferred to name this "display_transformation".
        // This is the only way I found to be able to keep this setting sticky
        // per SQL query, and at the same time have a default that displays
        // the transformations.
        echo '<div class="formelement">';
        PMA_display_html_checkbox('hide_transformation', __('Hide browser transformation'), !empty($_SESSION['tmp_user_values']['hide_transformation']), false);
        echo '</div>';
        if (!PMA_DRIZZLE) {
            echo '<div class="formelement">';
            $choices = array('GEOM' => __('Geometry'), 'WKT' => __('Well Known Text'), 'WKB' => __('Well Known Binary'));
            PMA_display_html_radio('geometry_display', $choices, $_SESSION['tmp_user_values']['geometry_display']);
            echo '</div>';
        }
        echo '<div class="clearfloat"></div>';
        echo '</fieldset>';
        echo '<fieldset class="tblFooters">';
        echo '<input type="submit" value="' . __('Go') . '" />';
        echo '</fieldset>';
        echo '</div>';
        echo '</form>';
    }
    // Start of form for multi-rows edit/delete/export
    if ($is_display['del_lnk'] == 'dr' || $is_display['del_lnk'] == 'kp') {
        echo '<form method="post" action="tbl_row_action.php" name="resultsForm" id="resultsForm"';
        if ($GLOBALS['cfg']['AjaxEnable']) {
            echo ' class="ajax" ';
        }
        echo '>' . "\n";
        echo PMA_generate_common_hidden_inputs($db, $table, 1);
        echo '<input type="hidden" name="goto"             value="sql.php" />' . "\n";
    }
    echo '<table id="table_results" class="data';
    if ($GLOBALS['cfg']['AjaxEnable']) {
        echo ' ajax';
    }
    echo '">' . "\n";
    if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
        echo '<thead><tr>' . "\n";
    }
    // 1. Displays the full/partial text button (part 1)...
    if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
        $colspan = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? ' colspan="4"' : '';
    } else {
        $rowspan = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? ' rowspan="4"' : '';
    }
    //     ... before the result table
    if ($is_display['edit_lnk'] == 'nn' && $is_display['del_lnk'] == 'nn' && $is_display['text_btn'] == '1') {
        $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 4 : 0;
        if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
            ?>
    <th colspan="<?php 
            echo $fields_cnt;
            ?>
"></th>
</tr>
<tr>
            <?php 
            // end horizontal/horizontalflipped mode
        } else {
            ?>
<tr>
    <th colspan="<?php 
            echo $num_rows + floor($num_rows / $_SESSION['tmp_user_values']['repeat_cells']) + 1;
            ?>
"></th>
</tr>
            <?php 
        }
        // end vertical mode
    } elseif (($GLOBALS['cfg']['RowActionLinks'] == 'left' || $GLOBALS['cfg']['RowActionLinks'] == 'both') && $is_display['text_btn'] == '1') {
        $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 4 : 0;
        if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
            ?>
                <th <?php 
            echo $colspan;
            ?>
><?php 
            echo $full_or_partial_text_link;
            ?>
</th>
            <?php 
            // end horizontal/horizontalflipped mode
        } else {
            $vertical_display['textbtn'] = '    <th ' . $rowspan . ' valign="middle">' . "\n" . '        ' . "\n" . '    </th>' . "\n";
        }
        // end vertical mode
    } elseif (($GLOBALS['cfg']['RowActionLinks'] == 'left' || $GLOBALS['cfg']['RowActionLinks'] == 'both') && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn')) {
        $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 4 : 0;
        if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
            ?>
    <td<?php 
            echo $colspan;
            ?>
></td>
            <?php 
            // end horizontal/horizontalfipped mode
        } else {
            $vertical_display['textbtn'] = '    <td' . $rowspan . '></td>' . "\n";
        }
        // end vertical mode
    } elseif ($GLOBALS['cfg']['RowActionLinks'] == 'none' && ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped')) {
        echo '<th></th>';
    }
    // 2. Displays the fields' name
    // 2.0 If sorting links should be used, checks if the query is a "JOIN"
    //     statement (see 2.1.3)
    // 2.0.1 Prepare Display column comments if enabled ($GLOBALS['cfg']['ShowBrowseComments']).
    //       Do not show comments, if using horizontalflipped mode, because of space usage
    if ($GLOBALS['cfg']['ShowBrowseComments'] && $_SESSION['tmp_user_values']['disp_direction'] != 'horizontalflipped') {
        $comments_map = array();
        if (isset($analyzed_sql[0]) && is_array($analyzed_sql[0])) {
            foreach ($analyzed_sql[0]['table_ref'] as $tbl) {
                $tb = $tbl['table_true_name'];
                $comments_map[$tb] = PMA_getComments($db, $tb);
                unset($tb);
            }
        }
    }
    if ($GLOBALS['cfgRelation']['commwork'] && $GLOBALS['cfgRelation']['mimework'] && $GLOBALS['cfg']['BrowseMIME'] && !$_SESSION['tmp_user_values']['hide_transformation']) {
        include_once './libraries/transformations.lib.php';
        $GLOBALS['mime_map'] = PMA_getMIME($db, $table);
    }
    // See if we have to highlight any header fields of a WHERE query.
    // Uses SQL-Parser results.
    $highlight_columns = array();
    if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['where_clause_identifiers'])) {
        $wi = 0;
        if (isset($analyzed_sql[0]['where_clause_identifiers']) && is_array($analyzed_sql[0]['where_clause_identifiers'])) {
            foreach ($analyzed_sql[0]['where_clause_identifiers'] as $wci_nr => $wci) {
                $highlight_columns[$wci] = 'true';
            }
        }
    }
    if (PMA_isSelect()) {
        // prepare to get the column order, if available
        $pmatable = new PMA_Table($GLOBALS['table'], $GLOBALS['db']);
        $col_order = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_ORDER);
        $col_visib = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_VISIB);
    } else {
        $col_order = false;
        $col_visib = false;
    }
    for ($j = 0; $j < $fields_cnt; $j++) {
        // assign $i with appropriate column order
        $i = $col_order ? $col_order[$j] : $j;
        //  See if this column should get highlight because it's used in the
        //  where-query.
        if (isset($highlight_columns[$fields_meta[$i]->name]) || isset($highlight_columns[PMA_backquote($fields_meta[$i]->name)])) {
            $condition_field = true;
        } else {
            $condition_field = false;
        }
        // 2.0 Prepare comment-HTML-wrappers for each row, if defined/enabled.
        if (isset($comments_map) && isset($comments_map[$fields_meta[$i]->table]) && isset($comments_map[$fields_meta[$i]->table][$fields_meta[$i]->name])) {
            $comments = '<span class="tblcomment">' . htmlspecialchars($comments_map[$fields_meta[$i]->table][$fields_meta[$i]->name]) . '</span>';
        } else {
            $comments = '';
        }
        // 2.1 Results can be sorted
        if ($is_display['sort_lnk'] == '1') {
            // 2.1.1 Checks if the table name is required; it's the case
            //       for a query with a "JOIN" statement and if the column
            //       isn't aliased, or in queries like
            //       SELECT `1`.`master_field` , `2`.`master_field`
            //       FROM `PMA_relation` AS `1` , `PMA_relation` AS `2`
            if (isset($fields_meta[$i]->table) && strlen($fields_meta[$i]->table)) {
                $sort_tbl = PMA_backquote($fields_meta[$i]->table) . '.';
            } else {
                $sort_tbl = '';
            }
            // 2.1.2 Checks if the current column is used to sort the
            //       results
            // the orgname member does not exist for all MySQL versions
            // but if found, it's the one on which to sort
            $name_to_use_in_sort = $fields_meta[$i]->name;
            $is_orgname = false;
            if (isset($fields_meta[$i]->orgname) && strlen($fields_meta[$i]->orgname)) {
                $name_to_use_in_sort = $fields_meta[$i]->orgname;
                $is_orgname = true;
            }
            // $name_to_use_in_sort might contain a space due to
            // formatting of function expressions like "COUNT(name )"
            // so we remove the space in this situation
            $name_to_use_in_sort = str_replace(' )', ')', $name_to_use_in_sort);
            if (empty($sort_expression)) {
                $is_in_sort = false;
            } else {
                // Field name may be preceded by a space, or any number
                // of characters followed by a dot (tablename.fieldname)
                // so do a direct comparison for the sort expression;
                // this avoids problems with queries like
                // "SELECT id, count(id)..." and clicking to sort
                // on id or on count(id).
                // Another query to test this:
                // SELECT p.*, FROM_UNIXTIME(p.temps) FROM mytable AS p
                // (and try clicking on each column's header twice)
                if (!empty($sort_tbl) && strpos($sort_expression_nodirection, $sort_tbl) === false && strpos($sort_expression_nodirection, '(') === false) {
                    $sort_expression_nodirection = $sort_tbl . $sort_expression_nodirection;
                }
                $is_in_sort = str_replace('`', '', $sort_tbl) . $name_to_use_in_sort == str_replace('`', '', $sort_expression_nodirection) ? true : false;
            }
            // 2.1.3 Check the field name for a bracket.
            //       If it contains one, it's probably a function column
            //       like 'COUNT(`field`)'
            //       It still might be a column name of a view. See bug #3383711
            //       Check is_orgname.
            if (strpos($name_to_use_in_sort, '(') !== false && !$is_orgname) {
                $sort_order = "\n" . 'ORDER BY ' . $name_to_use_in_sort . ' ';
            } else {
                $sort_order = "\n" . 'ORDER BY ' . $sort_tbl . PMA_backquote($name_to_use_in_sort) . ' ';
            }
            unset($name_to_use_in_sort);
            unset($is_orgname);
            // 2.1.4 Do define the sorting URL
            if (!$is_in_sort) {
                // patch #455484 ("Smart" order)
                $GLOBALS['cfg']['Order'] = strtoupper($GLOBALS['cfg']['Order']);
                if ($GLOBALS['cfg']['Order'] === 'SMART') {
                    $sort_order .= preg_match('@time|date@i', $fields_meta[$i]->type) ? 'DESC' : 'ASC';
                } else {
                    $sort_order .= $GLOBALS['cfg']['Order'];
                }
                $order_img = '';
            } elseif ('DESC' == $sort_direction) {
                $sort_order .= ' ASC';
                $order_img = ' ' . PMA_getImage('s_desc.png', __('Descending'), array('class' => "soimg{$i}", 'title' => ''));
                $order_img .= ' ' . PMA_getImage('s_asc.png', __('Ascending'), array('class' => "soimg{$i} hide", 'title' => ''));
            } else {
                $sort_order .= ' DESC';
                $order_img = ' ' . PMA_getImage('s_asc.png', __('Ascending'), array('class' => "soimg{$i}", 'title' => ''));
                $order_img .= ' ' . PMA_getImage('s_desc.png', __('Descending'), array('class' => "soimg{$i} hide", 'title' => ''));
            }
            if (preg_match('@(.*)([[:space:]](LIMIT (.*)|PROCEDURE (.*)|FOR UPDATE|LOCK IN SHARE MODE))@is', $unsorted_sql_query, $regs3)) {
                $sorted_sql_query = $regs3[1] . $sort_order . $regs3[2];
            } else {
                $sorted_sql_query = $unsorted_sql_query . $sort_order;
            }
            $_url_params = array('db' => $db, 'table' => $table, 'sql_query' => $sorted_sql_query, 'session_max_rows' => $session_max_rows);
            $order_url = 'sql.php' . PMA_generate_common_url($_url_params);
            // 2.1.5 Displays the sorting URL
            // enable sort order swapping for image
            $order_link_params = array();
            if (isset($order_img) && $order_img != '') {
                if (strstr($order_img, 'asc')) {
                    $order_link_params['onmouseover'] = "\$('.soimg{$i}').toggle()";
                    $order_link_params['onmouseout'] = "\$('.soimg{$i}').toggle()";
                } elseif (strstr($order_img, 'desc')) {
                    $order_link_params['onmouseover'] = "\$('.soimg{$i}').toggle()";
                    $order_link_params['onmouseout'] = "\$('.soimg{$i}').toggle()";
                }
            }
            if ($GLOBALS['cfg']['HeaderFlipType'] == 'auto') {
                if (PMA_USR_BROWSER_AGENT == 'IE') {
                    $GLOBALS['cfg']['HeaderFlipType'] = 'css';
                } else {
                    $GLOBALS['cfg']['HeaderFlipType'] = 'fake';
                }
            }
            if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'css') {
                $order_link_params['style'] = 'direction: ltr; writing-mode: tb-rl;';
            }
            $order_link_params['title'] = __('Sort');
            $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);
            $order_link = PMA_linkOrButton($order_url, $order_link_content . $order_img, $order_link_params, false, true);
            if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
                echo '<th';
                $th_class = array();
                $th_class[] = 'draggable';
                if ($col_visib && !$col_visib[$j]) {
                    $th_class[] = 'hide';
                }
                if ($condition_field) {
                    $th_class[] = 'condition';
                }
                $th_class[] = 'column_heading';
                if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) {
                    $th_class[] = 'pointer';
                }
                if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) {
                    $th_class[] = 'marker';
                }
                echo ' class="' . implode(' ', $th_class) . '"';
                if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
                    echo ' valign="bottom"';
                }
                echo '>' . $order_link . $comments . '</th>';
            }
            $vertical_display['desc'][] = '    <th ' . 'class="draggable' . ($condition_field ? ' condition' : '') . '">' . "\n" . $order_link . $comments . '    </th>' . "\n";
        } else {
            if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
                echo '<th';
                $th_class = array();
                $th_class[] = 'draggable';
                if ($col_visib && !$col_visib[$j]) {
                    $th_class[] = 'hide';
                }
                if ($condition_field) {
                    $th_class[] = 'condition';
                }
                echo ' class="' . implode(' ', $th_class) . '"';
                if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
                    echo ' valign="bottom"';
                }
                if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'css') {
                    echo ' style="direction: ltr; writing-mode: tb-rl;"';
                }
                echo '>';
                if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'fake') {
                    echo PMA_flipstring(htmlspecialchars($fields_meta[$i]->name), '<br />');
                } else {
                    echo htmlspecialchars($fields_meta[$i]->name);
                }
                echo "\n" . $comments . '</th>';
            }
            $vertical_display['desc'][] = '    <th ' . 'class="draggable' . ($condition_field ? ' condition"' : '') . '">' . "\n" . '        ' . htmlspecialchars($fields_meta[$i]->name) . "\n" . $comments . '    </th>';
        }
        // end else (2.2)
    }
    // end for
    // 3. Displays the needed checkboxes at the right
    //    column of the result table header if possible and required...
    if (($GLOBALS['cfg']['RowActionLinks'] == 'right' || $GLOBALS['cfg']['RowActionLinks'] == 'both') && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn') && $is_display['text_btn'] == '1') {
        $vertical_display['emptyafter'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 4 : 1;
        if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
            echo "\n";
            ?>
        <th <?php 
            echo $colspan;
            ?>
><?php 
            echo $full_or_partial_text_link;
            ?>
</th>
            <?php 
            // end horizontal/horizontalflipped mode
        } else {
            $vertical_display['textbtn'] = '    <th ' . $rowspan . ' valign="middle">' . "\n" . '        ' . "\n" . '    </th>' . "\n";
        }
        // end vertical mode
    } elseif (($GLOBALS['cfg']['RowActionLinks'] == 'left' || $GLOBALS['cfg']['RowActionLinks'] == 'both') && ($is_display['edit_lnk'] == 'nn' && $is_display['del_lnk'] == 'nn') && !$GLOBALS['is_header_sent']) {
        $vertical_display['emptyafter'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 4 : 1;
        if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
            echo "\n";
            ?>
<td<?php 
            echo $colspan;
            ?>
></td>
            <?php 
            // end horizontal/horizontalflipped mode
        } else {
            $vertical_display['textbtn'] = '    <td' . $rowspan . '></td>' . "\n";
        }
        // end vertical mode
    }
    if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') {
        ?>
</tr>
</thead>
        <?php 
    }
    return true;
}
Example #4
0
/**
 * Displays the headers of the results table
 *
 * @param   array    which elements to display
 * @param   array    the list of fields properties
 * @param   integer  the total number of fields returned by the sql query
 * @param   array    the analyzed query
 *
 * @return  boolean  always true
 *
 * @global  string   the current language
 * @global  string   the current charset for MySQL
 * @global  integer  the server to use (refers to the number in the
 *                   configuration file)
 * @global  string   the database name
 * @global  string   the table name
 * @global  string   the sql query
 * @global  string   the url to go back in case of errors
 * @global  integer  the total number of rows returned by the sql query
 * @global  integer  the current position in results
 * @global  integer  the maximum number of rows per page
 * @global  array    informations used with vertical display mode
 * @global  string   the display mode (horizontal/vertical/horizontalflipped)
 * @global  integer  the number of row to display between two table headers
 * @global  boolean  whether to limit the number of displayed characters of
 *                   text type fields or not
 *
 * @access  private
 *
 * @see     PMA_displayTable()
 */
function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $analyzed_sql = '')
{
    global $lang, $convcharset, $server, $db, $table;
    global $goto;
    global $sql_query, $num_rows, $pos, $session_max_rows;
    global $vertical_display, $disp_direction, $repeat_cells, $highlight_columns;
    global $dontlimitchars;
    if ($analyzed_sql == '') {
        $analyzed_sql = array();
    }
    // can be result sorted?
    if ($is_display['sort_lnk'] == '1') {
        // Defines the url used to append/modify a sorting order
        // Nijel: This was originally done inside loop below, but I see
        //        no reason to do this for each column.
        if (preg_match('@(.*)([[:space:]]ORDER[[:space:]]*BY[[:space:]](.*))@si', $sql_query, $regs1)) {
            if (preg_match('@((.*)([[:space:]]ASC|[[:space:]]DESC)([[:space:]]|$))(.*)@si', $regs1[2], $regs2)) {
                $unsorted_sql_query = trim($regs1[1] . ' ' . $regs2[5]);
                $sql_order = trim($regs2[1]);
                preg_match('@(ORDER[[:space:]]*BY[[:space:]]*)(.*)([[:space:]]*ASC|[[:space:]]*DESC)@si', $sql_order, $after_order);
                $sort_expression = trim($after_order[2]);
            } else {
                if (preg_match('@((.*))[[:space:]]+(LIMIT (.*)|PROCEDURE (.*)|FOR UPDATE|LOCK IN SHARE MODE)@si', $regs1[2], $regs3)) {
                    $unsorted_sql_query = trim($regs1[1] . ' ' . $regs3[3]);
                    $sql_order = trim($regs3[1]) . ' ASC';
                    preg_match('@(ORDER[[:space:]]*BY[[:space:]]*)(.*)([[:space:]]*ASC|[[:space:]]*DESC)@si', $sql_order, $after_order);
                    $sort_expression = trim($after_order[2]);
                } else {
                    $unsorted_sql_query = trim($regs1[1]);
                    $sql_order = trim($regs1[2]) . ' ASC';
                    preg_match('@(ORDER[[:space:]]*BY[[:space:]]*)(.*)([[:space:]]*ASC|[[:space:]]*DESC)@si', $sql_order, $after_order);
                    $sort_expression = trim($after_order[2]);
                }
            }
        } else {
            $unsorted_sql_query = $sql_query;
        }
        // sorting by indexes, only if it makes sense
        if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['querytype']) && $analyzed_sql[0]['querytype'] == 'SELECT' && isset($analyzed_sql[0]['table_ref']) && count($analyzed_sql[0]['table_ref']) == 1) {
            // grab indexes data:
            $local_query = 'SHOW KEYS FROM ' . PMA_backquote($table);
            $result = PMA_mysql_query($local_query) or PMA_mysqlDie('', $local_query, '', $err_url_0);
            $idx_cnt = mysql_num_rows($result);
            $prev_index = '';
            for ($i = 0; $i < $idx_cnt; $i++) {
                $row = defined('PMA_IDX_INCLUDED') ? $ret_keys[$i] : PMA_mysql_fetch_array($result);
                if ($row['Key_name'] != $prev_index) {
                    $indexes[] = $row['Key_name'];
                    $prev_index = $row['Key_name'];
                }
                $indexes_info[$row['Key_name']]['Sequences'][] = $row['Seq_in_index'];
                $indexes_info[$row['Key_name']]['Non_unique'] = $row['Non_unique'];
                if (isset($row['Cardinality'])) {
                    $indexes_info[$row['Key_name']]['Cardinality'] = $row['Cardinality'];
                }
                //    I don't know what does following column mean....
                //    $indexes_info[$row['Key_name']]['Packed']          = $row['Packed'];
                $indexes_info[$row['Key_name']]['Comment'] = isset($row['Comment']) ? $row['Comment'] : '';
                $indexes_info[$row['Key_name']]['Index_type'] = isset($row['Index_type']) ? $row['Index_type'] : '';
                $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name'] = $row['Column_name'];
                if (isset($row['Sub_part'])) {
                    $indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part'] = $row['Sub_part'];
                }
            }
            // end while
            // do we have any index?
            if (isset($indexes_data)) {
                if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
                    $span = $fields_cnt;
                } else {
                    $span = $num_rows + floor($num_rows / $repeat_cells) + 1;
                }
                if ($is_display['edit_lnk'] != 'nn') {
                    $span++;
                }
                if ($is_display['del_lnk'] != 'nn') {
                    $span++;
                }
                ?>
<tr>
<td colspan="<?php 
                echo $span;
                ?>
" align="center">
                <?php 
                echo '<form action="sql.php" method="POST">' . "\n";
                echo PMA_generate_common_hidden_inputs($db, $table, 5);
                echo '<input type="hidden" name="pos" value="' . $pos . '" />' . "\n";
                echo '<input type="hidden" name="session_max_rows" value="' . $session_max_rows . '" />' . "\n";
                echo '<input type="hidden" name="disp_direction" value="' . $disp_direction . '" />' . "\n";
                echo '<input type="hidden" name="repeat_cells" value="' . $repeat_cells . '" />' . "\n";
                echo '<input type="hidden" name="dontlimitchars" value="' . $dontlimitchars . '" />' . "\n";
                echo $GLOBALS['strSortByKey'] . ': <select name="sql_query">&nbsp;';
                $used_index = false;
                $local_order = isset($sql_order) ? str_replace('  ', ' ', $sql_order) : '';
                foreach ($indexes_data as $key => $val) {
                    $asc_sort = 'ORDER BY ';
                    $desc_sort = 'ORDER BY ';
                    foreach ($val as $key2 => $val2) {
                        $asc_sort .= PMA_backquote($val2['Column_name']) . ' ASC , ';
                        $desc_sort .= PMA_backquote($val2['Column_name']) . ' DESC , ';
                    }
                    $asc_sort = substr($asc_sort, 0, -3);
                    $desc_sort = substr($desc_sort, 0, -3);
                    $used_index = $used_index || $local_order == $asc_sort || $local_order == $desc_sort;
                    echo '<option value="' . htmlspecialchars($unsorted_sql_query . ' ' . $asc_sort) . '"' . ($local_order == $asc_sort ? ' selected="selected"' : '') . '>' . htmlspecialchars($key) . ' (' . $GLOBALS['strAscending'] . ')</option>';
                    echo "\n";
                    echo '<option value="' . htmlspecialchars($unsorted_sql_query . ' ' . $desc_sort) . '"' . ($local_order == $desc_sort ? ' selected="selected"' : '') . '>' . htmlspecialchars($key) . ' (' . $GLOBALS['strDescending'] . ')</option>';
                    echo "\n";
                }
                echo '<option value="' . htmlspecialchars($unsorted_sql_query) . '"' . ($used_index ? '' : ' selected="selected"') . '>' . $GLOBALS['strNone'] . '</option>';
                echo "\n";
                echo '</select>&nbsp;';
                echo "\n";
                echo '<input type="submit" value="' . $GLOBALS['strGo'] . '" />';
                echo "\n";
                echo '</form>';
                echo "\n";
                ?>
</td>
</tr>
            <?php 
            }
        }
    }
    if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
        ?>
<!-- Results table headers -->
<tr>
        <?php 
        echo "\n";
    }
    $vertical_display['emptypre'] = 0;
    $vertical_display['emptyafter'] = 0;
    $vertical_display['textbtn'] = '';
    // Start of form for multi-rows delete
    if ($is_display['del_lnk'] == 'dr' || $is_display['del_lnk'] == 'kp') {
        echo '<form method="post" action="tbl_row_delete.php" name="rowsDeleteForm">' . "\n";
        echo PMA_generate_common_hidden_inputs($db, $table, 1);
        echo '<input type="hidden" name="disp_direction" value="' . $disp_direction . '" />' . "\n";
        echo '<input type="hidden" name="repeat_cells"   value="' . $repeat_cells . '" />' . "\n";
        echo '<input type="hidden" name="goto"           value="' . $goto . '" />' . "\n";
        echo '<input type="hidden" name="dontlimitchars" value="' . $dontlimitchars . '" />' . "\n";
    }
    // 1. Displays the full/partial text button (part 1)...
    if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
        $colspan = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? ' colspan="3"' : '';
    } else {
        $rowspan = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? ' rowspan="3"' : '';
    }
    $text_url = 'sql.php?' . PMA_generate_common_url($db, $table) . '&amp;sql_query=' . urlencode($sql_query) . '&amp;pos=' . $pos . '&amp;session_max_rows=' . $session_max_rows . '&amp;pos=' . $pos . '&amp;disp_direction=' . $disp_direction . '&amp;repeat_cells=' . $repeat_cells . '&amp;goto=' . $goto . '&amp;dontlimitchars=' . ($dontlimitchars ? 0 : 1);
    //     ... before the result table
    if ($is_display['edit_lnk'] == 'nn' && $is_display['del_lnk'] == 'nn' && $is_display['text_btn'] == '1') {
        $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 0;
        if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
            ?>
<td colspan="<?php 
            echo $fields_cnt;
            ?>
" align="center">
    <a href="<?php 
            echo $text_url;
            ?>
">
        <img src="./images/<?php 
            echo $dontlimitchars ? 'partialtext' : 'fulltext';
            ?>
.png" border="0" width="50" height="20" alt="<?php 
            echo $dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText'];
            ?>
" title="<?php 
            echo $dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText'];
            ?>
" /></a>
</td>
</tr>

<tr>
            <?php 
        } else {
            echo "\n";
            ?>
<tr>
<td colspan="<?php 
            echo $num_rows + floor($num_rows / $repeat_cells) + 1;
            ?>
" align="center">
    <a href="<?php 
            echo $text_url;
            ?>
">
        <img src="./images/<?php 
            echo $dontlimitchars ? 'partialtext' : 'fulltext';
            ?>
.png" border="0" width="50" height="20" alt="<?php 
            echo $dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText'];
            ?>
" title="<?php 
            echo $dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText'];
            ?>
" /></a>
</td>
</tr>
            <?php 
        }
        // end vertical mode
    } else {
        if ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && $is_display['text_btn'] == '1') {
            $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 0;
            if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
                echo "\n";
                ?>
<td<?php 
                echo $colspan;
                ?>
 align="center">
    <a href="<?php 
                echo $text_url;
                ?>
">
        <img src="./images/<?php 
                echo $dontlimitchars ? 'partialtext' : 'fulltext';
                ?>
.png" border="0" width="50" height="20" alt="<?php 
                echo $dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText'];
                ?>
" title="<?php 
                echo $dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText'];
                ?>
" /></a>
</td>
            <?php 
            } else {
                $vertical_display['textbtn'] = '    <td' . $rowspan . ' align="center" valign="middle">' . "\n" . '        <a href="' . $text_url . '">' . "\n" . '            <img src="./images/' . ($dontlimitchars ? 'partialtext' : 'fulltext') . '.png" border="0" width="50" height="20" alt="' . ($dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText']) . '" title="' . ($dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText']) . '" /></a>' . "\n" . '    </td>' . "\n";
            }
            // end vertical mode
        } else {
            if ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn')) {
                $vertical_display['emptypre'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 0;
                if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
                    echo "\n";
                    ?>
<td<?php 
                    echo $colspan;
                    ?>
></td>
            <?php 
                    echo "\n";
                } else {
                    $vertical_display['textbtn'] = '    <td' . $rowspan . '></td>' . "\n";
                }
                // end vertical mode
            }
        }
    }
    // 2. Displays the fields' name
    // 2.0 If sorting links should be used, checks if the query is a "JOIN"
    //     statement (see 2.1.3)
    // 2.0.1 Prepare Display column comments if enabled ($cfg['ShowBrowseComments']).
    //       Do not show comments, if using horizontalflipped mode, because of space usage
    if ($GLOBALS['cfg']['ShowBrowseComments'] && $GLOBALS['cfgRelation']['commwork'] && $disp_direction != 'horizontalflipped') {
        $comments_map = PMA_getComments($db, $table);
    } else {
        $comments_map = array();
    }
    if ($GLOBALS['cfgRelation']['commwork'] && $GLOBALS['cfgRelation']['mimework'] && $GLOBALS['cfg']['BrowseMIME']) {
        require_once './libraries/transformations.lib.php';
        $GLOBALS['mime_map'] = PMA_getMIME($db, $table);
    }
    if ($is_display['sort_lnk'] == '1') {
        $is_join = preg_match('@(.*)[[:space:]]+FROM[[:space:]]+.*[[:space:]]+JOIN@i', $sql_query, $select_stt);
    } else {
        $is_join = FALSE;
    }
    // garvin: See if we have to highlight any header fields of a WHERE query.
    //  Uses SQL-Parser results.
    $highlight_columns = array();
    if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['where_clause_identifiers'])) {
        $wi = 0;
        if (isset($analyzed_sql[0]['where_clause_identifiers']) && is_array($analyzed_sql[0]['where_clause_identifiers'])) {
            foreach ($analyzed_sql[0]['where_clause_identifiers'] as $wci_nr => $wci) {
                $highlight_columns[$wci] = 'true';
            }
        }
    }
    for ($i = 0; $i < $fields_cnt; $i++) {
        // garvin: See if this column should get highlight because it's used in the
        //  where-query.
        if (isset($highlight_columns[$fields_meta[$i]->name]) || isset($highlight_columns[PMA_backquote($fields_meta[$i]->name)])) {
            $column_style = 'style="border: 1px solid ' . $GLOBALS['cfg']['BrowseMarkerColor'] . '"';
        } else {
            $column_style = '';
        }
        // 2.0 Prepare comment-HTML-wrappers for each row, if defined/enabled.
        if (isset($comments_map[$fields_meta[$i]->name])) {
            $comments_table_wrap_pre = '<table border="0" cellpadding="0" cellspacing="0" width="100%"><tr><th>';
            $comments_table_wrap_post = '</th></tr><tr><th style="font-size: 8pt; font-weight: normal">' . htmlspecialchars($comments_map[$fields_meta[$i]->name]) . '</td></tr></table>';
        } else {
            $comments_table_wrap_pre = '';
            $comments_table_wrap_post = '';
        }
        // 2.1 Results can be sorted
        if ($is_display['sort_lnk'] == '1') {
            // 2.1.1 Checks if the table name is required; it's the case
            //       for a query with a "JOIN" statement and if the column
            //       isn't aliased, or in queries like
            //       SELECT `1`.`master_field` , `2`.`master_field`
            //       FROM `PMA_relation` AS `1` , `PMA_relation` AS `2`
            if ($is_join && !preg_match('~([^[:space:],]|`[^`]`)[[:space:]]+(as[[:space:]]+)?' . $fields_meta[$i]->name . '~i', $select_stt[1], $parts) || isset($analyzed_sql[0]['select_expr'][$i]['expr']) && isset($analyzed_sql[0]['select_expr'][$i]['column']) && $analyzed_sql[0]['select_expr'][$i]['expr'] != $analyzed_sql[0]['select_expr'][$i]['column'] && !empty($fields_meta[$i]->table)) {
                $sort_tbl = PMA_backquote($fields_meta[$i]->table) . '.';
            } else {
                $sort_tbl = '';
            }
            // 2.1.2 Checks if the current column is used to sort the
            //       results
            if (empty($sql_order)) {
                $is_in_sort = FALSE;
            } else {
                // field name may be preceded by a space, or any number
                // of characters followed by a dot (tablename.fieldname)
                // so do a direct comparison
                // for the sort expression (avoids problems with queries
                // like "SELECT id, count(id)..." and clicking to sort
                // on id or on count(id) )
                $is_in_sort = $sort_tbl . PMA_backquote($fields_meta[$i]->name) == $sort_expression ? TRUE : FALSE;
            }
            // 2.1.3 Check the field name for backquotes.
            //       If it contains some, it's probably a function column
            //       like 'COUNT(`field`)'
            if (strpos(' ' . $fields_meta[$i]->name, '`') > 0) {
                $sort_order = ' ORDER BY \'' . $fields_meta[$i]->name . '\' ';
            } else {
                $sort_order = ' ORDER BY ' . $sort_tbl . PMA_backquote($fields_meta[$i]->name) . ' ';
            }
            // 2.1.4 Do define the sorting url
            if (!$is_in_sort) {
                // loic1: patch #455484 ("Smart" order)
                $cfg['Order'] = strtoupper($GLOBALS['cfg']['Order']);
                if ($cfg['Order'] == 'SMART') {
                    $cfg['Order'] = preg_match('@time|date@i', $fields_meta[$i]->type) ? 'DESC' : 'ASC';
                }
                $sort_order .= $cfg['Order'];
                $order_img = '';
            } else {
                if (preg_match('@[[:space:]]ASC$@i', $sql_order)) {
                    $sort_order .= ' DESC';
                    $order_img = '&nbsp;<img src="./images/asc_order.png" border="0" width="7" height="7" alt="' . $GLOBALS['strAscending'] . '" title="' . $GLOBALS['strAscending'] . '" />';
                } else {
                    if (preg_match('@[[:space:]]DESC$@i', $sql_order)) {
                        $sort_order .= ' ASC';
                        $order_img = '&nbsp;<img src="./images/desc_order.png" border="0" width="7" height="7" alt="' . $GLOBALS['strDescending'] . '" title="' . $GLOBALS['strDescending'] . '" />';
                    }
                }
            }
            if (preg_match('@(.*)([[:space:]](LIMIT (.*)|PROCEDURE (.*)|FOR UPDATE|LOCK IN SHARE MODE))@i', $unsorted_sql_query, $regs3)) {
                $sorted_sql_query = $regs3[1] . $sort_order . $regs3[2];
            } else {
                $sorted_sql_query = $unsorted_sql_query . $sort_order;
            }
            $url_query = PMA_generate_common_url($db, $table) . '&amp;pos=' . $pos . '&amp;session_max_rows=' . $session_max_rows . '&amp;disp_direction=' . $disp_direction . '&amp;repeat_cells=' . $repeat_cells . '&amp;dontlimitchars=' . $dontlimitchars . '&amp;sql_query=' . urlencode($sorted_sql_query);
            // 2.1.5 Displays the sorting url
            if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
                echo "\n";
                ?>
<th <?php 
                echo $column_style;
                ?>
 <?php 
                if ($disp_direction == 'horizontalflipped') {
                    echo 'valign="bottom"';
                }
                ?>
>
    <?php 
                echo $comments_table_wrap_pre;
                ?>
    <a href="sql.php?<?php 
                echo $url_query;
                ?>
" <?php 
                echo (($disp_direction == 'horizontalflipped' and $GLOBALS['cfg']['HeaderFlipType'] == 'css') ? 'style="direction: ltr; writing-mode: tb-rl;"' : '') . ' title="' . $GLOBALS['strSort'] . '"';
                ?>
>
        <?php 
                echo $disp_direction == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'fake' ? PMA_flipstring(htmlspecialchars($fields_meta[$i]->name), "<br />\n") : htmlspecialchars($fields_meta[$i]->name);
                ?>
 </a><?php 
                echo $order_img . "\n";
                ?>
    <?php 
                echo $comments_table_wrap_post;
                ?>
</th>
                <?php 
            }
            $vertical_display['desc'][] = '    <th ' . $column_style . '>' . "\n" . $comments_table_wrap_pre . '        <a href="sql.php?' . $url_query . '">' . "\n" . '            ' . htmlspecialchars($fields_meta[$i]->name) . '</a>' . $order_img . "\n" . $comments_table_wrap_post . '    </th>' . "\n";
        } else {
            if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
                echo "\n";
                ?>
<th <?php 
                echo $column_style;
                ?>
 <?php 
                if ($disp_direction == 'horizontalflipped') {
                    echo 'valign="bottom"';
                }
                ?>
  <?php 
                echo $disp_direction == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'css' ? 'style="direction: ltr; writing-mode: tb-rl;"' : '';
                ?>
>
    <?php 
                echo $comments_table_wrap_pre;
                ?>
    <?php 
                echo ($disp_direction == 'horizontalflipped' && $GLOBALS['cfg']['HeaderFlipType'] == 'fake' ? PMA_flipstring(htmlspecialchars($fields_meta[$i]->name), "<br />\n") : htmlspecialchars($fields_meta[$i]->name)) . "\n";
                ?>
    <?php 
                echo $comments_table_wrap_post;
                ?>
</th>
                <?php 
            }
            $vertical_display['desc'][] = '    <th ' . $column_style . '>' . "\n" . $comments_table_wrap_pre . '        ' . htmlspecialchars($fields_meta[$i]->name) . "\n" . $comments_table_wrap_post . '    </th>';
        }
        // end else (2.2)
    }
    // end for
    // 3. Displays the full/partial text button (part 2) at the right
    //    column of the result table header if possible and required...
    if ($GLOBALS['cfg']['ModifyDeleteAtRight'] && ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn') && $is_display['text_btn'] == '1') {
        $vertical_display['emptyafter'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 1;
        if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
            echo "\n";
            ?>
<td<?php 
            echo $colspan;
            ?>
 align="center">
    <a href="<?php 
            echo $text_url;
            ?>
">
        <img src="./images/<?php 
            echo $dontlimitchars ? 'partialtext' : 'fulltext';
            ?>
.png" border="0" width="50" height="20" alt="<?php 
            echo $dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText'];
            ?>
" title="<?php 
            echo $dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText'];
            ?>
" /></a>
</td>
            <?php 
        } else {
            $vertical_display['textbtn'] = '    <td' . $rowspan . ' align="center" valign="middle">' . "\n" . '        <a href="' . $text_url . '">' . "\n" . '            <img src="./images/' . ($dontlimitchars ? 'partialtext' : 'fulltext') . '.png" border="0" width="50" height="20" alt="' . ($dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText']) . '" title="' . ($dontlimitchars ? $GLOBALS['strPartialText'] : $GLOBALS['strFullText']) . '" /></a>' . "\n" . '    </td>' . "\n";
        }
        // end vertical mode
    } else {
        if ($GLOBALS['cfg']['ModifyDeleteAtRight'] && ($is_display['edit_lnk'] == 'nn' && $is_display['del_lnk'] == 'nn') && !$GLOBALS['is_header_sent']) {
            $vertical_display['emptyafter'] = $is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn' ? 3 : 1;
            if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
                echo "\n";
                ?>
<td<?php 
                echo $colspan;
                ?>
></td>
            <?php 
            } else {
                $vertical_display['textbtn'] = '    <td' . $rowspan . '></td>' . "\n";
            }
            // end vertical mode
        }
    }
    if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') {
        echo "\n";
        ?>
</tr>
        <?php 
    }
    echo "\n";
    return TRUE;
}
 /**
  * test of changing string from horizontal to vertical orientation
  * @dataProvider flipStringDataProvider
  */
 public function testFlipString($a, $e)
 {
     $this->assertEquals($e, PMA_flipstring($a));
 }