/** * Displays the body of the results table * * @uses $_SESSION['tmp_user_values']['disp_direction'] * @uses $_SESSION['tmp_user_values']['repeat_cells'] * @uses $_SESSION['tmp_user_values']['max_rows'] * @uses $_SESSION['tmp_user_values']['display_text'] * @uses $_SESSION['tmp_user_values']['display_binary'] * @uses $_SESSION['tmp_user_values']['display_binary_as_hex'] * @uses $_SESSION['tmp_user_values']['display_blob'] * @param integer the link id associated to the query which results have * to be displayed * @param array which elements to display * @param array the list of relations * @param array the analyzed query * * @return boolean always true * * @global string $db the database name * @global string $table the table name * @global string $goto the URL to go back in case of errors * @global string $sql_query the SQL query * @global array $fields_meta the list of fields properties * @global integer $fields_cnt the total number of fields returned by * the SQL query * @global array $vertical_display informations used with vertical display * mode * @global array $highlight_columns column names to highlight * @global array $row current row data * * @access private * * @see PMA_displayTable() */ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) { global $db, $table, $goto; global $sql_query, $fields_meta, $fields_cnt; global $vertical_display, $highlight_columns; global $row; // mostly because of browser transformations, to make the row-data accessible in a plugin $url_sql_query = $sql_query; // query without conditions to shorten URLs when needed, 200 is just // guess, it should depend on remaining URL length if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['querytype']) && $analyzed_sql[0]['querytype'] == 'SELECT' && strlen($sql_query) > 200) { $url_sql_query = 'SELECT '; if (isset($analyzed_sql[0]['queryflags']['distinct'])) { $url_sql_query .= ' DISTINCT '; } $url_sql_query .= $analyzed_sql[0]['select_expr_clause']; if (!empty($analyzed_sql[0]['from_clause'])) { $url_sql_query .= ' FROM ' . $analyzed_sql[0]['from_clause']; } } if (!is_array($map)) { $map = array(); } $row_no = 0; $vertical_display['edit'] = array(); $vertical_display['delete'] = array(); $vertical_display['data'] = array(); $vertical_display['row_delete'] = array(); // Correction University of Virginia 19991216 in the while below // Previous code assumed that all tables have keys, specifically that // the phpMyAdmin GUI should support row delete/edit only for such // tables. // Although always using keys is arguably the prescribed way of // defining a relational table, it is not required. This will in // particular be violated by the novice. // We want to encourage phpMyAdmin usage by such novices. So the code // below has been changed to conditionally work as before when the // table being displayed has one or more keys; but to display // delete/edit options correctly for tables without keys. $odd_row = true; while ($row = PMA_DBI_fetch_row($dt_result)) { // lem9: "vertical display" mode stuff if ($row_no != 0 && $_SESSION['tmp_user_values']['repeat_cells'] != 0 && !($row_no % $_SESSION['tmp_user_values']['repeat_cells']) && ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped')) { echo '<tr>' . "\n"; if ($vertical_display['emptypre'] > 0) { echo ' <th colspan="' . $vertical_display['emptypre'] . '">' . "\n" . ' </th>' . "\n"; } foreach ($vertical_display['desc'] as $val) { echo $val; } if ($vertical_display['emptyafter'] > 0) { echo ' <th colspan="' . $vertical_display['emptyafter'] . '">' . "\n" . ' </th>' . "\n"; } echo '</tr>' . "\n"; } // end if $class = $odd_row ? 'odd' : 'even'; $odd_row = !$odd_row; if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { // loic1: pointer code part echo ' <tr class="' . $class . '">' . "\n"; $class = ''; } // 1. Prepares the row // 1.1 Results from a "SELECT" statement -> builds the // WHERE clause to use in links (a unique key if possible) /** * @todo $where_clause could be empty, for example a table * with only one field and it's a BLOB; in this case, * avoid to display the delete and edit links */ list($where_clause, $clause_is_unique) = PMA_getUniqueCondition($dt_result, $fields_cnt, $fields_meta, $row); $where_clause_html = urlencode($where_clause); // 1.2 Defines the URLs for the modify/delete link(s) if ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn') { // We need to copy the value or else the == 'both' check will always return true if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') { $iconic_spacer = '<div class="nowrap">'; } else { $iconic_spacer = ''; } // 1.2.1 Modify link(s) if ($is_display['edit_lnk'] == 'ur') { // update row case $_url_params = array('db' => $db, 'table' => $table, 'where_clause' => $where_clause, 'clause_is_unique' => $clause_is_unique, 'sql_query' => $url_sql_query, 'goto' => 'sql.php'); $edit_url = 'tbl_change.php' . PMA_generate_common_url($_url_params); $edit_str = PMA_getIcon('b_edit.png', $GLOBALS['strEdit'], true); } // end if (1.2.1) if (isset($GLOBALS['cfg']['Bookmark']['table']) && isset($GLOBALS['cfg']['Bookmark']['db']) && $table == $GLOBALS['cfg']['Bookmark']['table'] && $db == $GLOBALS['cfg']['Bookmark']['db'] && isset($row[1]) && isset($row[0])) { $_url_params = array('db' => $row[1], 'id_bookmark' => $row[0], 'action_bookmark' => '0', 'action_bookmark_all' => '1', 'SQL' => $GLOBALS['strExecuteBookmarked']); $bookmark_go = '<a href="import.php' . PMA_generate_common_url($_url_params) . ' " title="' . $GLOBALS['strExecuteBookmarked'] . '">'; $bookmark_go .= PMA_getIcon('b_bookmark.png', $GLOBALS['strExecuteBookmarked'], true); $bookmark_go .= '</a>'; } else { $bookmark_go = ''; } // 1.2.2 Delete/Kill link(s) if ($is_display['del_lnk'] == 'dr') { // delete row case $_url_params = array('db' => $db, 'table' => $table, 'sql_query' => $url_sql_query, 'zero_rows' => $GLOBALS['strDeleted'], 'goto' => empty($goto) ? 'tbl_sql.php' : $goto); $lnk_goto = 'sql.php' . PMA_generate_common_url($_url_params, 'text'); $del_query = 'DELETE FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table) . ' WHERE ' . $where_clause . ($clause_is_unique ? '' : ' LIMIT 1'); $_url_params = array('db' => $db, 'table' => $table, 'sql_query' => $del_query, 'zero_rows' => $GLOBALS['strDeleted'], 'goto' => $lnk_goto); $del_url = 'sql.php' . PMA_generate_common_url($_url_params); $js_conf = 'DELETE FROM ' . PMA_jsFormat($db) . '.' . PMA_jsFormat($table) . ' WHERE ' . PMA_jsFormat($where_clause, false) . ($clause_is_unique ? '' : ' LIMIT 1'); $del_str = PMA_getIcon('b_drop.png', $GLOBALS['strDelete'], true); } elseif ($is_display['del_lnk'] == 'kp') { // kill process case $_url_params = array('db' => $db, 'table' => $table, 'sql_query' => $url_sql_query, 'goto' => 'main.php'); $lnk_goto = 'sql.php' . PMA_generate_common_url($_url_params, 'text'); $_url_params = array('db' => 'mysql', 'sql_query' => 'KILL ' . $row[0], 'goto' => $lnk_goto); $del_url = 'sql.php' . PMA_generate_common_url($_url_params); $del_query = 'KILL ' . $row[0]; $js_conf = 'KILL ' . $row[0]; $del_str = PMA_getIcon('b_drop.png', $GLOBALS['strKill'], true); } // end if (1.2.2) // 1.3 Displays the links at left if required if ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped')) { $doWriteModifyAt = 'left'; require './libraries/display_tbl_links.lib.php'; } // end if (1.3) } // end if (1) // 2. Displays the rows' values for ($i = 0; $i < $fields_cnt; ++$i) { $meta = $fields_meta[$i]; $pointer = $i; // garvin: See if this column should get highlight because it's used in the // where-query. if (isset($highlight_columns) && (isset($highlight_columns[$meta->name]) || isset($highlight_columns[PMA_backquote($meta->name)]))) { $condition_field = true; } else { $condition_field = false; } $mouse_events = ''; if ($_SESSION['tmp_user_values']['disp_direction'] == 'vertical' && (!isset($GLOBALS['printview']) || $GLOBALS['printview'] != '1')) { if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) { $mouse_events .= ' onmouseover="setVerticalPointer(this, ' . $row_no . ', \'over\', \'odd\', \'even\', \'hover\', \'marked\');"' . ' onmouseout="setVerticalPointer(this, ' . $row_no . ', \'out\', \'odd\', \'even\', \'hover\', \'marked\');" '; } if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) { $mouse_events .= ' onmousedown="setVerticalPointer(this, ' . $row_no . ', \'click\', \'odd\', \'even\', \'hover\', \'marked\'); setCheckboxColumn(\'id_rows_to_delete' . $row_no . '\');" '; } else { $mouse_events .= ' onmousedown="setCheckboxColumn(\'id_rows_to_delete' . $row_no . '\');" '; } } // end if // garvin: Wrap MIME-transformations. [MIME] $default_function = 'default_function'; // default_function $transform_function = $default_function; $transform_options = array(); if ($GLOBALS['cfgRelation']['mimework'] && $GLOBALS['cfg']['BrowseMIME']) { if (isset($GLOBALS['mime_map'][$meta->name]['mimetype']) && isset($GLOBALS['mime_map'][$meta->name]['transformation']) && !empty($GLOBALS['mime_map'][$meta->name]['transformation'])) { $include_file = $GLOBALS['mime_map'][$meta->name]['transformation']; if (file_exists('./libraries/transformations/' . $include_file)) { $transformfunction_name = str_replace('.inc.php', '', $GLOBALS['mime_map'][$meta->name]['transformation']); require_once './libraries/transformations/' . $include_file; if (function_exists('PMA_transformation_' . $transformfunction_name)) { $transform_function = 'PMA_transformation_' . $transformfunction_name; $transform_options = PMA_transformation_getOptions(isset($GLOBALS['mime_map'][$meta->name]['transformation_options']) ? $GLOBALS['mime_map'][$meta->name]['transformation_options'] : ''); $meta->mimetype = str_replace('_', '/', $GLOBALS['mime_map'][$meta->name]['mimetype']); } } // end if file_exists } // end if transformation is set } // end if mime/transformation works. $_url_params = array('db' => $db, 'table' => $table, 'where_clause' => $where_clause, 'transform_key' => $meta->name); if (!empty($sql_query)) { $_url_params['sql_query'] = $url_sql_query; } $transform_options['wrapper_link'] = PMA_generate_common_url($_url_params); // n u m e r i c if ($meta->numeric == 1) { // lem9: if two fields have the same name (this is possible // with self-join queries, for example), using $meta->name // will show both fields NULL even if only one is NULL, // so use the $pointer if (!isset($row[$i]) || is_null($row[$i])) { $vertical_display['data'][$row_no][$i] = ' <td align="right"' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"><i>NULL</i></td>' . "\n"; } elseif ($row[$i] != '') { $nowrap = ' nowrap'; $where_comparison = ' = ' . $row[$i]; $vertical_display['data'][$row_no][$i] = '<td align="right"' . PMA_prepare_row_data($mouse_events, $class, $condition_field, $analyzed_sql, $meta, $map, $row[$i], $transform_function, $default_function, $nowrap, $where_comparison, $transform_options); } else { $vertical_display['data'][$row_no][$i] = ' <td align="right"' . $mouse_events . ' class="' . $class . ' nowrap' . ($condition_field ? ' condition' : '') . '"> </td>' . "\n"; } // b l o b } elseif (stristr($meta->type, 'BLOB')) { // loic1 : PMA_mysql_fetch_fields returns BLOB in place of // TEXT fields type so we have to ensure it's really a BLOB $field_flags = PMA_DBI_field_flags($dt_result, $i); if (stristr($field_flags, 'BINARY')) { // rajk - for blobstreaming $bs_reference_exists = $allBSTablesExist = FALSE; // load PMA configuration $PMA_Config = $_SESSION['PMA_Config']; // if PMA configuration exists if ($PMA_Config) { // load BS variables $pluginsExist = $PMA_Config->get('BLOBSTREAMING_PLUGINS_EXIST'); // if BS plugins exist if ($pluginsExist) { // load BS databases $bs_tables = $PMA_Config->get('BLOBSTREAMABLE_DATABASES'); // if BS db array and specified db string not empty and valid if (!empty($bs_tables) && strlen($db) > 0) { $bs_tables = $bs_tables[$db]; if (isset($bs_tables)) { $allBSTablesExist = TRUE; // check if BS tables exist for given database foreach ($bs_tables as $table_key => $bs_tbl) { if (!$bs_tables[$table_key]['Exists']) { $allBSTablesExist = FALSE; break; } } } } } } // if necessary BS tables exist if ($allBSTablesExist) { $bs_reference_exists = PMA_BS_ReferenceExists($row[$i], $db); } // if valid BS reference exists if ($bs_reference_exists) { $blobtext = PMA_BS_CreateReferenceLink($row[$i], $db); } else { $blobtext = PMA_handle_non_printable_contents('BLOB', isset($row[$i]) ? $row[$i] : '', $transform_function, $transform_options, $default_function, $meta); } $vertical_display['data'][$row_no][$i] = ' <td align="left"' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '">' . $blobtext . '</td>'; unset($blobtext); // not binary: } else { if (!isset($row[$i]) || is_null($row[$i])) { $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"><i>NULL</i></td>' . "\n"; } elseif ($row[$i] != '') { // garvin: if a transform function for blob is set, none of these replacements will be made if (PMA_strlen($row[$i]) > $GLOBALS['cfg']['LimitChars'] && $_SESSION['tmp_user_values']['display_text'] == 'P') { $row[$i] = PMA_substr($row[$i], 0, $GLOBALS['cfg']['LimitChars']) . '...'; } // loic1: displays all space characters, 4 space // characters for tabulations and <cr>/<lf> $row[$i] = $default_function != $transform_function ? $transform_function($row[$i], $transform_options, $meta) : $default_function($row[$i], array(), $meta); $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '">' . $row[$i] . '</td>' . "\n"; } else { $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"> </td>' . "\n"; } } // n o t n u m e r i c a n d n o t B L O B } else { if (!isset($row[$i]) || is_null($row[$i])) { $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"><i>NULL</i></td>' . "\n"; } elseif ($row[$i] != '') { // loic1: support blanks in the key $relation_id = $row[$i]; // nijel: Cut all fields to $GLOBALS['cfg']['LimitChars'] // lem9: (unless it's a link-type transformation) if (PMA_strlen($row[$i]) > $GLOBALS['cfg']['LimitChars'] && $_SESSION['tmp_user_values']['display_text'] == 'P' && !strpos($transform_function, 'link') === true) { $row[$i] = PMA_substr($row[$i], 0, $GLOBALS['cfg']['LimitChars']) . '...'; } // loic1: displays special characters from binaries $field_flags = PMA_DBI_field_flags($dt_result, $i); if (isset($meta->_type) && $meta->_type === MYSQLI_TYPE_BIT) { $row[$i] = PMA_printable_bit_value($row[$i], $meta->length); } elseif (stristr($field_flags, 'BINARY') && $meta->type == 'string') { if ($_SESSION['tmp_user_values']['display_binary'] || isset($GLOBALS['is_analyse']) && $GLOBALS['is_analyse']) { // user asked to see the real contents of BINARY // fields, or we detected a PROCEDURE ANALYSE in // the query (results are reported as being // binary strings) if ($_SESSION['tmp_user_values']['display_binary_as_hex']) { $row[$i] = bin2hex($row[$i]); } else { $row[$i] = htmlspecialchars(PMA_replace_binary_contents($row[$i])); } } else { // we show the BINARY message and field's size // (or maybe use a transformation) $row[$i] = PMA_handle_non_printable_contents('BINARY', $row[$i], $transform_function, $transform_options, $default_function, $meta); } } // garvin: transform functions may enable no-wrapping: $function_nowrap = $transform_function . '_nowrap'; $bool_nowrap = $default_function != $transform_function && function_exists($function_nowrap) ? $function_nowrap($transform_options) : false; // loic1: do not wrap if date field type $nowrap = preg_match('@DATE|TIME@i', $meta->type) || $bool_nowrap ? ' nowrap' : ''; $where_comparison = ' = \'' . PMA_sqlAddslashes($row[$i]) . '\''; $vertical_display['data'][$row_no][$i] = '<td ' . PMA_prepare_row_data($mouse_events, $class, $condition_field, $analyzed_sql, $meta, $map, $row[$i], $transform_function, $default_function, $nowrap, $where_comparison, $transform_options); } else { $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"> </td>' . "\n"; } } // lem9: output stored cell if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { echo $vertical_display['data'][$row_no][$i]; } if (isset($vertical_display['rowdata'][$i][$row_no])) { $vertical_display['rowdata'][$i][$row_no] .= $vertical_display['data'][$row_no][$i]; } else { $vertical_display['rowdata'][$i][$row_no] = $vertical_display['data'][$row_no][$i]; } } // end for (2) // 3. Displays the modify/delete links on the right if required if ($GLOBALS['cfg']['ModifyDeleteAtRight'] && ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped')) { $doWriteModifyAt = 'right'; require './libraries/display_tbl_links.lib.php'; } // end if (3) if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { ?> </tr> <?php } // end if // 4. Gather links of del_urls and edit_urls in an array for later // output if (!isset($vertical_display['edit'][$row_no])) { $vertical_display['edit'][$row_no] = ''; $vertical_display['delete'][$row_no] = ''; $vertical_display['row_delete'][$row_no] = ''; } $column_style_vertical = ''; if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) { $column_style_vertical .= ' onmouseover="setVerticalPointer(this, ' . $row_no . ', \'over\', \'odd\', \'even\', \'hover\', \'marked\');"' . ' onmouseout="setVerticalPointer(this, ' . $row_no . ', \'out\', \'odd\', \'even\', \'hover\', \'marked\');"'; } $column_marker_vertical = ''; if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) { $column_marker_vertical .= 'setVerticalPointer(this, ' . $row_no . ', \'click\', \'odd\', \'even\', \'hover\', \'marked\');'; } if (!empty($del_url) && $is_display['del_lnk'] != 'kp') { $vertical_display['row_delete'][$row_no] .= ' <td align="center" class="' . $class . '" ' . $column_style_vertical . '>' . "\n" . ' <input type="checkbox" id="id_rows_to_delete' . $row_no . '[%_PMA_CHECKBOX_DIR_%]" name="rows_to_delete[' . $where_clause_html . ']"' . ' onclick="' . $column_marker_vertical . 'copyCheckboxesRange(\'rowsDeleteForm\', \'id_rows_to_delete' . $row_no . '\',\'[%_PMA_CHECKBOX_DIR_%]\');"' . ' value="' . htmlspecialchars($del_query) . '" ' . (isset($GLOBALS['checkall']) ? 'checked="checked"' : '') . ' />' . "\n" . ' </td>' . "\n"; } else { unset($vertical_display['row_delete'][$row_no]); } if (isset($edit_url)) { $vertical_display['edit'][$row_no] .= ' <td align="center" class="' . $class . '" ' . $column_style_vertical . '>' . "\n" . PMA_linkOrButton($edit_url, $edit_str, array(), false) . $bookmark_go . ' </td>' . "\n"; } else { unset($vertical_display['edit'][$row_no]); } if (isset($del_url)) { $vertical_display['delete'][$row_no] .= ' <td align="center" class="' . $class . '" ' . $column_style_vertical . '>' . "\n" . PMA_linkOrButton($del_url, $del_str, isset($js_conf) ? $js_conf : '', false) . ' </td>' . "\n"; } else { unset($vertical_display['delete'][$row_no]); } echo $_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' ? "\n" : ''; $row_no++; } // end while // this is needed by PMA_displayTable() to generate the proper param // in the multi-edit and multi-delete form return $clause_is_unique; }
/** * Function to generate unique condition for specified row. * * @param resource $handle current query result * @param integer $fields_cnt number of fields * @param array $fields_meta meta information about fields * @param array $row current row * @param boolean $force_unique generate condition only on pk or unique * * @access public * * @return array the calculated condition and whether condition is unique */ function PMA_getUniqueCondition($handle, $fields_cnt, $fields_meta, $row, $force_unique = false) { $primary_key = ''; $unique_key = ''; $nonprimary_condition = ''; $preferred_condition = ''; $primary_key_array = array(); $unique_key_array = array(); $nonprimary_condition_array = array(); $condition_array = array(); for ($i = 0; $i < $fields_cnt; ++$i) { $condition = ''; $con_key = ''; $con_val = ''; $field_flags = PMA_DBI_field_flags($handle, $i); $meta = $fields_meta[$i]; // do not use a column alias in a condition if (!isset($meta->orgname) || !strlen($meta->orgname)) { $meta->orgname = $meta->name; if (isset($GLOBALS['analyzed_sql'][0]['select_expr']) && is_array($GLOBALS['analyzed_sql'][0]['select_expr'])) { foreach ($GLOBALS['analyzed_sql'][0]['select_expr'] as $select_expr) { // need (string) === (string) // '' !== 0 but '' == 0 if ((string) $select_expr['alias'] === (string) $meta->name) { $meta->orgname = $select_expr['column']; break; } // end if } // end foreach } } // Do not use a table alias in a condition. // Test case is: // select * from galerie x WHERE //(select count(*) from galerie y where y.datum=x.datum)>1 // // But orgtable is present only with mysqli extension so the // fix is only for mysqli. // Also, do not use the original table name if we are dealing with // a view because this view might be updatable. // (The isView() verification should not be costly in most cases // because there is some caching in the function). if (isset($meta->orgtable) && $meta->table != $meta->orgtable && !PMA_Table::isView($GLOBALS['db'], $meta->table)) { $meta->table = $meta->orgtable; } // to fix the bug where float fields (primary or not) // can't be matched because of the imprecision of // floating comparison, use CONCAT // (also, the syntax "CONCAT(field) IS NULL" // that we need on the next "if" will work) if ($meta->type == 'real') { $con_key = 'CONCAT(' . PMA_backquote($meta->table) . '.' . PMA_backquote($meta->orgname) . ')'; } else { $con_key = PMA_backquote($meta->table) . '.' . PMA_backquote($meta->orgname); } // end if... else... $condition = ' ' . $con_key . ' '; if (!isset($row[$i]) || is_null($row[$i])) { $con_val = 'IS NULL'; } else { // timestamp is numeric on some MySQL 4.1 // for real we use CONCAT above and it should compare to string if ($meta->numeric && $meta->type != 'timestamp' && $meta->type != 'real') { $con_val = '= ' . $row[$i]; } elseif (($meta->type == 'blob' || $meta->type == 'string') && stristr($field_flags, 'BINARY') && !empty($row[$i])) { // do not waste memory building a too big condition if (strlen($row[$i]) < 1000) { // use a CAST if possible, to avoid problems // if the field contains wildcard characters % or _ $con_val = '= CAST(0x' . bin2hex($row[$i]) . ' AS BINARY)'; } else { // this blob won't be part of the final condition $con_val = null; } } elseif (in_array($meta->type, PMA_getGISDatatypes()) && !empty($row[$i])) { // do not build a too big condition if (strlen($row[$i]) < 5000) { $condition .= '=0x' . bin2hex($row[$i]) . ' AND'; } else { $condition = ''; } } elseif ($meta->type == 'bit') { $con_val = "= b'" . PMA_printable_bit_value($row[$i], $meta->length) . "'"; } else { $con_val = '= \'' . PMA_sqlAddSlashes($row[$i], false, true) . '\''; } } if ($con_val != null) { $condition .= $con_val . ' AND'; if ($meta->primary_key > 0) { $primary_key .= $condition; $primary_key_array[$con_key] = $con_val; } elseif ($meta->unique_key > 0) { $unique_key .= $condition; $unique_key_array[$con_key] = $con_val; } $nonprimary_condition .= $condition; $nonprimary_condition_array[$con_key] = $con_val; } } // end for // Correction University of Virginia 19991216: // prefer primary or unique keys for condition, // but use conjunction of all values if no primary key $clause_is_unique = true; if ($primary_key) { $preferred_condition = $primary_key; $condition_array = $primary_key_array; } elseif ($unique_key) { $preferred_condition = $unique_key; $condition_array = $unique_key_array; } elseif (!$force_unique) { $preferred_condition = $nonprimary_condition; $condition_array = $nonprimary_condition_array; $clause_is_unique = false; } $where_clause = trim(preg_replace('|\\s?AND$|', '', $preferred_condition)); return array($where_clause, $clause_is_unique, $condition_array); }
/** * returns metainfo for fields in $result * * @todo preserve orignal flags value * @uses PMA_DBI_field_flags() * @uses MYSQLI_TYPE_* * @uses MYSQLI_MULTIPLE_KEY_FLAG * @uses MYSQLI_PRI_KEY_FLAG * @uses MYSQLI_UNIQUE_KEY_FLAG * @uses MYSQLI_NOT_NULL_FLAG * @uses MYSQLI_UNSIGNED_FLAG * @uses MYSQLI_ZEROFILL_FLAG * @uses MYSQLI_NUM_FLAG * @uses MYSQLI_TYPE_BLOB * @uses MYSQLI_BLOB_FLAG * @uses defined() * @uses mysqli_fetch_fields() * @uses is_array() * @param object mysqli result $result * @return array meta info for fields in $result */ function PMA_DBI_get_fields_meta($result) { // Build an associative array for a type look up $typeAr = array(); $typeAr[MYSQLI_TYPE_DECIMAL] = 'real'; $typeAr[MYSQLI_TYPE_NEWDECIMAL] = 'real'; $typeAr[MYSQLI_TYPE_BIT] = 'bool'; $typeAr[MYSQLI_TYPE_TINY] = 'int'; $typeAr[MYSQLI_TYPE_SHORT] = 'int'; $typeAr[MYSQLI_TYPE_LONG] = 'int'; $typeAr[MYSQLI_TYPE_FLOAT] = 'real'; $typeAr[MYSQLI_TYPE_DOUBLE] = 'real'; $typeAr[MYSQLI_TYPE_NULL] = 'null'; $typeAr[MYSQLI_TYPE_TIMESTAMP] = 'timestamp'; $typeAr[MYSQLI_TYPE_LONGLONG] = 'int'; $typeAr[MYSQLI_TYPE_INT24] = 'int'; $typeAr[MYSQLI_TYPE_DATE] = 'date'; $typeAr[MYSQLI_TYPE_TIME] = 'time'; $typeAr[MYSQLI_TYPE_DATETIME] = 'datetime'; $typeAr[MYSQLI_TYPE_YEAR] = 'year'; $typeAr[MYSQLI_TYPE_NEWDATE] = 'date'; $typeAr[MYSQLI_TYPE_ENUM] = 'unknown'; $typeAr[MYSQLI_TYPE_SET] = 'unknown'; $typeAr[MYSQLI_TYPE_TINY_BLOB] = 'blob'; $typeAr[MYSQLI_TYPE_MEDIUM_BLOB] = 'blob'; $typeAr[MYSQLI_TYPE_LONG_BLOB] = 'blob'; $typeAr[MYSQLI_TYPE_BLOB] = 'blob'; $typeAr[MYSQLI_TYPE_VAR_STRING] = 'string'; $typeAr[MYSQLI_TYPE_STRING] = 'string'; // MySQL returns MYSQLI_TYPE_STRING for CHAR // and MYSQLI_TYPE_CHAR === MYSQLI_TYPE_TINY // so this would override TINYINT and mark all TINYINT as string // https://sf.net/tracker/?func=detail&aid=1532111&group_id=23067&atid=377408 //$typeAr[MYSQLI_TYPE_CHAR] = 'string'; $typeAr[MYSQLI_TYPE_GEOMETRY] = 'unknown'; $fields = mysqli_fetch_fields($result); // this happens sometimes (seen under MySQL 4.0.25) if (!is_array($fields)) { return false; } foreach ($fields as $k => $field) { $fields[$k]->_type = $field->type; $fields[$k]->type = $typeAr[$field->type]; $fields[$k]->_flags = $field->flags; $fields[$k]->flags = PMA_DBI_field_flags($result, $k); // Enhance the field objects for mysql-extension compatibilty //$flags = explode(' ', $fields[$k]->flags); //array_unshift($flags, 'dummy'); $fields[$k]->multiple_key = (int) (bool) ($fields[$k]->_flags & MYSQLI_MULTIPLE_KEY_FLAG); $fields[$k]->primary_key = (int) (bool) ($fields[$k]->_flags & MYSQLI_PRI_KEY_FLAG); $fields[$k]->unique_key = (int) (bool) ($fields[$k]->_flags & MYSQLI_UNIQUE_KEY_FLAG); $fields[$k]->not_null = (int) (bool) ($fields[$k]->_flags & MYSQLI_NOT_NULL_FLAG); $fields[$k]->unsigned = (int) (bool) ($fields[$k]->_flags & MYSQLI_UNSIGNED_FLAG); $fields[$k]->zerofill = (int) (bool) ($fields[$k]->_flags & MYSQLI_ZEROFILL_FLAG); $fields[$k]->numeric = (int) (bool) ($fields[$k]->_flags & MYSQLI_NUM_FLAG); $fields[$k]->blob = (int) (bool) ($fields[$k]->_flags & MYSQLI_BLOB_FLAG); } return $fields; }
/** * Outputs the content of a table in SQL format * * @param string $db database name * @param string $table table name * @param string $crlf the end of line sequence * @param string $error_url the url to go back in case of error * @param string $sql_query SQL query for obtaining data * * @return bool Whether it succeeded */ public function exportData($db, $table, $crlf, $error_url, $sql_query) { global $current_row, $sql_backquotes; if (isset($GLOBALS['sql_compatibility'])) { $compat = $GLOBALS['sql_compatibility']; } else { $compat = 'NONE'; } $formatted_table_name = isset($GLOBALS['sql_backquotes']) ? PMA_Util::backquoteCompat($table, $compat) : '\'' . $table . '\''; // Do not export data for a VIEW // (For a VIEW, this is called only when exporting a single VIEW) if (PMA_Table::isView($db, $table)) { $head = $this->_possibleCRLF() . $this->_exportComment() . $this->_exportComment('VIEW ' . ' ' . $formatted_table_name) . $this->_exportComment(__('Data') . ': ' . __('None')) . $this->_exportComment() . $this->_possibleCRLF(); if (!PMA_exportOutputHandler($head)) { return false; } return true; } // analyze the query to get the true column names, not the aliases // (this fixes an undefined index, also if Complete inserts // are used, we did not get the true column name in case of aliases) $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($sql_query)); $result = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); // a possible error: the table has crashed $tmp_error = PMA_DBI_getError(); if ($tmp_error) { return PMA_exportOutputHandler($this->_exportComment(__('Error reading data:') . ' (' . $tmp_error . ')')); } if ($result != false) { $fields_cnt = PMA_DBI_num_fields($result); // Get field information $fields_meta = PMA_DBI_get_fields_meta($result); $field_flags = array(); for ($j = 0; $j < $fields_cnt; $j++) { $field_flags[$j] = PMA_DBI_field_flags($result, $j); } for ($j = 0; $j < $fields_cnt; $j++) { if (isset($analyzed_sql[0]['select_expr'][$j]['column'])) { $field_set[$j] = PMA_Util::backquoteCompat($analyzed_sql[0]['select_expr'][$j]['column'], $compat, $sql_backquotes); } else { $field_set[$j] = PMA_Util::backquoteCompat($fields_meta[$j]->name, $compat, $sql_backquotes); } } if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'UPDATE') { // update $schema_insert = 'UPDATE '; if (isset($GLOBALS['sql_ignore'])) { $schema_insert .= 'IGNORE '; } // avoid EOL blank $schema_insert .= PMA_Util::backquoteCompat($table, $compat, $sql_backquotes) . ' SET'; } else { // insert or replace if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'REPLACE') { $sql_command = 'REPLACE'; } else { $sql_command = 'INSERT'; } // delayed inserts? if (isset($GLOBALS['sql_delayed'])) { $insert_delayed = ' DELAYED'; } else { $insert_delayed = ''; } // insert ignore? if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'INSERT' && isset($GLOBALS['sql_ignore'])) { $insert_delayed .= ' IGNORE'; } //truncate table before insert if (isset($GLOBALS['sql_truncate']) && $GLOBALS['sql_truncate'] && $sql_command == 'INSERT') { $truncate = 'TRUNCATE TABLE ' . PMA_Util::backquoteCompat($table, $compat, $sql_backquotes) . ";"; $truncatehead = $this->_possibleCRLF() . $this->_exportComment() . $this->_exportComment(__('Truncate table before insert') . ' ' . $formatted_table_name) . $this->_exportComment() . $crlf; PMA_exportOutputHandler($truncatehead); PMA_exportOutputHandler($truncate); } else { $truncate = ''; } // scheme for inserting fields if ($GLOBALS['sql_insert_syntax'] == 'complete' || $GLOBALS['sql_insert_syntax'] == 'both') { $fields = implode(', ', $field_set); $schema_insert = $sql_command . $insert_delayed . ' INTO ' . PMA_Util::backquoteCompat($table, $compat, $sql_backquotes) . ' (' . $fields . ') VALUES'; } else { $schema_insert = $sql_command . $insert_delayed . ' INTO ' . PMA_Util::backquoteCompat($table, $compat, $sql_backquotes) . ' VALUES'; } } //\x08\\x09, not required $search = array("", "\n", "\r", ""); $replace = array('\\0', '\\n', '\\r', '\\Z'); $current_row = 0; $query_size = 0; if (($GLOBALS['sql_insert_syntax'] == 'extended' || $GLOBALS['sql_insert_syntax'] == 'both') && (!isset($GLOBALS['sql_type']) || $GLOBALS['sql_type'] != 'UPDATE')) { $separator = ','; $schema_insert .= $crlf; } else { $separator = ';'; } while ($row = PMA_DBI_fetch_row($result)) { if ($current_row == 0) { $head = $this->_possibleCRLF() . $this->_exportComment() . $this->_exportComment(__('Dumping data for table') . ' ' . $formatted_table_name) . $this->_exportComment() . $crlf; if (!PMA_exportOutputHandler($head)) { return false; } } // We need to SET IDENTITY_INSERT ON for MSSQL if (isset($GLOBALS['sql_compatibility']) && $GLOBALS['sql_compatibility'] == 'MSSQL' && $current_row == 0) { if (!PMA_exportOutputHandler('SET IDENTITY_INSERT ' . PMA_Util::backquoteCompat($table, $compat) . ' ON ;' . $crlf)) { return false; } } $current_row++; for ($j = 0; $j < $fields_cnt; $j++) { // NULL if (!isset($row[$j]) || is_null($row[$j])) { $values[] = 'NULL'; } elseif ($fields_meta[$j]->numeric && $fields_meta[$j]->type != 'timestamp' && !$fields_meta[$j]->blob) { // a number // timestamp is numeric on some MySQL 4.1, BLOBs are // sometimes numeric $values[] = $row[$j]; } elseif (stristr($field_flags[$j], 'BINARY') && $fields_meta[$j]->blob && isset($GLOBALS['sql_hex_for_blob'])) { // a true BLOB // - mysqldump only generates hex data when the --hex-blob // option is used, for fields having the binary attribute // no hex is generated // - a TEXT field returns type blob but a real blob // returns also the 'binary' flag // empty blobs need to be different, but '0' is also empty // :-( if (empty($row[$j]) && $row[$j] != '0') { $values[] = '\'\''; } else { $values[] = '0x' . bin2hex($row[$j]); } } elseif ($fields_meta[$j]->type == 'bit') { // detection of 'bit' works only on mysqli extension $values[] = "b'" . PMA_Util::sqlAddSlashes(PMA_Util::printableBitValue($row[$j], $fields_meta[$j]->length)) . "'"; } else { // something else -> treat as a string $values[] = '\'' . str_replace($search, $replace, PMA_Util::sqlAddSlashes($row[$j])) . '\''; } // end if } // end for // should we make update? if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'UPDATE') { $insert_line = $schema_insert; for ($i = 0; $i < $fields_cnt; $i++) { if (0 == $i) { $insert_line .= ' '; } if ($i > 0) { // avoid EOL blank $insert_line .= ','; } $insert_line .= $field_set[$i] . ' = ' . $values[$i]; } list($tmp_unique_condition, $tmp_clause_is_unique) = PMA_Util::getUniqueCondition($result, $fields_cnt, $fields_meta, $row); $insert_line .= ' WHERE ' . $tmp_unique_condition; unset($tmp_unique_condition, $tmp_clause_is_unique); } else { // Extended inserts case if ($GLOBALS['sql_insert_syntax'] == 'extended' || $GLOBALS['sql_insert_syntax'] == 'both') { if ($current_row == 1) { $insert_line = $schema_insert . '(' . implode(', ', $values) . ')'; } else { $insert_line = '(' . implode(', ', $values) . ')'; $sql_max_size = $GLOBALS['sql_max_query_size']; if (isset($sql_max_size) && $sql_max_size > 0 && $query_size + strlen($insert_line) > $sql_max_size) { if (!PMA_exportOutputHandler(';' . $crlf)) { return false; } $query_size = 0; $current_row = 1; $insert_line = $schema_insert . $insert_line; } } $query_size += strlen($insert_line); // Other inserts case } else { $insert_line = $schema_insert . '(' . implode(', ', $values) . ')'; } } unset($values); if (!PMA_exportOutputHandler(($current_row == 1 ? '' : $separator . $crlf) . $insert_line)) { return false; } } // end while if ($current_row > 0) { if (!PMA_exportOutputHandler(';' . $crlf)) { return false; } } // We need to SET IDENTITY_INSERT OFF for MSSQL if (isset($GLOBALS['sql_compatibility']) && $GLOBALS['sql_compatibility'] == 'MSSQL' && $current_row > 0) { $outputSucceeded = PMA_exportOutputHandler($crlf . 'SET IDENTITY_INSERT ' . PMA_Util::backquoteCompat($table, $compat) . ' OFF;' . $crlf); if (!$outputSucceeded) { return false; } } } // end if ($result != false) PMA_DBI_free_result($result); return true; }
/** * returns metainfo for fields in $result * * @param PMA_DrizzleResult $result * @return array meta info for fields in $result */ function PMA_DBI_get_fields_meta($result) { // Build an associative array for a type look up $typeAr = array(); /*$typeAr[DRIZZLE_COLUMN_TYPE_DECIMAL] = 'real'; $typeAr[DRIZZLE_COLUMN_TYPE_NEWDECIMAL] = 'real'; $typeAr[DRIZZLE_COLUMN_TYPE_BIT] = 'int'; $typeAr[DRIZZLE_COLUMN_TYPE_TINY] = 'int'; $typeAr[DRIZZLE_COLUMN_TYPE_SHORT] = 'int'; $typeAr[DRIZZLE_COLUMN_TYPE_LONG] = 'int'; $typeAr[DRIZZLE_COLUMN_TYPE_FLOAT] = 'real'; $typeAr[DRIZZLE_COLUMN_TYPE_DOUBLE] = 'real'; $typeAr[DRIZZLE_COLUMN_TYPE_NULL] = 'null'; $typeAr[DRIZZLE_COLUMN_TYPE_TIMESTAMP] = 'timestamp'; $typeAr[DRIZZLE_COLUMN_TYPE_LONGLONG] = 'int'; $typeAr[DRIZZLE_COLUMN_TYPE_INT24] = 'int'; $typeAr[DRIZZLE_COLUMN_TYPE_DATE] = 'date'; $typeAr[DRIZZLE_COLUMN_TYPE_TIME] = 'date'; $typeAr[DRIZZLE_COLUMN_TYPE_DATETIME] = 'datetime'; $typeAr[DRIZZLE_COLUMN_TYPE_YEAR] = 'year'; $typeAr[DRIZZLE_COLUMN_TYPE_NEWDATE] = 'date'; $typeAr[DRIZZLE_COLUMN_TYPE_ENUM] = 'unknown'; $typeAr[DRIZZLE_COLUMN_TYPE_SET] = 'unknown'; $typeAr[DRIZZLE_COLUMN_TYPE_VIRTUAL] = 'unknown'; $typeAr[DRIZZLE_COLUMN_TYPE_TINY_BLOB] = 'blob'; $typeAr[DRIZZLE_COLUMN_TYPE_MEDIUM_BLOB] = 'blob'; $typeAr[DRIZZLE_COLUMN_TYPE_LONG_BLOB] = 'blob'; $typeAr[DRIZZLE_COLUMN_TYPE_BLOB] = 'blob'; $typeAr[DRIZZLE_COLUMN_TYPE_VAR_STRING] = 'string'; $typeAr[DRIZZLE_COLUMN_TYPE_VARCHAR] = 'string'; $typeAr[DRIZZLE_COLUMN_TYPE_STRING] = 'string'; $typeAr[DRIZZLE_COLUMN_TYPE_GEOMETRY] = 'geometry';*/ $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_BLOB] = 'blob'; $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DATE] = 'date'; $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DATETIME] = 'datetime'; $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_DOUBLE] = 'real'; $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_ENUM] = 'unknown'; $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_LONG] = 'int'; $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_LONGLONG] = 'int'; $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_MAX] = 'unknown'; $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_NULL] = 'null'; $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_TIMESTAMP] = 'timestamp'; $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_TINY] = 'int'; $typeAr[DRIZZLE_COLUMN_TYPE_DRIZZLE_VARCHAR] = 'string'; // array of DrizzleColumn $columns = $result->getColumns(); // columns in a standarized format $std_columns = array(); foreach ($columns as $k => $column) { $c = new stdClass(); $c->name = $column->name(); $c->orgname = $column->origName(); $c->table = $column->table(); $c->orgtable = $column->origTable(); $c->def = $column->defaultValue(); $c->db = $column->db(); $c->catalog = $column->catalog(); // $column->maxSize() returns always 0 while size() seems // to return a correct value (drizzle extension v.0.5, API v.7) $c->max_length = $column->size(); $c->decimals = $column->decimals(); $c->charsetnr = $column->charset(); $c->type = $typeAr[$column->typeDrizzle()]; $c->_type = $column->type(); $c->flags = PMA_DBI_field_flags($result, $k); $c->_flags = $column->flags(); $c->multiple_key = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_MULTIPLE_KEY); $c->primary_key = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_PRI_KEY); $c->unique_key = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_UNIQUE_KEY); $c->not_null = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_NOT_NULL); $c->unsigned = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_UNSIGNED); $c->zerofill = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_ZEROFILL); $c->numeric = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_NUM); $c->blob = (int) (bool) ($c->_flags & DRIZZLE_COLUMN_FLAGS_BLOB); $std_columns[] = $c; } return $std_columns; }
/** * Displays the body of the results table * * @uses $_SESSION['tmp_user_values']['disp_direction'] * @uses $_SESSION['tmp_user_values']['repeat_cells'] * @uses $_SESSION['tmp_user_values']['max_rows'] * @uses $_SESSION['tmp_user_values']['display_text'] * @uses $_SESSION['tmp_user_values']['display_binary'] * @uses $_SESSION['tmp_user_values']['display_binary_as_hex'] * @uses $_SESSION['tmp_user_values']['display_blob'] * @param integer the link id associated to the query which results have * to be displayed * @param array which elements to display * @param array the list of relations * @param array the analyzed query * * @return boolean always true * * @global string $db the database name * @global string $table the table name * @global string $goto the URL to go back in case of errors * @global string $sql_query the SQL query * @global array $fields_meta the list of fields properties * @global integer $fields_cnt the total number of fields returned by * the SQL query * @global array $vertical_display informations used with vertical display * mode * @global array $highlight_columns column names to highlight * @global array $row current row data * * @access private * * @see PMA_displayTable() */ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) { global $db, $table, $goto; global $sql_query, $fields_meta, $fields_cnt; global $vertical_display, $highlight_columns; global $row; // mostly because of browser transformations, to make the row-data accessible in a plugin $url_sql_query = $sql_query; // query without conditions to shorten URLs when needed, 200 is just // guess, it should depend on remaining URL length if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['querytype']) && $analyzed_sql[0]['querytype'] == 'SELECT' && strlen($sql_query) > 200) { $url_sql_query = 'SELECT '; if (isset($analyzed_sql[0]['queryflags']['distinct'])) { $url_sql_query .= ' DISTINCT '; } $url_sql_query .= $analyzed_sql[0]['select_expr_clause']; if (!empty($analyzed_sql[0]['from_clause'])) { $url_sql_query .= ' FROM ' . $analyzed_sql[0]['from_clause']; } } if (!is_array($map)) { $map = array(); } $row_no = 0; $vertical_display['edit'] = array(); $vertical_display['copy'] = array(); $vertical_display['delete'] = array(); $vertical_display['data'] = array(); $vertical_display['row_delete'] = array(); // name of the class added to all inline editable elements $inline_edit_class = 'inline_edit'; // Correction University of Virginia 19991216 in the while below // Previous code assumed that all tables have keys, specifically that // the phpMyAdmin GUI should support row delete/edit only for such // tables. // Although always using keys is arguably the prescribed way of // defining a relational table, it is not required. This will in // particular be violated by the novice. // We want to encourage phpMyAdmin usage by such novices. So the code // below has been changed to conditionally work as before when the // table being displayed has one or more keys; but to display // delete/edit options correctly for tables without keys. $odd_row = true; while ($row = PMA_DBI_fetch_row($dt_result)) { // "vertical display" mode stuff if ($row_no != 0 && $_SESSION['tmp_user_values']['repeat_cells'] != 0 && !($row_no % $_SESSION['tmp_user_values']['repeat_cells']) && ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped')) { echo '<tr>' . "\n"; if ($vertical_display['emptypre'] > 0) { echo ' <th colspan="' . $vertical_display['emptypre'] . '">' . "\n" . ' </th>' . "\n"; } foreach ($vertical_display['desc'] as $val) { echo $val; } if ($vertical_display['emptyafter'] > 0) { echo ' <th colspan="' . $vertical_display['emptyafter'] . '">' . "\n" . ' </th>' . "\n"; } echo '</tr>' . "\n"; } // end if $alternating_color_class = $odd_row ? 'odd' : 'even'; $odd_row = !$odd_row; if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { // pointer code part echo '<tr class="' . $alternating_color_class . '">'; } // 1. Prepares the row // 1.1 Results from a "SELECT" statement -> builds the // WHERE clause to use in links (a unique key if possible) /** * @todo $where_clause could be empty, for example a table * with only one field and it's a BLOB; in this case, * avoid to display the delete and edit links */ list($where_clause, $clause_is_unique) = PMA_getUniqueCondition($dt_result, $fields_cnt, $fields_meta, $row); $where_clause_html = urlencode($where_clause); // 1.2 Defines the URLs for the modify/delete link(s) if ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn') { // We need to copy the value or else the == 'both' check will always return true if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') { $iconic_spacer = '<div class="nowrap">'; } else { $iconic_spacer = ''; } // 1.2.1 Modify link(s) if ($is_display['edit_lnk'] == 'ur') { // update row case $_url_params = array('db' => $db, 'table' => $table, 'where_clause' => $where_clause, 'clause_is_unique' => $clause_is_unique, 'sql_query' => $url_sql_query, 'goto' => 'sql.php'); $edit_url = 'tbl_change.php' . PMA_generate_common_url($_url_params + array('default_action' => 'update')); $copy_url = 'tbl_change.php' . PMA_generate_common_url($_url_params + array('default_action' => 'insert')); $edit_str = PMA_getIcon('b_edit.png', __('Edit'), true); $copy_str = PMA_getIcon('b_insrow.png', __('Copy'), true); // Class definitions required for inline editing jQuery scripts $edit_anchor_class = "edit_row_anchor"; if ($clause_is_unique == 0) { $edit_anchor_class .= ' nonunique'; } } // end if (1.2.1) // 1.2.2 Delete/Kill link(s) if ($is_display['del_lnk'] == 'dr') { // delete row case $_url_params = array('db' => $db, 'table' => $table, 'sql_query' => $url_sql_query, 'message_to_show' => __('The row has been deleted'), 'goto' => empty($goto) ? 'tbl_sql.php' : $goto); $lnk_goto = 'sql.php' . PMA_generate_common_url($_url_params, 'text'); $del_query = 'DELETE FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table) . ' WHERE ' . $where_clause . ($clause_is_unique ? '' : ' LIMIT 1'); $_url_params = array('db' => $db, 'table' => $table, 'sql_query' => $del_query, 'message_to_show' => __('The row has been deleted'), 'goto' => $lnk_goto); $del_url = 'sql.php' . PMA_generate_common_url($_url_params); $js_conf = 'DELETE FROM ' . PMA_jsFormat($db) . '.' . PMA_jsFormat($table) . ' WHERE ' . PMA_jsFormat($where_clause, false) . ($clause_is_unique ? '' : ' LIMIT 1'); $del_str = PMA_getIcon('b_drop.png', __('Delete'), true); } elseif ($is_display['del_lnk'] == 'kp') { // kill process case $_url_params = array('db' => $db, 'table' => $table, 'sql_query' => $url_sql_query, 'goto' => 'main.php'); $lnk_goto = 'sql.php' . PMA_generate_common_url($_url_params, 'text'); $_url_params = array('db' => 'mysql', 'sql_query' => 'KILL ' . $row[0], 'goto' => $lnk_goto); $del_url = 'sql.php' . PMA_generate_common_url($_url_params); $del_query = 'KILL ' . $row[0]; $js_conf = 'KILL ' . $row[0]; $del_str = PMA_getIcon('b_drop.png', __('Kill'), true); } // end if (1.2.2) // 1.3 Displays the links at left if required if ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped')) { if (!isset($js_conf)) { $js_conf = ''; } echo PMA_generateCheckboxAndLinks('left', $del_url, $is_display, $row_no, $where_clause, $where_clause_html, $del_query, 'l', $edit_url, $copy_url, $edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf); } // end if (1.3) } // end if (1) // 2. Displays the rows' values for ($i = 0; $i < $fields_cnt; ++$i) { $meta = $fields_meta[$i]; $not_null_class = $meta->not_null ? 'not_null' : ''; $relation_class = isset($map[$meta->name]) ? 'relation' : ''; $pointer = $i; $is_field_truncated = false; //If the previous column had blob data, we need to reset the class // to $inline_edit_class $class = 'data ' . $inline_edit_class . ' ' . $not_null_class . ' ' . $alternating_color_class . ' ' . $relation_class; // See if this column should get highlight because it's used in the // where-query. if (isset($highlight_columns) && (isset($highlight_columns[$meta->name]) || isset($highlight_columns[PMA_backquote($meta->name)]))) { $condition_field = true; } else { $condition_field = false; } if ($_SESSION['tmp_user_values']['disp_direction'] == 'vertical' && (!isset($GLOBALS['printview']) || $GLOBALS['printview'] != '1')) { // the row number corresponds to a data row, not HTML table row $class .= ' row_' . $row_no; if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) { $class .= ' vpointer'; } if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) { $class .= ' vmarker'; } } // end if // Wrap MIME-transformations. [MIME] $default_function = 'default_function'; // default_function $transform_function = $default_function; $transform_options = array(); if ($GLOBALS['cfgRelation']['mimework'] && $GLOBALS['cfg']['BrowseMIME']) { if (isset($GLOBALS['mime_map'][$meta->name]['mimetype']) && isset($GLOBALS['mime_map'][$meta->name]['transformation']) && !empty($GLOBALS['mime_map'][$meta->name]['transformation'])) { $include_file = PMA_securePath($GLOBALS['mime_map'][$meta->name]['transformation']); if (file_exists('./libraries/transformations/' . $include_file)) { $transformfunction_name = str_replace('.inc.php', '', $GLOBALS['mime_map'][$meta->name]['transformation']); require_once './libraries/transformations/' . $include_file; if (function_exists('PMA_transformation_' . $transformfunction_name)) { $transform_function = 'PMA_transformation_' . $transformfunction_name; $transform_options = PMA_transformation_getOptions(isset($GLOBALS['mime_map'][$meta->name]['transformation_options']) ? $GLOBALS['mime_map'][$meta->name]['transformation_options'] : ''); $meta->mimetype = str_replace('_', '/', $GLOBALS['mime_map'][$meta->name]['mimetype']); } } // end if file_exists } // end if transformation is set } // end if mime/transformation works. $_url_params = array('db' => $db, 'table' => $table, 'where_clause' => $where_clause, 'transform_key' => $meta->name); if (!empty($sql_query)) { $_url_params['sql_query'] = $url_sql_query; } $transform_options['wrapper_link'] = PMA_generate_common_url($_url_params); // n u m e r i c if ($meta->numeric == 1) { // if two fields have the same name (this is possible // with self-join queries, for example), using $meta->name // will show both fields NULL even if only one is NULL, // so use the $pointer if (!isset($row[$i]) || is_null($row[$i])) { $vertical_display['data'][$row_no][$i] = PMA_buildNullDisplay($class, $condition_field, $meta, 'align="right"'); } elseif ($row[$i] != '') { $nowrap = ' nowrap'; $where_comparison = ' = ' . $row[$i]; $vertical_display['data'][$row_no][$i] = '<td align="right"' . PMA_prepare_row_data($class, $condition_field, $analyzed_sql, $meta, $map, $row[$i], $transform_function, $default_function, $nowrap, $where_comparison, $transform_options, $is_field_truncated); } else { $vertical_display['data'][$row_no][$i] = PMA_buildEmptyDisplay($class, $condition_field, $meta, 'align="right"'); } // b l o b } elseif (stristr($meta->type, 'BLOB')) { // PMA_mysql_fetch_fields returns BLOB in place of // TEXT fields type so we have to ensure it's really a BLOB $field_flags = PMA_DBI_field_flags($dt_result, $i); // remove 'inline_edit' from $class as we can't edit binary data. $class = str_replace('inline_edit', '', $class); if (stristr($field_flags, 'BINARY')) { if (!isset($row[$i]) || is_null($row[$i])) { $vertical_display['data'][$row_no][$i] = PMA_buildNullDisplay($class, $condition_field, $meta); } else { // for blobstreaming // if valid BS reference exists if (PMA_BS_IsPBMSReference($row[$i], $db)) { $blobtext = PMA_BS_CreateReferenceLink($row[$i], $db); } else { $blobtext = PMA_handle_non_printable_contents('BLOB', isset($row[$i]) ? $row[$i] : '', $transform_function, $transform_options, $default_function, $meta, $_url_params); } $vertical_display['data'][$row_no][$i] = PMA_buildValueDisplay($class, $condition_field, $blobtext); unset($blobtext); } // not binary: } else { if (!isset($row[$i]) || is_null($row[$i])) { $vertical_display['data'][$row_no][$i] = PMA_buildNullDisplay($class, $condition_field, $meta); } elseif ($row[$i] != '') { // if a transform function for blob is set, none of these replacements will be made if (PMA_strlen($row[$i]) > $GLOBALS['cfg']['LimitChars'] && $_SESSION['tmp_user_values']['display_text'] == 'P') { $row[$i] = PMA_substr($row[$i], 0, $GLOBALS['cfg']['LimitChars']) . '...'; $is_field_truncated = true; } // displays all space characters, 4 space // characters for tabulations and <cr>/<lf> $row[$i] = $default_function != $transform_function ? $transform_function($row[$i], $transform_options, $meta) : $default_function($row[$i], array(), $meta); $vertical_display['data'][$row_no][$i] = PMA_buildValueDisplay($class, $condition_field, $row[$i]); } else { $vertical_display['data'][$row_no][$i] = PMA_buildEmptyDisplay($class, $condition_field, $meta); } } // g e o m e t r y } elseif ($meta->type == 'geometry') { $geometry_text = PMA_handle_non_printable_contents('GEOMETRY', isset($row[$i]) ? $row[$i] : '', $transform_function, $transform_options, $default_function, $meta); // remove 'inline_edit' from $class as we can't edit geometry data. $class = str_replace('inline_edit', '', $class); $vertical_display['data'][$row_no][$i] = PMA_buildValueDisplay($class, $condition_field, $geometry_text); unset($geometry_text); // n o t n u m e r i c a n d n o t B L O B } else { if (!isset($row[$i]) || is_null($row[$i])) { $vertical_display['data'][$row_no][$i] = PMA_buildNullDisplay($class, $condition_field, $meta); } elseif ($row[$i] != '') { // support blanks in the key $relation_id = $row[$i]; // Cut all fields to $GLOBALS['cfg']['LimitChars'] // (unless it's a link-type transformation) if (PMA_strlen($row[$i]) > $GLOBALS['cfg']['LimitChars'] && $_SESSION['tmp_user_values']['display_text'] == 'P' && !strpos($transform_function, 'link') === true) { $row[$i] = PMA_substr($row[$i], 0, $GLOBALS['cfg']['LimitChars']) . '...'; $is_field_truncated = true; } // displays special characters from binaries $field_flags = PMA_DBI_field_flags($dt_result, $i); $is_html = false; if (isset($meta->_type) && $meta->_type === MYSQLI_TYPE_BIT) { $row[$i] = PMA_printable_bit_value($row[$i], $meta->length); // some results of PROCEDURE ANALYSE() are reported as // being BINARY but they are quite readable, // so don't treat them as BINARY } elseif (stristr($field_flags, 'BINARY') && $meta->type == 'string' && !(isset($GLOBALS['is_analyse']) && $GLOBALS['is_analyse'])) { if ($_SESSION['tmp_user_values']['display_binary']) { // user asked to see the real contents of BINARY // fields if ($_SESSION['tmp_user_values']['display_binary_as_hex'] && PMA_contains_nonprintable_ascii($row[$i])) { $row[$i] = bin2hex($row[$i]); } else { $row[$i] = htmlspecialchars(PMA_replace_binary_contents($row[$i])); } } else { // we show the BINARY message and field's size // (or maybe use a transformation) $row[$i] = PMA_handle_non_printable_contents('BINARY', $row[$i], $transform_function, $transform_options, $default_function, $meta, $_url_params); $is_html = true; } } if ($is_html) { $vertical_display['data'][$row_no][$i] = PMA_buildValueDisplay($class, $condition_field, $row[$i]); } else { // transform functions may enable no-wrapping: $function_nowrap = $transform_function . '_nowrap'; $bool_nowrap = $default_function != $transform_function && function_exists($function_nowrap) ? $function_nowrap($transform_options) : false; // do not wrap if date field type $nowrap = preg_match('@DATE|TIME@i', $meta->type) || $bool_nowrap ? ' nowrap' : ''; $where_comparison = ' = \'' . PMA_sqlAddslashes($row[$i]) . '\''; $vertical_display['data'][$row_no][$i] = '<td ' . PMA_prepare_row_data($class, $condition_field, $analyzed_sql, $meta, $map, $row[$i], $transform_function, $default_function, $nowrap, $where_comparison, $transform_options, $is_field_truncated); } } else { $vertical_display['data'][$row_no][$i] = PMA_buildEmptyDisplay($class, $condition_field, $meta); } } // output stored cell if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { echo $vertical_display['data'][$row_no][$i]; } if (isset($vertical_display['rowdata'][$i][$row_no])) { $vertical_display['rowdata'][$i][$row_no] .= $vertical_display['data'][$row_no][$i]; } else { $vertical_display['rowdata'][$i][$row_no] = $vertical_display['data'][$row_no][$i]; } } // end for (2) // 3. Displays the modify/delete links on the right if required if ($GLOBALS['cfg']['ModifyDeleteAtRight'] && ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped')) { if (!isset($js_conf)) { $js_conf = ''; } echo PMA_generateCheckboxAndLinks('right', $del_url, $is_display, $row_no, $where_clause, $where_clause_html, $del_query, 'r', $edit_url, $copy_url, $edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf); } // end if (3) if ($_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped') { ?> </tr> <?php } // end if // 4. Gather links of del_urls and edit_urls in an array for later // output if (!isset($vertical_display['edit'][$row_no])) { $vertical_display['edit'][$row_no] = ''; $vertical_display['copy'][$row_no] = ''; $vertical_display['delete'][$row_no] = ''; $vertical_display['row_delete'][$row_no] = ''; } $vertical_class = ' row_' . $row_no; if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) { $vertical_class .= ' vpointer'; } if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) { $vertical_class .= ' vmarker'; } if (!empty($del_url) && $is_display['del_lnk'] != 'kp') { $vertical_display['row_delete'][$row_no] .= PMA_generateCheckboxForMulti($del_url, $is_display, $row_no, $where_clause_html, $del_query, '[%_PMA_CHECKBOX_DIR_%]', $alternating_color_class . $vertical_class); } else { unset($vertical_display['row_delete'][$row_no]); } if (isset($edit_url)) { $vertical_display['edit'][$row_no] .= PMA_generateEditLink($edit_url, $alternating_color_class . ' ' . $edit_anchor_class . $vertical_class, $edit_str, $where_clause, $where_clause_html); } else { unset($vertical_display['edit'][$row_no]); } if (isset($copy_url)) { $vertical_display['copy'][$row_no] .= PMA_generateCopyLink($copy_url, $copy_str, $where_clause, $where_clause_html, $alternating_color_class . $vertical_class); } else { unset($vertical_display['copy'][$row_no]); } if (isset($del_url)) { if (!isset($js_conf)) { $js_conf = ''; } $vertical_display['delete'][$row_no] .= PMA_generateDeleteLink($del_url, $del_str, $js_conf, $alternating_color_class . $vertical_class); } else { unset($vertical_display['delete'][$row_no]); } echo $_SESSION['tmp_user_values']['disp_direction'] == 'horizontal' || $_SESSION['tmp_user_values']['disp_direction'] == 'horizontalflipped' ? "\n" : ''; $row_no++; } // end while // this is needed by PMA_displayTable() to generate the proper param // in the multi-edit and multi-delete form return $clause_is_unique; }
/** * Get data cell for non numeric and non blob type fields * * @param string $column the relavent column in data row * @param string $class the html class for column * @param object $meta the meta-information about the field * @param array $map the list of relations * @param array $_url_params the parameters for generate url * @param boolean $condition_field the column should highlighted * or not * @param string $transformation_plugin the name of transformation function * @param string $default_function the default transformation function * @param string $transform_options the transformation parameters * @param boolean $is_field_truncated the condition for blob data * replacements * @param array $analyzed_sql the analyzed query * @param integer &$dt_result the link id associated to the query * which results have to be displayed * @param integer $col_index the column index * * @return string $cell the prepared data cell, html content * * @access private * * @see _getTableBody() */ private function _getDataCellForNonNumericAndNonBlobColumns($column, $class, $meta, $map, $_url_params, $condition_field, $transformation_plugin, $default_function, $transform_options, $is_field_truncated, $analyzed_sql, &$dt_result, $col_index) { $is_analyse = $this->__get('_is_analyse'); $field_flags = PMA_DBI_field_flags($dt_result, $col_index); if (stristr($field_flags, self::BINARY_FIELD) && ($GLOBALS['cfg']['ProtectBinary'] == 'all' || $GLOBALS['cfg']['ProtectBinary'] == 'noblob')) { $class = str_replace('grid_edit', '', $class); } if (!isset($column) || is_null($column)) { $cell = $this->_buildNullDisplay($class, $condition_field, $meta); } elseif ($column != '') { // Cut all fields to $GLOBALS['cfg']['LimitChars'] // (unless it's a link-type transformation) if (PMA_strlen($column) > $GLOBALS['cfg']['LimitChars'] && $_SESSION['tmp_user_values']['display_text'] == self::DISPLAY_PARTIAL_TEXT && gettype($transformation_plugin) == "object" && !strpos($transformation_plugin::getName(), 'Link') === true) { $column = PMA_substr($column, 0, $GLOBALS['cfg']['LimitChars']) . '...'; $is_field_truncated = true; } $formatted = false; if (isset($meta->_type) && $meta->_type === MYSQLI_TYPE_BIT) { $column = $this->getCommonFunctions()->printableBitValue($column, $meta->length); // some results of PROCEDURE ANALYSE() are reported as // being BINARY but they are quite readable, // so don't treat them as BINARY } elseif (stristr($field_flags, self::BINARY_FIELD) && $meta->type == self::STRING_FIELD && !(isset($is_analyse) && $is_analyse)) { if ($_SESSION['tmp_user_values']['display_binary']) { // user asked to see the real contents of BINARY // fields if ($_SESSION['tmp_user_values']['display_binary_as_hex'] && $this->getCommonFunctions()->containsNonPrintableAscii($column)) { $column = bin2hex($column); } else { $column = htmlspecialchars($this->getCommonFunctions()->replaceBinaryContents($column)); } } else { // we show the BINARY message and field's size // (or maybe use a transformation) $column = $this->_handleNonPrintableContents(self::BINARY_FIELD, $column, $transformation_plugin, $transform_options, $default_function, $meta, $_url_params); $formatted = true; } } if ($formatted) { $cell = $this->_buildValueDisplay($class, $condition_field, $column); } else { // transform functions may enable no-wrapping: $function_nowrap = 'applyTransformationNoWrap'; $bool_nowrap = $default_function != $transformation_plugin && function_exists($transformation_plugin->{$function_nowrap}()) ? $transformation_plugin->{$function_nowrap}($transform_options) : false; // do not wrap if date field type $nowrap = preg_match('@DATE|TIME@i', $meta->type) || $bool_nowrap ? ' nowrap' : ''; $where_comparison = ' = \'' . $this->getCommonFunctions()->sqlAddSlashes($column) . '\''; $cell = $this->_getRowData($class, $condition_field, $analyzed_sql, $meta, $map, $column, $transformation_plugin, $default_function, $nowrap, $where_comparison, $transform_options, $is_field_truncated); } } else { $cell = $this->_buildEmptyDisplay($class, $condition_field, $meta); } return $cell; }
/** * Outputs the content of a table in CSV format * * @param string the database name * @param string the table name * @param string the end of line sequence * @param string the url to go back in case of error * @param string SQL query for obtaining data * * @return bool Whether it suceeded * * @access public */ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) { global $what; // Gets the data from the database $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); $fields_cnt = PMA_DBI_num_fields($result); $fields_meta = PMA_DBI_get_fields_meta($result); $field_flags = array(); for ($j = 0; $j < $fields_cnt; $j++) { $field_flags[$j] = PMA_DBI_field_flags($result, $j); } $GLOBALS['ods_buffer'] .= '<table:table table:name="' . htmlspecialchars($table) . '">'; // If required, get fields name at the first line if (isset($GLOBALS[$what . '_columns'])) { $GLOBALS['ods_buffer'] .= '<table:table-row>'; for ($i = 0; $i < $fields_cnt; $i++) { $GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars(stripslashes(PMA_DBI_field_name($result, $i))) . '</text:p>' . '</table:table-cell>'; } // end for $GLOBALS['ods_buffer'] .= '</table:table-row>'; } // end if // Format the data while ($row = PMA_DBI_fetch_row($result)) { $GLOBALS['ods_buffer'] .= '<table:table-row>'; for ($j = 0; $j < $fields_cnt; $j++) { if (!isset($row[$j]) || is_null($row[$j])) { $GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars($GLOBALS[$what . '_null']) . '</text:p>' . '</table:table-cell>'; // ignore binary field // Note: with mysqli, under MySQL 4.1.3, we get the flag // "binary" for those field types (I don't know why) } elseif (stristr($field_flags[$j], 'BINARY') && isset($GLOBALS['sql_hex_for_binary']) && $fields_meta[$j]->type != 'datetime' && $fields_meta[$j]->type != 'date' && $fields_meta[$j]->type != 'time' && $fields_meta[$j]->type != 'timestamp') { $GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p></text:p>' . '</table:table-cell>'; } elseif ($fields_meta[$j]->numeric && $fields_meta[$j]->type != 'timestamp' && !$fields_meta[$j]->blob) { $GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="float" office:value="' . $row[$j] . '" >' . '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>' . '</table:table-cell>'; } else { $GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>' . '</table:table-cell>'; } } // end for $GLOBALS['ods_buffer'] .= '</table:table-row>'; } // end while PMA_DBI_free_result($result); $GLOBALS['ods_buffer'] .= '</table:table>'; return TRUE; }
/** * Dispatches between the versions of 'getTableContent' to use depending * on the php version * * @param string the database name * @param string the table name * @param string the end of line sequence * @param string the url to go back in case of error * @param string SQL query for obtaining data * * @return bool Whether it suceeded * * @global boolean whether to use backquotes to allow the use of special * characters in database, table and fields names or not * @global integer the number of records * @global integer the current record position * * @access public * * @see PMA_getTableContentFast(), PMA_getTableContentOld() * * @author staybyte */ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) { global $sql_backquotes; global $rows_cnt; global $current_row; $formatted_table_name = isset($GLOBALS['sql_backquotes']) ? PMA_backquote($table) : '\'' . $table . '\''; // Do not export data for a VIEW // (For a VIEW, this is called only when exporting a single VIEW) if (PMA_Table::_isView($db, $table)) { $head = $crlf . PMA_exportComment() . PMA_exportComment('VIEW ' . ' ' . $formatted_table_name) . PMA_exportComment($GLOBALS['strData'] . ': ' . $GLOBALS['strNone']) . PMA_exportComment() . $crlf; if (!PMA_exportOutputHandler($head)) { return FALSE; } return true; } // it's not a VIEW $head = $crlf . PMA_exportComment() . PMA_exportComment($GLOBALS['strDumpingData'] . ' ' . $formatted_table_name) . PMA_exportComment() . $crlf; if (!PMA_exportOutputHandler($head)) { return FALSE; } $buffer = ''; // analyze the query to get the true column names, not the aliases // (this fixes an undefined index, also if Complete inserts // are used, we did not get the true column name in case of aliases) $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($sql_query)); $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); if ($result != FALSE) { $fields_cnt = PMA_DBI_num_fields($result); // Get field information $fields_meta = PMA_DBI_get_fields_meta($result); $field_flags = array(); for ($j = 0; $j < $fields_cnt; $j++) { $field_flags[$j] = PMA_DBI_field_flags($result, $j); } for ($j = 0; $j < $fields_cnt; $j++) { if (isset($analyzed_sql[0]['select_expr'][$j]['column'])) { $field_set[$j] = PMA_backquote($analyzed_sql[0]['select_expr'][$j]['column'], $sql_backquotes); } else { $field_set[$j] = PMA_backquote($fields_meta[$j]->name, $sql_backquotes); } } if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'UPDATE') { // update $schema_insert = 'UPDATE '; if (isset($GLOBALS['sql_ignore'])) { $schema_insert .= 'IGNORE '; } // avoid EOL blank $schema_insert .= PMA_backquote($table, $sql_backquotes) . ' SET'; } else { // insert or replace if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'REPLACE') { $sql_command = 'REPLACE'; } else { $sql_command = 'INSERT'; } // delayed inserts? if (isset($GLOBALS['sql_delayed'])) { $insert_delayed = ' DELAYED'; } else { $insert_delayed = ''; } // insert ignore? if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'INSERT' && isset($GLOBALS['sql_ignore'])) { $insert_delayed .= ' IGNORE'; } // scheme for inserting fields if (isset($GLOBALS['sql_columns'])) { $fields = implode(', ', $field_set); $schema_insert = $sql_command . $insert_delayed . ' INTO ' . PMA_backquote($table, $sql_backquotes) . ' (' . $fields . ') VALUES'; } else { $schema_insert = $sql_command . $insert_delayed . ' INTO ' . PMA_backquote($table, $sql_backquotes) . ' VALUES'; } } $search = array("", "\n", "\r", ""); //\x08\\x09, not required $replace = array('\\0', '\\n', '\\r', '\\Z'); $current_row = 0; $query_size = 0; if (isset($GLOBALS['sql_extended']) && (!isset($GLOBALS['sql_type']) || $GLOBALS['sql_type'] != 'UPDATE')) { $separator = ','; $schema_insert .= $crlf; } else { $separator = ';'; } while ($row = PMA_DBI_fetch_row($result)) { $current_row++; for ($j = 0; $j < $fields_cnt; $j++) { // NULL if (!isset($row[$j]) || is_null($row[$j])) { $values[] = 'NULL'; // a number // timestamp is numeric on some MySQL 4.1, BLOBs are sometimes numeric } elseif ($fields_meta[$j]->numeric && $fields_meta[$j]->type != 'timestamp' && !$fields_meta[$j]->blob) { $values[] = $row[$j]; // a true BLOB // - mysqldump only generates hex data when the --hex-blob // option is used, for fields having the binary attribute // no hex is generated // - a TEXT field returns type blob but a real blob // returns also the 'binary' flag } elseif (stristr($field_flags[$j], 'BINARY') && $fields_meta[$j]->blob && isset($GLOBALS['sql_hex_for_blob'])) { // empty blobs need to be different, but '0' is also empty :-( if (empty($row[$j]) && $row[$j] != '0') { $values[] = '\'\''; } else { $values[] = '0x' . bin2hex($row[$j]); } // detection of 'bit' works only on mysqli extension } elseif ($fields_meta[$j]->type == 'bit') { $values[] = "b'" . PMA_sqlAddslashes(PMA_printable_bit_value($row[$j], $fields_meta[$j]->length)) . "'"; // something else -> treat as a string } else { $values[] = '\'' . str_replace($search, $replace, PMA_sqlAddslashes($row[$j])) . '\''; } // end if } // end for // should we make update? if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'UPDATE') { $insert_line = $schema_insert; for ($i = 0; $i < $fields_cnt; $i++) { if (0 == $i) { $insert_line .= ' '; } if ($i > 0) { // avoid EOL blank $insert_line .= ','; } $insert_line .= $field_set[$i] . ' = ' . $values[$i]; } $insert_line .= ' WHERE ' . PMA_getUniqueCondition($result, $fields_cnt, $fields_meta, $row); } else { // Extended inserts case if (isset($GLOBALS['sql_extended'])) { if ($current_row == 1) { $insert_line = $schema_insert . '(' . implode(', ', $values) . ')'; } else { $insert_line = '(' . implode(', ', $values) . ')'; if (isset($GLOBALS['sql_max_query_size']) && $GLOBALS['sql_max_query_size'] > 0 && $query_size + strlen($insert_line) > $GLOBALS['sql_max_query_size']) { if (!PMA_exportOutputHandler(';' . $crlf)) { return FALSE; } $query_size = 0; $current_row = 1; $insert_line = $schema_insert . $insert_line; } } $query_size += strlen($insert_line); } else { $insert_line = $schema_insert . '(' . implode(', ', $values) . ')'; } } unset($values); if (!PMA_exportOutputHandler(($current_row == 1 ? '' : $separator . $crlf) . $insert_line)) { return FALSE; } } // end while if ($current_row > 0) { if (!PMA_exportOutputHandler(';' . $crlf)) { return FALSE; } } } // end if ($result != FALSE) PMA_DBI_free_result($result); return TRUE; }
/** * Function to generate unique condition for specified row. * * @uses PMA_MYSQL_INT_VERSION * @uses $GLOBALS['analyzed_sql'][0] * @uses PMA_DBI_field_flags() * @uses PMA_backquote() * @uses PMA_sqlAddslashes() * @uses stristr() * @uses bin2hex() * @uses preg_replace() * @param resource $handle current query result * @param integer $fields_cnt number of fields * @param array $fields_meta meta information about fields * @param array $row current row * @param boolean $force_unique generate condition only on pk or unique * * @access public * @author Michal Cihar (michal@cihar.com) and others... * @return string calculated condition */ function PMA_getUniqueCondition($handle, $fields_cnt, $fields_meta, $row, $force_unique = false) { $primary_key = ''; $unique_key = ''; $nonprimary_condition = ''; $preferred_condition = ''; for ($i = 0; $i < $fields_cnt; ++$i) { $condition = ''; $field_flags = PMA_DBI_field_flags($handle, $i); $meta = $fields_meta[$i]; // do not use a column alias in a condition if (!isset($meta->orgname) || !strlen($meta->orgname)) { $meta->orgname = $meta->name; if (isset($GLOBALS['analyzed_sql'][0]['select_expr']) && is_array($GLOBALS['analyzed_sql'][0]['select_expr'])) { foreach ($GLOBALS['analyzed_sql'][0]['select_expr'] as $select_expr) { // need (string) === (string) // '' !== 0 but '' == 0 if ((string) $select_expr['alias'] === (string) $meta->name) { $meta->orgname = $select_expr['column']; break; } // end if } // end foreach } } // Do not use a table alias in a condition. // Test case is: // select * from galerie x WHERE //(select count(*) from galerie y where y.datum=x.datum)>1 // // But orgtable is present only with mysqli extension so the // fix is only for mysqli. if (isset($meta->orgtable) && $meta->table != $meta->orgtable) { $meta->table = $meta->orgtable; } // to fix the bug where float fields (primary or not) // can't be matched because of the imprecision of // floating comparison, use CONCAT // (also, the syntax "CONCAT(field) IS NULL" // that we need on the next "if" will work) if ($meta->type == 'real') { $condition = ' CONCAT(' . PMA_backquote($meta->table) . '.' . PMA_backquote($meta->orgname) . ') '; } else { // string and blob fields have to be converted using // the system character set (always utf8) since // mysql4.1 can use different charset for fields. if (PMA_MYSQL_INT_VERSION >= 40100 && ($meta->type == 'string' || $meta->type == 'blob')) { $condition = ' CONVERT(' . PMA_backquote($meta->table) . '.' . PMA_backquote($meta->orgname) . ' USING utf8) '; } else { $condition = ' ' . PMA_backquote($meta->table) . '.' . PMA_backquote($meta->orgname) . ' '; } } // end if... else... if (!isset($row[$i]) || is_null($row[$i])) { $condition .= 'IS NULL AND'; } else { // timestamp is numeric on some MySQL 4.1 if ($meta->numeric && $meta->type != 'timestamp') { $condition .= '= ' . $row[$i] . ' AND'; } elseif (($meta->type == 'blob' || $meta->type == 'string') && stristr($field_flags, 'BINARY') && !empty($row[$i])) { // do not waste memory building a too big condition if (strlen($row[$i]) < 1000) { if (PMA_MYSQL_INT_VERSION < 40002) { $condition .= 'LIKE 0x' . bin2hex($row[$i]) . ' AND'; } else { // use a CAST if possible, to avoid problems // if the field contains wildcard characters % or _ $condition .= '= CAST(0x' . bin2hex($row[$i]) . ' AS BINARY) AND'; } } else { // this blob won't be part of the final condition $condition = ''; } } else { $condition .= '= \'' . PMA_sqlAddslashes($row[$i], false, true) . '\' AND'; } } if ($meta->primary_key > 0) { $primary_key .= $condition; } elseif ($meta->unique_key > 0) { $unique_key .= $condition; } $nonprimary_condition .= $condition; } // end for // Correction University of Virginia 19991216: // prefer primary or unique keys for condition, // but use conjunction of all values if no primary key if ($primary_key) { $preferred_condition = $primary_key; } elseif ($unique_key) { $preferred_condition = $unique_key; } elseif (!$force_unique) { $preferred_condition = $nonprimary_condition; } return preg_replace('|\\s?AND$|', '', $preferred_condition); }
/** * Dispatches between the versions of 'getTableContent' to use depending * on the php version * * @param string the database name * @param string the table name * @param string the end of line sequence * @param string the url to go back in case of error * @param string SQL query for obtaining data * * @return bool Whether it suceeded * * @global boolean whether to use backquotes to allow the use of special * characters in database, table and fields names or not * @global integer the number of records * @global integer the current record position * * @access public * * @see PMA_getTableContentFast(), PMA_getTableContentOld() * * @author staybyte */ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) { global $sql_backquotes; global $rows_cnt; global $current_row; $formatted_table_name = isset($GLOBALS['sql_backquotes']) ? PMA_backquote($table) : '\'' . $table . '\''; $head = $crlf . $GLOBALS['comment_marker'] . $crlf . $GLOBALS['comment_marker'] . $GLOBALS['strDumpingData'] . ' ' . $formatted_table_name . $crlf . $GLOBALS['comment_marker'] . $crlf . $crlf; if (!PMA_exportOutputHandler($head)) { return FALSE; } $buffer = ''; // analyze the query to get the true column names, not the aliases // (this fixes an undefined index, also if Complete inserts // are used, we did not get the true column name in case of aliases) $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($sql_query)); $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); if ($result != FALSE) { $fields_cnt = PMA_DBI_num_fields($result); // Get field information $fields_meta = PMA_DBI_get_fields_meta($result); $field_flags = array(); for ($j = 0; $j < $fields_cnt; $j++) { $field_flags[$j] = PMA_DBI_field_flags($result, $j); } for ($j = 0; $j < $fields_cnt; $j++) { if (isset($analyzed_sql[0]['select_expr'][$j]['column'])) { $field_set[$j] = PMA_backquote($analyzed_sql[0]['select_expr'][$j]['column'], $sql_backquotes); } else { $field_set[$j] = PMA_backquote($fields_meta[$j]->name, $sql_backquotes); } } if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'UPDATE') { // update $schema_insert = 'UPDATE '; if (isset($GLOBALS['sql_ignore'])) { $schema_insert .= 'IGNORE '; } $schema_insert .= PMA_backquote($table, $sql_backquotes) . ' SET '; } else { // insert or replace if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'REPLACE') { $sql_command = 'REPLACE'; } else { $sql_command = 'INSERT'; } // delayed inserts? if (isset($GLOBALS['sql_delayed'])) { $insert_delayed = ' DELAYED'; } else { $insert_delayed = ''; } // insert ignore? if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'INSERT' && isset($GLOBALS['sql_ignore'])) { $insert_delayed .= ' IGNORE'; } // scheme for inserting fields if (isset($GLOBALS['sql_columns'])) { $fields = implode(', ', $field_set); $schema_insert = $sql_command . $insert_delayed . ' INTO ' . PMA_backquote($table, $sql_backquotes) . ' (' . $fields . ') VALUES '; } else { $schema_insert = $sql_command . $insert_delayed . ' INTO ' . PMA_backquote($table, $sql_backquotes) . ' VALUES '; } } $search = array("", "\n", "\r", ""); //\x08\\x09, not required $replace = array('\\0', '\\n', '\\r', '\\Z'); $current_row = 0; $query_size = 0; if (isset($GLOBALS['sql_extended']) && (!isset($GLOBALS['sql_type']) || $GLOBALS['sql_type'] != 'UPDATE')) { $separator = ','; $schema_insert .= $crlf; } else { $separator = ';'; } while ($row = PMA_DBI_fetch_row($result)) { $current_row++; for ($j = 0; $j < $fields_cnt; $j++) { // NULL if (!isset($row[$j]) || is_null($row[$j])) { $values[] = 'NULL'; // a number // timestamp is numeric on some MySQL 4.1, BLOBs are sometimes numeric } elseif ($fields_meta[$j]->numeric && $fields_meta[$j]->type != 'timestamp' && !$fields_meta[$j]->blob) { $values[] = $row[$j]; // a binary field // Note: with mysqli, under MySQL 4.1.3, we get the flag // "binary" for those field types (I don't know why) } elseif (stristr($field_flags[$j], 'BINARY') && isset($GLOBALS['sql_hex_for_binary']) && $fields_meta[$j]->type != 'datetime' && $fields_meta[$j]->type != 'date' && $fields_meta[$j]->type != 'time' && $fields_meta[$j]->type != 'timestamp') { // empty blobs need to be different, but '0' is also empty :-( if (empty($row[$j]) && $row[$j] != '0') { $values[] = '\'\''; } else { $values[] = '0x' . bin2hex($row[$j]); } // something else -> treat as a string } else { $values[] = '\'' . str_replace($search, $replace, PMA_sqlAddslashes($row[$j])) . '\''; } // end if } // end for // should we make update? if (isset($GLOBALS['sql_type']) && $GLOBALS['sql_type'] == 'UPDATE') { $insert_line = $schema_insert; for ($i = 0; $i < $fields_cnt; $i++) { if ($i > 0) { $insert_line .= ', '; } $insert_line .= $field_set[$i] . ' = ' . $values[$i]; } $insert_line .= ' WHERE ' . PMA_getUniqueCondition($result, $fields_cnt, $fields_meta, $row); } else { // Extended inserts case if (isset($GLOBALS['sql_extended'])) { if ($current_row == 1) { $insert_line = $schema_insert . '(' . implode(', ', $values) . ')'; } else { $insert_line = '(' . implode(', ', $values) . ')'; if (isset($GLOBALS['sql_max_query_size']) && $GLOBALS['sql_max_query_size'] > 0 && $query_size + strlen($insert_line) > $GLOBALS['sql_max_query_size']) { if (!PMA_exportOutputHandler(';' . $crlf)) { return FALSE; } $query_size = 0; $current_row = 1; $insert_line = $schema_insert . $insert_line; } } $query_size += strlen($insert_line); } else { $insert_line = $schema_insert . '(' . implode(', ', $values) . ')'; } } unset($values); if (!PMA_exportOutputHandler(($current_row == 1 ? '' : $separator . $crlf) . $insert_line)) { return FALSE; } } // end while if ($current_row > 0) { if (!PMA_exportOutputHandler(';' . $crlf)) { return FALSE; } } } // end if ($result != FALSE) PMA_DBI_free_result($result); return TRUE; }
/** * Outputs the content of a table in ODS format * * @param string $db database name * @param string $table table name * @param string $crlf the end of line sequence * @param string $error_url the url to go back in case of error * @param string $sql_query SQL query for obtaining data * @return bool Whether it succeeded * * @access public */ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) { global $what; // Gets the data from the database $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); $fields_cnt = PMA_DBI_num_fields($result); $fields_meta = PMA_DBI_get_fields_meta($result); $field_flags = array(); for ($j = 0; $j < $fields_cnt; $j++) { $field_flags[$j] = PMA_DBI_field_flags($result, $j); } $GLOBALS['ods_buffer'] .= '<table:table table:name="' . htmlspecialchars($table) . '">'; // If required, get fields name at the first line if (isset($GLOBALS[$what . '_columns'])) { $GLOBALS['ods_buffer'] .= '<table:table-row>'; for ($i = 0; $i < $fields_cnt; $i++) { $GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars(stripslashes(PMA_DBI_field_name($result, $i))) . '</text:p>' . '</table:table-cell>'; } // end for $GLOBALS['ods_buffer'] .= '</table:table-row>'; } // end if // Format the data while ($row = PMA_DBI_fetch_row($result)) { $GLOBALS['ods_buffer'] .= '<table:table-row>'; for ($j = 0; $j < $fields_cnt; $j++) { if (!isset($row[$j]) || is_null($row[$j])) { $GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars($GLOBALS[$what . '_null']) . '</text:p>' . '</table:table-cell>'; // ignore BLOB } elseif (stristr($field_flags[$j], 'BINARY') && $fields_meta[$j]->blob) { $GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p></text:p>' . '</table:table-cell>'; } elseif ($fields_meta[$j]->type == "date") { $GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="date" office:date-value="' . date("Y-m-d", strtotime($row[$j])) . '" table:style-name="DateCell">' . '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>' . '</table:table-cell>'; } elseif ($fields_meta[$j]->type == "time") { $GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="time" office:time-value="' . date("\\P\\TH\\Hi\\Ms\\S", strtotime($row[$j])) . '" table:style-name="TimeCell">' . '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>' . '</table:table-cell>'; } elseif ($fields_meta[$j]->type == "datetime") { $GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="date" office:date-value="' . date("Y-m-d\\TH:i:s", strtotime($row[$j])) . '" table:style-name="DateTimeCell">' . '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>' . '</table:table-cell>'; } elseif ($fields_meta[$j]->numeric && $fields_meta[$j]->type != 'timestamp' && !$fields_meta[$j]->blob) { $GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="float" office:value="' . $row[$j] . '" >' . '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>' . '</table:table-cell>'; } else { $GLOBALS['ods_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>' . '</table:table-cell>'; } } // end for $GLOBALS['ods_buffer'] .= '</table:table-row>'; } // end while PMA_DBI_free_result($result); $GLOBALS['ods_buffer'] .= '</table:table>'; return true; }
function PMA_DBI_get_fields_meta($result) { // Build an associative array for a type look up $typeAr = array(); $typeAr[MYSQLI_TYPE_DECIMAL] = 'real'; $typeAr[MYSQLI_TYPE_NEWDECIMAL] = 'real'; $typeAr[MYSQLI_TYPE_BIT] = 'bool'; $typeAr[MYSQLI_TYPE_TINY] = 'int'; $typeAr[MYSQLI_TYPE_SHORT] = 'int'; $typeAr[MYSQLI_TYPE_LONG] = 'int'; $typeAr[MYSQLI_TYPE_FLOAT] = 'real'; $typeAr[MYSQLI_TYPE_DOUBLE] = 'real'; $typeAr[MYSQLI_TYPE_NULL] = 'null'; $typeAr[MYSQLI_TYPE_TIMESTAMP] = 'timestamp'; $typeAr[MYSQLI_TYPE_LONGLONG] = 'int'; $typeAr[MYSQLI_TYPE_INT24] = 'int'; $typeAr[MYSQLI_TYPE_DATE] = 'date'; $typeAr[MYSQLI_TYPE_TIME] = 'time'; $typeAr[MYSQLI_TYPE_DATETIME] = 'datetime'; $typeAr[MYSQLI_TYPE_YEAR] = 'year'; $typeAr[MYSQLI_TYPE_NEWDATE] = 'date'; $typeAr[MYSQLI_TYPE_ENUM] = 'unknown'; $typeAr[MYSQLI_TYPE_SET] = 'unknown'; $typeAr[MYSQLI_TYPE_TINY_BLOB] = 'blob'; $typeAr[MYSQLI_TYPE_MEDIUM_BLOB] = 'blob'; $typeAr[MYSQLI_TYPE_LONG_BLOB] = 'blob'; $typeAr[MYSQLI_TYPE_BLOB] = 'blob'; $typeAr[MYSQLI_TYPE_VAR_STRING] = 'string'; $typeAr[MYSQLI_TYPE_STRING] = 'string'; $typeAr[MYSQLI_TYPE_CHAR] = 'string'; $typeAr[MYSQLI_TYPE_GEOMETRY] = 'unknown'; $fields = mysqli_fetch_fields($result); // this happens sometimes (seen under MySQL 4.0.25) if (!is_array($fields)) { return FALSE; } foreach ($fields as $k => $field) { $fields[$k]->type = $typeAr[$fields[$k]->type]; $fields[$k]->flags = PMA_DBI_field_flags($result, $k); // Enhance the field objects for mysql-extension compatibilty $flags = explode(' ', $fields[$k]->flags); array_unshift($flags, 'dummy'); $fields[$k]->multiple_key = (int) (array_search('multiple_key', $flags, true) > 0); $fields[$k]->primary_key = (int) (array_search('primary_key', $flags, true) > 0); $fields[$k]->unique_key = (int) (array_search('unique_key', $flags, true) > 0); $fields[$k]->not_null = (int) (array_search('not_null', $flags, true) > 0); $fields[$k]->unsigned = (int) (array_search('unsigned', $flags, true) > 0); $fields[$k]->zerofill = (int) (array_search('zerofill', $flags, true) > 0); $fields[$k]->numeric = (int) (array_search('num', $flags, true) > 0); $fields[$k]->blob = (int) (array_search('blob', $flags, true) > 0); } return $fields; }
/** * Displays the body of the results table * * @param integer the link id associated to the query which results have * to be displayed * @param array which elements to display * @param array the list of relations * @param array the analyzed query * * @return boolean always true * * @global string $db the database name * @global string $table the table name * @global string $goto the url to go back in case of errors * @global 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 $pos the current position in results * @global integer $session_max_rows the maximum number of rows per page * @global array $fields_meta the list of fields properties * @global integer $fields_cnt the total number of fields returned by * the sql query * @global array $vertical_display informations used with vertical display * mode * @global string $disp_direction the display mode * (horizontal/vertical/horizontalflipped) * @global integer $repeat_cells the number of row to display between two * table headers * @global array $highlight_columns collumn names to highlight * @gloabl array $row current row data * * @access private * * @see PMA_displayTable() */ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) { global $db, $table, $goto, $dontlimitchars; global $sql_query, $pos, $session_max_rows, $fields_meta, $fields_cnt; global $vertical_display, $disp_direction, $repeat_cells, $highlight_columns; global $row; // mostly because of browser transformations, to make the row-data accessible in a plugin $url_sql_query = $sql_query; // query without conditions to shorten urls when needed, 200 is just // guess, it should depend on remaining url length if (isset($analyzed_sql) && isset($analyzed_sql[0]) && isset($analyzed_sql[0]['querytype']) && $analyzed_sql[0]['querytype'] == 'SELECT' && strlen($sql_query) > 200) { $url_sql_query = 'SELECT '; if (isset($analyzed_sql[0]['queryflags']['distinct'])) { $url_sql_query .= ' DISTINCT '; } $url_sql_query .= $analyzed_sql[0]['select_expr_clause']; if (!empty($analyzed_sql[0]['from_clause'])) { $url_sql_query .= ' FROM ' . $analyzed_sql[0]['from_clause']; } } if (!is_array($map)) { $map = array(); } $row_no = 0; $vertical_display['edit'] = array(); $vertical_display['delete'] = array(); $vertical_display['data'] = array(); $vertical_display['row_delete'] = array(); // Correction uva 19991216 in the while below // Previous code assumed that all tables have keys, specifically that // the phpMyAdmin GUI should support row delete/edit only for such // tables. // Although always using keys is arguably the prescribed way of // defining a relational table, it is not required. This will in // particular be violated by the novice. // We want to encourage phpMyAdmin usage by such novices. So the code // below has been changed to conditionally work as before when the // table being displayed has one or more keys; but to display // delete/edit options correctly for tables without keys. // loic1: use 'PMA_mysql_fetch_array' rather than 'PMA_mysql_fetch_row' // to get the NULL values // rabus: This function needs a little rework. // Using MYSQL_BOTH just pollutes the memory! // ne0x: Use function PMA_DBI_fetch_array() due to mysqli // compatibility. Now this function is wrapped. $odd_row = true; while ($row = PMA_DBI_fetch_row($dt_result)) { // lem9: "vertical display" mode stuff if ($row_no != 0 && $repeat_cells != 0 && !($row_no % $repeat_cells) && ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped')) { echo '<tr>' . "\n"; if ($vertical_display['emptypre'] > 0) { echo ' <th colspan="' . $vertical_display['emptypre'] . '">' . "\n" . ' </th>' . "\n"; } foreach ($vertical_display['desc'] as $val) { echo $val; } if ($vertical_display['emptyafter'] > 0) { echo ' <th colspan="' . $vertical_display['emptyafter'] . '">' . "\n" . ' </th>' . "\n"; } echo '</tr>' . "\n"; } // end if $class = $odd_row ? 'odd' : 'even'; $odd_row = !$odd_row; if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') { // loic1: pointer code part echo ' <tr class="' . $class . '">' . "\n"; $class = ''; } // 1. Prepares the row (gets primary keys to use) // 1.1 Results from a "SELECT" statement -> builds the // "primary" key to use in links $uva_condition = urlencode(PMA_getUvaCondition($dt_result, $fields_cnt, $fields_meta, $row)); // 1.2 Defines the urls for the modify/delete link(s) $url_query = PMA_generate_common_url($db, $table) . '&pos=' . $pos . '&session_max_rows=' . $session_max_rows . '&disp_direction=' . $disp_direction . '&repeat_cells=' . $repeat_cells . '&dontlimitchars=' . $dontlimitchars; if ($is_display['edit_lnk'] != 'nn' || $is_display['del_lnk'] != 'nn') { // We need to copy the value or else the == 'both' check will always return true if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') { $iconic_spacer = '<div class="nowrap">'; } else { $iconic_spacer = ''; } // 1.2.1 Modify link(s) if ($is_display['edit_lnk'] == 'ur') { // update row case $lnk_goto = 'sql.php'; $edit_url = 'tbl_change.php' . '?' . $url_query . '&primary_key=' . $uva_condition . '&sql_query=' . urlencode($url_sql_query) . '&goto=' . urlencode($lnk_goto); if ($GLOBALS['cfg']['PropertiesIconic'] === false) { $edit_str = $GLOBALS['strEdit']; } else { $edit_str = $iconic_spacer . '<img class="icon" width="16" height="16" src="' . $GLOBALS['pmaThemeImage'] . 'b_edit.png" alt="' . $GLOBALS['strEdit'] . '" title="' . $GLOBALS['strEdit'] . '" />'; if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') { $edit_str .= ' ' . $GLOBALS['strEdit'] . '</div>'; } } } // end if (1.2.1) if ($table == $GLOBALS['cfg']['Bookmark']['table'] && $db == $GLOBALS['cfg']['Bookmark']['db'] && isset($row[1]) && isset($row[0])) { $bookmark_go = '<a href="import.php?' . PMA_generate_common_url($row[1], '') . '&id_bookmark=' . $row[0] . '&action_bookmark=0' . '&action_bookmark_all=1' . '&SQL=' . $GLOBALS['strExecuteBookmarked'] . ' " title="' . $GLOBALS['strExecuteBookmarked'] . '">'; if ($GLOBALS['cfg']['PropertiesIconic'] === false) { $bookmark_go .= $GLOBALS['strExecuteBookmarked']; } else { $bookmark_go .= $iconic_spacer . '<img class="icon" width="16" height="16" src="' . $GLOBALS['pmaThemeImage'] . 'b_bookmark.png" alt="' . $GLOBALS['strExecuteBookmarked'] . '" title="' . $GLOBALS['strExecuteBookmarked'] . '" />'; if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') { $bookmark_go .= ' ' . $GLOBALS['strExecuteBookmarked'] . '</div>'; } } $bookmark_go .= '</a>'; } else { $bookmark_go = ''; } // 1.2.2 Delete/Kill link(s) if ($is_display['del_lnk'] == 'dr') { // delete row case $lnk_goto = 'sql.php' . '?' . str_replace('&', '&', $url_query) . '&sql_query=' . urlencode($url_sql_query) . '&zero_rows=' . urlencode(htmlspecialchars($GLOBALS['strDeleted'])) . '&goto=' . (empty($goto) ? 'tbl_properties.php' : $goto); $del_query = urlencode('DELETE FROM ' . PMA_backquote($table) . ' WHERE') . $uva_condition . '+LIMIT+1'; $del_url = 'sql.php' . '?' . $url_query . '&sql_query=' . $del_query . '&zero_rows=' . urlencode(htmlspecialchars($GLOBALS['strDeleted'])) . '&goto=' . urlencode($lnk_goto); $js_conf = 'DELETE FROM ' . PMA_jsFormat($table) . ' WHERE ' . trim(PMA_jsFormat(urldecode($uva_condition), false)) . ' LIMIT 1'; if ($GLOBALS['cfg']['PropertiesIconic'] === false) { $del_str = $GLOBALS['strDelete']; } else { $del_str = $iconic_spacer . '<img class="icon" width="16" height="16" src="' . $GLOBALS['pmaThemeImage'] . 'b_drop.png" alt="' . $GLOBALS['strDelete'] . '" title="' . $GLOBALS['strDelete'] . '" />'; if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') { $del_str .= ' ' . $GLOBALS['strDelete'] . '</div>'; } } } elseif ($is_display['del_lnk'] == 'kp') { // kill process case $lnk_goto = 'sql.php' . '?' . str_replace('&', '&', $url_query) . '&sql_query=' . urlencode($url_sql_query) . '&goto=main.php'; $del_url = 'sql.php?' . PMA_generate_common_url('mysql') . '&sql_query=' . urlencode('KILL ' . $row[0]) . '&goto=' . urlencode($lnk_goto); $del_query = urlencode('KILL ' . $row[0]); $js_conf = 'KILL ' . $row[0]; if ($GLOBALS['cfg']['PropertiesIconic'] === false) { $del_str = $GLOBALS['strKill']; } else { $del_str = $iconic_spacer . '<img class="icon" width="16" height="16" src="' . $GLOBALS['pmaThemeImage'] . 'b_drop.png" alt="' . $GLOBALS['strKill'] . '" title="' . $GLOBALS['strKill'] . '" />'; if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') { $del_str .= ' ' . $GLOBALS['strKill'] . '</div>'; } } } // end if (1.2.2) // 1.3 Displays the links at left if required if ($GLOBALS['cfg']['ModifyDeleteAtLeft'] && ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped')) { $doWriteModifyAt = 'left'; require './libraries/display_tbl_links.lib.php'; } // end if (1.3) } // end if (1) // 2. Displays the rows' values for ($i = 0; $i < $fields_cnt; ++$i) { $meta = $fields_meta[$i]; // loic1: To fix bug #474943 under php4, the row pointer will // depend on whether the "is_null" php4 function is // available or not $pointer = function_exists('is_null') ? $i : $meta->name; // garvin: See if this column should get highlight because it's used in the // where-query. if (isset($highlight_columns) && (isset($highlight_columns[$meta->name]) || isset($highlight_columns[PMA_backquote($meta->name)]))) { $condition_field = true; } else { $condition_field = false; } $mouse_events = ''; if ($disp_direction == 'vertical' && (!isset($GLOBALS['printview']) || $GLOBALS['printview'] != '1')) { if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) { $mouse_events .= ' onmouseover="setVerticalPointer(this, ' . $row_no . ', \'over\', \'odd\', \'even\', \'hover\', \'marked\');"' . ' onmouseout="setVerticalPointer(this, ' . $row_no . ', \'out\', \'odd\', \'even\', \'hover\', \'marked\');" '; } if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) { $mouse_events .= ' onmousedown="setVerticalPointer(this, ' . $row_no . ', \'click\', \'odd\', \'even\', \'hover\', \'marked\'); setCheckboxColumn(\'id_rows_to_delete' . $row_no . '\');" '; } else { $mouse_events .= ' onmousedown="setCheckboxColumn(\'id_rows_to_delete' . $row_no . '\');" '; } } // end if // garvin: Wrap MIME-transformations. [MIME] $default_function = 'default_function'; // default_function $transform_function = $default_function; $transform_options = array(); if ($GLOBALS['cfgRelation']['mimework'] && $GLOBALS['cfg']['BrowseMIME']) { if (isset($GLOBALS['mime_map'][$meta->name]['mimetype']) && isset($GLOBALS['mime_map'][$meta->name]['transformation']) && !empty($GLOBALS['mime_map'][$meta->name]['transformation'])) { $include_file = PMA_sanitizeTransformationFile($GLOBALS['mime_map'][$meta->name]['transformation']); if (file_exists('./libraries/transformations/' . $include_file)) { $transformfunction_name = preg_replace('@(\\.inc\\.php3?)$@i', '', $GLOBALS['mime_map'][$meta->name]['transformation']); require_once './libraries/transformations/' . $include_file; if (function_exists('PMA_transformation_' . $transformfunction_name)) { $transform_function = 'PMA_transformation_' . $transformfunction_name; $transform_options = PMA_transformation_getOptions(isset($GLOBALS['mime_map'][$meta->name]['transformation_options']) ? $GLOBALS['mime_map'][$meta->name]['transformation_options'] : ''); $meta->mimetype = str_replace('_', '/', $GLOBALS['mime_map'][$meta->name]['mimetype']); } } // end if file_exists } // end if transformation is set } // end if mime/transformation works. $transform_options['wrapper_link'] = '?' . (isset($url_query) ? $url_query : '') . '&primary_key=' . (isset($uva_condition) ? $uva_condition : '') . '&sql_query=' . (isset($sql_query) ? urlencode($url_sql_query) : '') . '&goto=' . (isset($sql_goto) ? urlencode($lnk_goto) : '') . '&transform_key=' . urlencode($meta->name); // n u m e r i c if ($meta->numeric == 1) { // lem9: if two fields have the same name (this is possible // with self-join queries, for example), using $meta->name // will show both fields NULL even if only one is NULL, // so use the $pointer // (works only if function_exists('is_null') // PS: why not always work with the number ($i), since // the default second parameter of // mysql_fetch_array() is MYSQL_BOTH, so we always get // associative and numeric indices? //if (!isset($row[$meta->name]) if (!isset($row[$i]) || is_null($row[$i])) { $vertical_display['data'][$row_no][$i] = ' <td align="right"' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"><i>NULL</i></td>' . "\n"; } elseif ($row[$i] != '') { $vertical_display['data'][$row_no][$i] = ' <td align="right"' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . ' nowrap">'; if (isset($analyzed_sql[0]['select_expr']) && is_array($analyzed_sql[0]['select_expr'])) { foreach ($analyzed_sql[0]['select_expr'] as $select_expr_position => $select_expr) { $alias = $analyzed_sql[0]['select_expr'][$select_expr_position]['alias']; if (isset($alias) && strlen($alias)) { $true_column = $analyzed_sql[0]['select_expr'][$select_expr_position]['column']; if ($alias == $meta->name) { $meta->name = $true_column; } // end if } // end if } // end while } if (isset($map[$meta->name])) { // Field to display from the foreign table? if (isset($map[$meta->name][2]) && strlen($map[$meta->name][2])) { $dispsql = 'SELECT ' . PMA_backquote($map[$meta->name][2]) . ' FROM ' . PMA_backquote($map[$meta->name][3]) . '.' . PMA_backquote($map[$meta->name][0]) . ' WHERE ' . PMA_backquote($map[$meta->name][1]) . ' = ' . $row[$i]; $dispresult = PMA_DBI_try_query($dispsql, null, PMA_DBI_QUERY_STORE); if ($dispresult && PMA_DBI_num_rows($dispresult) > 0) { list($dispval) = PMA_DBI_fetch_row($dispresult, 0); } else { $dispval = $GLOBALS['strLinkNotFound']; } @PMA_DBI_free_result($dispresult); } else { $dispval = ''; } // end if... else... if (isset($GLOBALS['printview']) && $GLOBALS['printview'] == '1') { $vertical_display['data'][$row_no][$i] .= ($transform_function != $default_function ? $transform_function($row[$i], $transform_options, $meta) : $transform_function($row[$i], array(), $meta)) . ' <code>[->' . $dispval . ']</code>'; } else { $title = !empty($dispval) ? ' title="' . htmlspecialchars($dispval) . '"' : ''; $vertical_display['data'][$row_no][$i] .= '<a href="sql.php?' . PMA_generate_common_url($map[$meta->name][3], $map[$meta->name][0]) . '&pos=0&session_max_rows=' . $session_max_rows . '&dontlimitchars=' . $dontlimitchars . '&sql_query=' . urlencode('SELECT * FROM ' . PMA_backquote($map[$meta->name][0]) . ' WHERE ' . PMA_backquote($map[$meta->name][1]) . ' = ' . $row[$i]) . '"' . $title . '>' . ($transform_function != $default_function ? $transform_function($row[$i], $transform_options, $meta) : $transform_function($row[$i], array(), $meta)) . '</a>'; } } else { $vertical_display['data'][$row_no][$i] .= $transform_function != $default_function ? $transform_function($row[$i], $transform_options, $meta) : $transform_function($row[$i], array(), $meta); } $vertical_display['data'][$row_no][$i] .= '</td>' . "\n"; } else { $vertical_display['data'][$row_no][$i] = ' <td align="right"' . $mouse_events . ' class="' . $class . ' nowrap' . ($condition_field ? ' condition' : '') . '"> </td>' . "\n"; } // b l o b } elseif ($GLOBALS['cfg']['ShowBlob'] == false && stristr($meta->type, 'BLOB')) { // loic1 : PMA_mysql_fetch_fields returns BLOB in place of // TEXT fields type, however TEXT fields must be displayed // even if $GLOBALS['cfg']['ShowBlob'] is false -> get the true type // of the fields. $field_flags = PMA_DBI_field_flags($dt_result, $i); if (stristr($field_flags, 'BINARY')) { $blobtext = '[BLOB'; if (!isset($row[$i]) || is_null($row[$i])) { $blobtext .= ' - NULL'; $blob_size = 0; } elseif (isset($row[$i])) { $blob_size = strlen($row[$i]); $display_blob_size = PMA_formatByteDown($blob_size, 3, 1); $blobtext .= ' - ' . $display_blob_size[0] . ' ' . $display_blob_size[1]; unset($display_blob_size); } $blobtext .= ']'; if (strpos($transform_function, 'octetstream')) { $blobtext = $row[$i]; } if ($blob_size > 0) { $blobtext = $default_function != $transform_function ? $transform_function($blobtext, $transform_options, $meta) : $default_function($blobtext, array(), $meta); } unset($blob_size); $vertical_display['data'][$row_no][$i] = ' <td align="left"' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '">' . $blobtext . '</td>'; } else { if (!isset($row[$i]) || is_null($row[$i])) { $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"><i>NULL</i></td>' . "\n"; } elseif ($row[$i] != '') { // garvin: if a transform function for blob is set, none of these replacements will be made if (PMA_strlen($row[$i]) > $GLOBALS['cfg']['LimitChars'] && $dontlimitchars != 1) { $row[$i] = PMA_substr($row[$i], 0, $GLOBALS['cfg']['LimitChars']) . '...'; } // loic1: displays all space characters, 4 space // characters for tabulations and <cr>/<lf> $row[$i] = $default_function != $transform_function ? $transform_function($row[$i], $transform_options, $meta) : $default_function($row[$i], array(), $meta); $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '">' . $row[$i] . '</td>' . "\n"; } else { $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"> </td>' . "\n"; } } } else { if (!isset($row[$i]) || is_null($row[$i])) { $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"><i>NULL</i></td>' . "\n"; } elseif ($row[$i] != '') { // loic1: support blanks in the key $relation_id = $row[$i]; // nijel: Cut all fields to $GLOBALS['cfg']['LimitChars'] // lem9: (unless it's a link-type transformation) if (PMA_strlen($row[$i]) > $GLOBALS['cfg']['LimitChars'] && $dontlimitchars != 1 && !strpos($transform_function, 'link') === true) { $row[$i] = PMA_substr($row[$i], 0, $GLOBALS['cfg']['LimitChars']) . '...'; } // loic1: displays special characters from binaries $field_flags = PMA_DBI_field_flags($dt_result, $i); if (stristr($field_flags, 'BINARY')) { $row[$i] = str_replace("", '\\0', $row[$i]); $row[$i] = str_replace("", '\\b', $row[$i]); $row[$i] = str_replace("\n", '\\n', $row[$i]); $row[$i] = str_replace("\r", '\\r', $row[$i]); $row[$i] = str_replace("", '\\Z', $row[$i]); $row[$i] = $default_function != $transform_function ? $transform_function($row[$i], $transform_options, $meta) : $default_function($row[$i], array(), $meta); } else { $row[$i] = $default_function != $transform_function ? $transform_function($row[$i], $transform_options, $meta) : $default_function($row[$i], array(), $meta); } // garvin: transform functions may enable nowrapping: $function_nowrap = $transform_function . '_nowrap'; $bool_nowrap = $default_function != $transform_function && function_exists($function_nowrap) ? $function_nowrap($transform_options) : false; // loic1: do not wrap if date field type $nowrap = preg_match('@DATE|TIME@i', $meta->type) || $bool_nowrap ? ' nowrap' : ''; $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . $nowrap . ($condition_field ? ' condition' : '') . '">'; if (isset($analyzed_sql[0]['select_expr']) && is_array($analyzed_sql[0]['select_expr'])) { foreach ($analyzed_sql[0]['select_expr'] as $select_expr_position => $select_expr) { $alias = $analyzed_sql[0]['select_expr'][$select_expr_position]['alias']; if (isset($alias) && strlen($alias)) { $true_column = $analyzed_sql[0]['select_expr'][$select_expr_position]['column']; if ($alias == $meta->name) { $meta->name = $true_column; } // end if } // end if } // end while } if (isset($map[$meta->name])) { // Field to display from the foreign table? if (isset($map[$meta->name][2]) && strlen($map[$meta->name][2])) { $dispsql = 'SELECT ' . PMA_backquote($map[$meta->name][2]) . ' FROM ' . PMA_backquote($map[$meta->name][3]) . '.' . PMA_backquote($map[$meta->name][0]) . ' WHERE ' . PMA_backquote($map[$meta->name][1]) . ' = \'' . PMA_sqlAddslashes($row[$i]) . '\''; $dispresult = PMA_DBI_try_query($dispsql, null, PMA_DBI_QUERY_STORE); if ($dispresult && PMA_DBI_num_rows($dispresult) > 0) { list($dispval) = PMA_DBI_fetch_row($dispresult); @PMA_DBI_free_result($dispresult); } else { $dispval = $GLOBALS['strLinkNotFound']; } } else { $dispval = ''; } $title = !empty($dispval) ? ' title="' . htmlspecialchars($dispval) . '"' : ''; $vertical_display['data'][$row_no][$i] .= '<a href="sql.php?' . PMA_generate_common_url($map[$meta->name][3], $map[$meta->name][0]) . '&pos=0&session_max_rows=' . $session_max_rows . '&dontlimitchars=' . $dontlimitchars . '&sql_query=' . urlencode('SELECT * FROM ' . PMA_backquote($map[$meta->name][0]) . ' WHERE ' . PMA_backquote($map[$meta->name][1]) . ' = \'' . PMA_sqlAddslashes($relation_id) . '\'') . '"' . $title . '>' . $row[$i] . '</a>'; } else { $vertical_display['data'][$row_no][$i] .= $row[$i]; } $vertical_display['data'][$row_no][$i] .= '</td>' . "\n"; } else { $vertical_display['data'][$row_no][$i] = ' <td' . $mouse_events . ' class="' . $class . ($condition_field ? ' condition' : '') . '"> </td>' . "\n"; } } // lem9: output stored cell if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') { echo $vertical_display['data'][$row_no][$i]; } if (isset($vertical_display['rowdata'][$i][$row_no])) { $vertical_display['rowdata'][$i][$row_no] .= $vertical_display['data'][$row_no][$i]; } else { $vertical_display['rowdata'][$i][$row_no] = $vertical_display['data'][$row_no][$i]; } } // end for (2) // 3. Displays the modify/delete links on the right if required if ($GLOBALS['cfg']['ModifyDeleteAtRight'] && ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped')) { $doWriteModifyAt = 'right'; require './libraries/display_tbl_links.lib.php'; } // end if (3) if ($disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped') { ?> </tr> <?php } // end if // 4. Gather links of del_urls and edit_urls in an array for later // output if (!isset($vertical_display['edit'][$row_no])) { $vertical_display['edit'][$row_no] = ''; $vertical_display['delete'][$row_no] = ''; $vertical_display['row_delete'][$row_no] = ''; } $column_style_vertical = ''; if ($GLOBALS['cfg']['BrowsePointerEnable'] == true) { $column_style_vertical .= ' onmouseover="setVerticalPointer(this, ' . $row_no . ', \'over\', \'odd\', \'even\', \'hover\', \'marked\');"' . ' onmouseout="setVerticalPointer(this, ' . $row_no . ', \'out\', \'odd\', \'even\', \'hover\', \'marked\');"'; } $column_marker_vertical = ''; if ($GLOBALS['cfg']['BrowseMarkerEnable'] == true) { $column_marker_vertical .= 'setVerticalPointer(this, ' . $row_no . ', \'click\', \'odd\', \'even\', \'hover\', \'marked\');'; } if (!empty($del_url) && $is_display['del_lnk'] != 'kp') { $vertical_display['row_delete'][$row_no] .= ' <td align="center" class="' . $class . '" ' . $column_style_vertical . '>' . "\n" . ' <input type="checkbox" id="id_rows_to_delete' . $row_no . '[%_PMA_CHECKBOX_DIR_%]" name="rows_to_delete[' . $uva_condition . ']"' . ' onclick="' . $column_marker_vertical . 'copyCheckboxesRange(\'rowsDeleteForm\', \'id_rows_to_delete' . $row_no . '\',\'[%_PMA_CHECKBOX_DIR_%]\');"' . ' value="' . $del_query . '" ' . (isset($GLOBALS['checkall']) ? 'checked="checked"' : '') . ' />' . "\n" . ' </td>' . "\n"; } else { unset($vertical_display['row_delete'][$row_no]); } if (isset($edit_url)) { $vertical_display['edit'][$row_no] .= ' <td align="center" class="' . $class . '" ' . $column_style_vertical . '>' . "\n" . PMA_linkOrButton($edit_url, $edit_str, array(), false) . $bookmark_go . ' </td>' . "\n"; } else { unset($vertical_display['edit'][$row_no]); } if (isset($del_url)) { $vertical_display['delete'][$row_no] .= ' <td align="center" class="' . $class . '" ' . $column_style_vertical . '>' . "\n" . PMA_linkOrButton($del_url, $del_str, isset($js_conf) ? $js_conf : '', false) . ' </td>' . "\n"; } else { unset($vertical_display['delete'][$row_no]); } echo $disp_direction == 'horizontal' || $disp_direction == 'horizontalflipped' ? "\n" : ''; $row_no++; } // end while if (isset($url_query)) { $GLOBALS['url_query'] = $url_query; } return true; }
/** * Outputs the content of a table in CSV format * * @param string the database name * @param string the table name * @param string the end of line sequence * @param string the url to go back in case of error * @param string SQL query for obtaining data * * @return bool Whether it suceeded * * @access public */ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) { global $what; // Gets the data from the database $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); $fields_cnt = PMA_DBI_num_fields($result); $fields_meta = PMA_DBI_get_fields_meta($result); $field_flags = array(); for ($j = 0; $j < $fields_cnt; $j++) { $field_flags[$j] = PMA_DBI_field_flags($result, $j); } $GLOBALS['odt_buffer'] .= '<text:h text:outline-level="2" text:style-name="Heading_2" text:is-list-header="true">' . htmlspecialchars(__('Dumping data for table') . ' ' . $table) . '</text:h>'; $GLOBALS['odt_buffer'] .= '<table:table table:name="' . htmlspecialchars($table) . '_structure">'; $GLOBALS['odt_buffer'] .= '<table:table-column table:number-columns-repeated="' . $fields_cnt . '"/>'; // If required, get fields name at the first line if (isset($GLOBALS[$what . '_columns'])) { $GLOBALS['odt_buffer'] .= '<table:table-row>'; for ($i = 0; $i < $fields_cnt; $i++) { $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars(stripslashes(PMA_DBI_field_name($result, $i))) . '</text:p>' . '</table:table-cell>'; } // end for $GLOBALS['odt_buffer'] .= '</table:table-row>'; } // end if // Format the data while ($row = PMA_DBI_fetch_row($result)) { $GLOBALS['odt_buffer'] .= '<table:table-row>'; for ($j = 0; $j < $fields_cnt; $j++) { if (!isset($row[$j]) || is_null($row[$j])) { $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars($GLOBALS[$what . '_null']) . '</text:p>' . '</table:table-cell>'; // ignore BLOB } elseif (stristr($field_flags[$j], 'BINARY') && $fields_meta[$j]->blob) { $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p></text:p>' . '</table:table-cell>'; } elseif ($fields_meta[$j]->numeric && $fields_meta[$j]->type != 'timestamp' && !$fields_meta[$j]->blob) { $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="float" office:value="' . $row[$j] . '" >' . '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>' . '</table:table-cell>'; } else { $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' . '<text:p>' . htmlspecialchars($row[$j]) . '</text:p>' . '</table:table-cell>'; } } // end for $GLOBALS['odt_buffer'] .= '</table:table-row>'; } // end while PMA_DBI_free_result($result); $GLOBALS['odt_buffer'] .= '</table:table>'; return TRUE; }
/** * Function to generate unique condition for specified row. * * @param resource handle for current query * @param integer number of fields * @param array meta information about fields * @param array current row * * @access public * @author Michal Cihar (michal@cihar.com) * @return string calculated condition */ function PMA_getUvaCondition($handle, $fields_cnt, $fields_meta, $row) { $primary_key = ''; $unique_key = ''; $uva_nonprimary_condition = ''; for ($i = 0; $i < $fields_cnt; ++$i) { $field_flags = PMA_DBI_field_flags($handle, $i); $meta = $fields_meta[$i]; // do not use an alias in a condition $column_for_condition = $meta->name; if (isset($analyzed_sql[0]['select_expr']) && is_array($analyzed_sql[0]['select_expr'])) { foreach ($analyzed_sql[0]['select_expr'] as $select_expr_position => $select_expr) { $alias = $analyzed_sql[0]['select_expr'][$select_expr_position]['alias']; if (!empty($alias)) { $true_column = $analyzed_sql[0]['select_expr'][$select_expr_position]['column']; if ($alias == $meta->name) { $column_for_condition = $true_column; } // end if } // end if } // end while } // to fix the bug where float fields (primary or not) // can't be matched because of the imprecision of // floating comparison, use CONCAT // (also, the syntax "CONCAT(field) IS NULL" // that we need on the next "if" will work) if ($meta->type == 'real') { $condition = ' CONCAT(' . PMA_backquote($column_for_condition) . ') '; } else { // string and blob fields have to be converted using // the system character set (always utf8) since // mysql4.1 can use different charset for fields. if (PMA_MYSQL_INT_VERSION >= 40100 && ($meta->type == 'string' || $meta->type == 'blob')) { $condition = ' CONVERT(' . PMA_backquote($column_for_condition) . ' USING utf8) '; } else { $condition = ' ' . PMA_backquote($column_for_condition) . ' '; } } // end if... else... if (!isset($row[$i]) || is_null($row[$i])) { $condition .= 'IS NULL AND'; } else { // timestamp is numeric on some MySQL 4.1 if ($meta->numeric && $meta->type != 'timestamp') { $condition .= '= ' . $row[$i] . ' AND'; } elseif ($meta->type == 'blob' && stristr($field_flags, 'BINARY') && !empty($row[$i])) { // use a CAST if possible, to avoid problems // if the field contains wildcard characters % or _ if (PMA_MYSQL_INT_VERSION < 40002) { $condition .= 'LIKE 0x' . bin2hex($row[$i]) . ' AND'; } else { $condition .= '= CAST(0x' . bin2hex($row[$i]) . ' AS BINARY) AND'; } } else { $condition .= '= \'' . PMA_sqlAddslashes($row[$i], FALSE, TRUE) . '\' AND'; } } if ($meta->primary_key > 0) { $primary_key .= $condition; } else { if ($meta->unique_key > 0) { $unique_key .= $condition; } } $uva_nonprimary_condition .= $condition; } // end for // Correction uva 19991216: prefer primary or unique keys // for condition, but use conjunction of all values if no // primary key if ($primary_key) { $uva_condition = $primary_key; } else { if ($unique_key) { $uva_condition = $unique_key; } else { $uva_condition = $uva_nonprimary_condition; } } return preg_replace('|\\s?AND$|', '', $uva_condition); }
function PMA_getTableContentFast($db, $table, $add_query = "", $handler, $exptype) { global $current_row, $rows_cnt, $crlf; // Поулучаем число записей, т.к mysql_num_rows не поддреживается с unbuffed_query $query = "SELECT COUNT(*) FROM " . PMA_backquote($db) . "." . PMA_backquote($table) . $add_query; $r = mysql_unbuffered_query($query); $rows_cnt = mysql_fetch_row($r); $rows_cnt = $rows_cnt[0]; mysql_free_result($r); $local_query = "SELECT * FROM " . PMA_backquote($db) . "." . PMA_backquote($table) . $add_query; $result = mysql_unbuffered_query($local_query) or die($local_query); if ($result != FALSE) { $fields_cnt = mysql_num_fields($result); //$rows_cnt = mysql_num_rows($result); // Get field information $fields_meta = PMA_DBI_get_fields_meta($result); $field_flags = array(); for ($j = 0; $j < $fields_cnt; $j++) { $field_flags[$j] = PMA_DBI_field_flags($result, $j); } // Checks whether the field is an integer or not for ($j = 0; $j < $fields_cnt; $j++) { $field_set[$j] = PMA_backquote(mysql_field_name($result, $j), $GLOBALS["_POST"]["use_backquotes"]); $type = mysql_field_type($result, $j); if (strpos($type, "int") !== false) { $field_num[$j] = TRUE; } else { $field_num[$j] = FALSE; } } // end for switch ($exptype) { case "einsert": if (isset($GLOBALS["_POST"]["showcolumns"])) { $fields = implode(", ", $field_set); $schema_insert = "INSERT INTO " . PMA_backquote($table, $GLOBALS["_POST"]["use_backquotes"]) . " (" . $fields . ") VALUES ("; } else { $schema_insert = "INSERT INTO " . PMA_backquote($table, $GLOBALS["_POST"]["use_backquotes"]) . " VALUES ("; } $mode = 'ins'; break; case "ereplace": if (isset($GLOBALS["_POST"]["showcolumns"])) { $fields = implode(", ", $field_set); $schema_insert = "REPLACE INTO " . PMA_backquote($table, $GLOBALS["_POST"]["use_backquotes"]) . " (" . $fields . ") VALUES ("; } else { $schema_insert = "REPLACE INTO " . PMA_backquote($table, $GLOBALS["_POST"]["use_backquotes"]) . " VALUES ("; } $mode = 'ins'; break; case "eupdate": $schema_insert = "UPDATE " . PMA_backquote($table, $GLOBALS["_POST"]["use_backquotes"]) . " SET "; $mode = 'upd'; $pkeys = array(); $npkeys = array(); for ($j = 0; $j < $fields_cnt; $j++) { if (strpos($field_flags[$j], 'primary_key') !== false) { $pkeys[$j] = $field_set[$j]; } else { $npkeys[$j] = $field_set[$j]; } } /*/////////////////////////////////////////////////////////////////////////// if (count($pkeys)<1) { pr($pkeys); pr($npkeys); pr($field_flags); die(); } */ break; } // Sets the scheme $search = array("", "\n", "\r", ""); //\x08\\x09, not required $replace = array("\\0", "\\n", "\\r", "\\Z"); $current_row = 0; // loic1: send a fake header to bypass browser timeout if data // are bufferized - part 1 if (!empty($GLOBALS["ob_mode"]) || (isset($GLOBALS["_POST"]["zip"]) || isset($GLOBALS["_POST"]["bzip"]) || isset($GLOBALS["_POST"]["gzip"]))) { $time0 = time(); } while ($row = mysql_fetch_row($result)) { $current_row++; for ($j = 0; $j < $fields_cnt; $j++) { if (!isset($row[$j])) { $values[] = "NULL"; } else { if ($row[$j] == "0" || $row[$j] != "") { // a number if ($field_num[$j]) { $values[] = $row[$j]; } else { $values[] = "'" . str_replace($search, $replace, PMA_sqlAddslashes($row[$j])) . "'"; } } else { $values[] = "''"; } } // end if } // end for if ($exptype != 'eupdate') { // Extended inserts case if (isset($GLOBALS["_POST"]["extended_ins"])) { if ($current_row == 1 || !($current_row % EXT_INC_COL)) { $insert_line = $schema_insert . implode(", ", $values) . ")"; } else { $insert_line = "(" . implode(", ", $values) . ")"; } } else { $insert_line = $schema_insert . implode(", ", $values) . ")"; } } else { $tmpnp = array(); $tmpp = array(); foreach ($npkeys as $k => $np) { $tmpnp[] = $np . ' = ' . $values[$k]; } foreach ($pkeys as $k => $pp) { $tmpp[] = $pp . ' = ' . $values[$k]; } $insert_line = $schema_insert . implode(', ', $tmpnp) . ' WHERE ' . implode(' AND ', $tmpp); unset($tmpnp); unset($tmpp); } unset($values); // Call the handler $handler($insert_line); // loic1: send a fake header to bypass browser timeout if data // are bufferized - part 2 if (isset($time0)) { $time1 = time(); if ($time1 >= $time0 + 1) { $time0 = $time1; echo ".\n\r"; flush(); ob_flush(); } } // end if } // end while } // end if ($result != FALSE) mysql_free_result($result); return TRUE; }