Translated using Weblate (Turkish)
[phpmyadmin.git] / libraries / structure.lib.php
blob9e616e40a26710d18954c72a726d73523e9bbb0c
1 <?php
3 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 /**
5 * set of functions for structure section in pma
7 * @package PhpMyAdmin
8 */
9 if (!defined('PHPMYADMIN')) {
10 exit;
13 /**
14 * Get the HTML links for action links
15 * Actions are, Browse, Search, Browse table label, empty table
17 * @param array $current_table current table
18 * @param boolean $table_is_view Is table view or not
19 * @param string $tbl_url_query table url query
20 * @param array $titles titles and icons for action links
21 * @param string $truename table name
22 * @param boolean $db_is_system_schema is database information schema or not
23 * @param string $url_query url query
25 * @return array ($browse_table, $search_table, $browse_table_label, $empty_table,
26 * $tracking_icon)
28 function PMA_getHtmlForActionLinks($current_table, $table_is_view, $tbl_url_query,
29 $titles, $truename, $db_is_system_schema, $url_query
30 ) {
31 $empty_table = '';
33 if ($current_table['TABLE_ROWS'] > 0 || $table_is_view) {
34 $may_have_rows = true;
35 } else {
36 $may_have_rows = false;
39 $browse_table = '<a href="sql.php?' . $tbl_url_query . '&amp;pos=0">';
40 if ($may_have_rows) {
41 $browse_table .= $titles['Browse'];
42 } else {
43 $browse_table .= $titles['NoBrowse'];
45 $browse_table .= '</a>';
47 $search_table = '<a href="tbl_select.php?' . $tbl_url_query . '">';
48 if ($may_have_rows) {
49 $search_table .= $titles['Search'];
50 } else {
51 $search_table .= $titles['NoSearch'];
53 $search_table .= '</a>';
55 $browse_table_label = '<a href="sql.php?' . $tbl_url_query
56 . '&amp;pos=0" title="'
57 . htmlspecialchars($current_table['TABLE_COMMENT']) . '">'
58 . $truename . '</a>';
60 if (!$db_is_system_schema) {
61 $empty_table = '<a class="truncate_table_anchor ajax"';
62 $empty_table .= ' href="sql.php?' . $tbl_url_query
63 . '&amp;sql_query=';
64 $empty_table .= urlencode(
65 'TRUNCATE ' . PMA_Util::backquote($current_table['TABLE_NAME'])
67 $empty_table .= '&amp;message_to_show='
68 . urlencode(
69 sprintf(
70 __('Table %s has been emptied.'),
71 htmlspecialchars($current_table['TABLE_NAME'])
74 . '">';
75 if ($may_have_rows) {
76 $empty_table .= $titles['Empty'];
77 } else {
78 $empty_table .= $titles['NoEmpty'];
80 $empty_table .= '</a>';
81 // truncating views doesn't work
82 if ($table_is_view) {
83 $empty_table = '&nbsp;';
87 $tracking_icon = '';
88 if (PMA_Tracker::isActive()) {
89 if (PMA_Tracker::isTracked($GLOBALS["db"], $truename)) {
90 $tracking_icon = '<a href="tbl_tracking.php?' . $url_query
91 . '&amp;table=' . $truename . '">'
92 . PMA_Util::getImage(
93 'eye.png', __('Tracking is active.')
95 . '</a>';
96 } elseif (PMA_Tracker::getVersion($GLOBALS["db"], $truename) > 0) {
97 $tracking_icon = '<a href="tbl_tracking.php?' . $url_query
98 . '&amp;table=' . $truename . '">'
99 . PMA_Util::getImage(
100 'eye_grey.png', __('Tracking is not active.')
102 . '</a>';
106 return array($browse_table,
107 $search_table,
108 $browse_table_label,
109 $empty_table,
110 $tracking_icon
115 * Get table drop query and drop message
117 * @param boolean $table_is_view Is table view or not
118 * @param string $current_table current table
120 * @return array ($drop_query, $drop_message)
122 function PMA_getTableDropQueryAndMessage($table_is_view, $current_table)
124 $drop_query = 'DROP '
125 . (($table_is_view || $current_table['ENGINE'] == null) ? 'VIEW' : 'TABLE')
126 . ' ' . PMA_Util::backquote(
127 $current_table['TABLE_NAME']
129 $drop_message = sprintf(
130 (($table_is_view || $current_table['ENGINE'] == null)
131 ? __('View %s has been dropped.')
132 : __('Table %s has been dropped.')),
133 str_replace(
134 ' ',
135 '&nbsp;',
136 htmlspecialchars($current_table['TABLE_NAME'])
139 return array($drop_query, $drop_message);
143 * Get HTML body for table summery
145 * @param integer $num_tables number of tables
146 * @param boolean $server_slave_status server slave state
147 * @param boolean $db_is_system_schema whether database is information schema or not
148 * @param integer $sum_entries sum entries
149 * @param string $db_collation collation of given db
150 * @param boolean $is_show_stats whether stats is show or not
151 * @param double $sum_size sum size
152 * @param double $overhead_size overhead size
153 * @param string $create_time_all create time
154 * @param string $update_time_all update time
155 * @param string $check_time_all check time
156 * @param boolean $approx_rows whether any table has approx row count or not
158 * @return string $html_output
160 function PMA_getHtmlBodyForTableSummary($num_tables, $server_slave_status,
161 $db_is_system_schema, $sum_entries, $db_collation, $is_show_stats,
162 $sum_size, $overhead_size, $create_time_all, $update_time_all,
163 $check_time_all, $approx_rows
165 $html_output = '<tbody id="tbl_summary_row">'
166 . '<tr><th></th>';
167 $html_output .= '<th class="tbl_num nowrap">';
168 $html_output .= sprintf(
169 _ngettext('%s table', '%s tables', $num_tables),
170 PMA_Util::formatNumber($num_tables, 0)
172 $html_output .= '</th>';
174 if ($server_slave_status) {
175 $html_output .= '<th>' . __('Replication') . '</th>' . "\n";
177 $html_output .= '<th colspan="' . ($db_is_system_schema ? 4 : 7) . '">'
178 . __('Sum')
179 . '</th>';
181 $row_count_sum = PMA_Util::formatNumber($sum_entries, 0);
182 // If a table shows approximate rows count, display update-all-real-count anchor.
183 if (isset($approx_rows)) {
184 $row_sum_url = array(
185 'ajax_request' => true,
186 'db' => $GLOBALS['db'],
187 'real_row_count' => 'true',
188 'real_row_count_all' => 'true'
191 $cell_text = ($approx_rows)
192 ? '<a href="db_structure.php' . PMA_URL_getCommon($row_sum_url)
193 . '" class="ajax row_count_sum">' . '~' . $row_count_sum . '</a>'
194 : $row_count_sum;
195 $html_output .= '<th class="value tbl_rows">'
196 . $cell_text
197 . '</th>';
199 if (!($GLOBALS['cfg']['PropertiesNumColumns'] > 1)) {
200 $default_engine = $GLOBALS['dbi']->fetchValue(
201 'SHOW VARIABLES LIKE \'storage_engine\';',
205 $html_output .= '<th class="center">' . "\n"
206 . '<dfn title="'
207 . sprintf(
208 __('%s is the default storage engine on this MySQL server.'),
209 $default_engine
211 . '">' . $default_engine . '</dfn></th>' . "\n";
212 // we got a case where $db_collation was empty
213 $html_output .= '<th>' . "\n";
215 if (! empty($db_collation)) {
216 $html_output .= '<dfn title="'
217 . PMA_getCollationDescr($db_collation)
218 . ' (' . __('Default') . ')">'
219 . $db_collation
220 . '</dfn>';
222 $html_output .= '</th>';
224 if ($is_show_stats) {
225 list($sum_formatted, $unit) = PMA_Util::formatByteDown(
226 $sum_size, 3, 1
228 list($overhead_formatted, $overhead_unit)
229 = PMA_Util::formatByteDown($overhead_size, 3, 1);
231 $html_output .= '<th class="value tbl_size">'
232 . $sum_formatted . ' ' . $unit
233 . '</th>';
234 $html_output .= '<th class="value tbl_overhead">'
235 . $overhead_formatted . ' ' . $overhead_unit
236 . '</th>';
239 if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
240 $html_output .= '<th class="value tbl_creation">' . "\n"
241 . ' '
242 . ($create_time_all
243 ? PMA_Util::localisedDate(strtotime($create_time_all))
244 : '-'
246 . '</th>';
249 if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
250 $html_output .= '<th class="value tbl_last_update">' . "\n"
251 . ' '
252 . ($update_time_all
253 ? PMA_Util::localisedDate(strtotime($update_time_all))
254 : '-'
256 . '</th>';
259 if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
260 $html_output .= '<th class="value tbl_last_check">' . "\n"
261 . ' '
262 . ($check_time_all
263 ? PMA_Util::localisedDate(strtotime($check_time_all))
264 : '-'
266 . '</th>';
268 $html_output .= '</tr>'
269 . '</tbody>';
271 return $html_output;
275 * Get HTML for "check all" check box with "with selected" dropdown
277 * @param string $pmaThemeImage pma theme image url
278 * @param string $text_dir url for text directory
279 * @param string $overhead_check overhead check
280 * @param boolean $db_is_system_schema whether database is information schema or not
281 * @param array $hidden_fields hidden fields
283 * @return string $html_output
285 function PMA_getHtmlForCheckAllTables($pmaThemeImage, $text_dir,
286 $overhead_check, $db_is_system_schema, $hidden_fields
288 $html_output = '<div class="clearfloat">';
289 $html_output .= '<img class="selectallarrow" '
290 . 'src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png" '
291 . 'width="38" height="22" alt="' . __('With selected:') . '" />';
293 $html_output .= '<input type="checkbox" id="tablesForm_checkall" '
294 . 'class="checkall_box" title="' . __('Check All') . '" />';
295 $html_output .= '<label for="tablesForm_checkall">' . __('Check All')
296 . '</label>';
298 if ($overhead_check != '') {
299 $html_output .= PMA_getHtmlForCheckTablesHavingOverheadlink(
300 $overhead_check
304 $html_output .= '<select name="submit_mult" class="autosubmit" '
305 . 'style="margin: 0 3em 0 3em;">';
307 $html_output .= '<option value="' . __('With selected:')
308 . '" selected="selected">'
309 . __('With selected:') . '</option>' . "\n";
310 $html_output .= '<option value="show_create" >'
311 . __('Show create') . '</option>' . "\n";
312 $html_output .= '<option value="export" >'
313 . __('Export') . '</option>' . "\n";
314 $html_output .= '<option value="print" >'
315 . __('Print view') . '</option>' . "\n";
317 if (!$db_is_system_schema
318 && !$GLOBALS['cfg']['DisableMultiTableMaintenance']
320 $html_output .= '<option value="empty_tbl" >'
321 . __('Empty') . '</option>' . "\n";
322 $html_output .= '<option value="drop_tbl" >'
323 . __('Drop') . '</option>' . "\n";
324 $html_output .= '<option value="check_tbl" >'
325 . __('Check table') . '</option>' . "\n";
326 if (!PMA_DRIZZLE) {
327 $html_output .= '<option value="optimize_tbl" >'
328 . __('Optimize table') . '</option>' . "\n";
329 $html_output .= '<option value="repair_tbl" >'
330 . __('Repair table') . '</option>' . "\n";
332 $html_output .= '<option value="analyze_tbl" >'
333 . __('Analyze table') . '</option>' . "\n";
334 $html_output .= '<option value="add_prefix_tbl" >'
335 . __('Add prefix to table') . '</option>' . "\n";
336 $html_output .= '<option value="replace_prefix_tbl" >'
337 . __('Replace table prefix') . '</option>' . "\n";
338 $html_output .= '<option value="copy_tbl_change_prefix" >'
339 . __('Copy table with prefix') . '</option>' . "\n";
340 if ($GLOBALS['cfgRelation']['central_columnswork']) {
341 $html_output .= '<option value="sync_unique_columns_central_list" >'
342 . __('Add columns to central list') . '</option>' . "\n";
343 $html_output .= '<option value="delete_unique_columns_central_list" >'
344 . __('Remove columns from central list') . '</option>' . "\n";
345 $html_output .= '<option value="make_consistent_with_central_list" >'
346 . __('Make consistent with central list') . '</option>' . "\n";
349 $html_output .= '</select>'
350 . implode("\n", $hidden_fields) . "\n";
351 $html_output .= '</div>';
353 return $html_output;
357 * Get HTML code for "Check tables having overhead" link
359 * @param string $overhead_check overhead check
361 * @return string $html_output
363 function PMA_getHtmlForCheckTablesHavingOverheadlink($overhead_check)
365 return ' / '
366 . '<a href="#" onclick="unMarkAllRows(\'tablesForm\');'
367 . $overhead_check . 'return false;">'
368 . __('Check tables having overhead')
369 . '</a>';
374 * Get HTML links for "Print view" options
376 * @param string $url_query url query
378 * @return string $html_output
380 function PMA_getHtmlForTablePrintViewLink($url_query)
382 return '<p>'
383 . '<a href="db_printview.php?' . $url_query . '" target="print_view">'
384 . PMA_Util::getIcon(
385 'b_print.png',
386 __('Print view'),
387 true
388 ) . '</a>';
392 * Get HTML links "Data Dictionary" options
394 * @param string $url_query url query
396 * @return string $html_output
398 function PMA_getHtmlForDataDictionaryLink($url_query)
400 return '<a href="db_datadict.php?' . $url_query . '" target="print_view">'
401 . PMA_Util::getIcon(
402 'b_tblanalyse.png',
403 __('Data Dictionary'),
404 true
405 ) . '</a>'
406 . '</p>';
410 * Get Time for Create time, update time and check time
412 * @param array $current_table current table
413 * @param string $time_label Create_time, Update_time, Check_time
414 * @param integer $time_all time
416 * @return array ($time, $time_all)
418 function PMA_getTimeForCreateUpdateCheck($current_table, $time_label, $time_all)
420 $showtable = PMA_Table::sGetStatusInfo(
421 $GLOBALS['db'],
422 $current_table['TABLE_NAME'],
423 null,
424 true
426 $time = isset($showtable[$time_label])
427 ? $showtable[$time_label]
428 : false;
430 // show oldest creation date in summary row
431 if ($time && (!$time_all || $time < $time_all)) {
432 $time_all = $time;
434 return array($time, $time_all);
438 * Get HTML for each table row of the database structure table,
439 * And this function returns $odd_row param also
441 * @param integer $curr current entry
442 * @param boolean $odd_row whether row is odd or not
443 * @param boolean $table_is_view whether table is view or not
444 * @param array $current_table current table
445 * @param string $browse_table_label browse table label action link
446 * @param string $tracking_icon tracking icon
447 * @param boolean $server_slave_status server slave state
448 * @param string $browse_table browse table action link
449 * @param string $tbl_url_query table url query
450 * @param string $search_table search table action link
451 * @param boolean $db_is_system_schema whether db is information schema or not
452 * @param array $titles titles array
453 * @param string $empty_table empty table action link
454 * @param string $drop_query table dropt query
455 * @param string $drop_message table drop message
456 * @param string $collation collation
457 * @param string $formatted_size formatted size
458 * @param string $unit unit
459 * @param string $overhead overhead
460 * @param string $create_time create time
461 * @param string $update_time last update time
462 * @param string $check_time last check time
463 * @param boolean $is_show_stats whether stats is show or not
464 * @param boolean $ignored ignored
465 * @param boolean $do do
466 * @param integer $colspan_for_structure colspan for structure
468 * @return array $html_output, $odd_row, $approx_rows
470 function PMA_getHtmlForStructureTableRow(
471 $curr, $odd_row, $table_is_view, $current_table,
472 $browse_table_label, $tracking_icon,$server_slave_status,
473 $browse_table, $tbl_url_query, $search_table,
474 $db_is_system_schema,$titles, $empty_table, $drop_query, $drop_message,
475 $collation, $formatted_size, $unit, $overhead, $create_time, $update_time,
476 $check_time,$is_show_stats, $ignored, $do, $colspan_for_structure
478 global $db;
479 $html_output = '<tr class="' . ($odd_row ? 'odd' : 'even');
480 $odd_row = ! $odd_row;
481 $html_output .= ($table_is_view ? ' is_view' : '')
482 . '" id="row_tbl_' . $curr . '">';
484 $html_output .= '<td class="center">'
485 . '<input type="checkbox" name="selected_tbl[]" class="checkall" '
486 . 'value="' . htmlspecialchars($current_table['TABLE_NAME']) . '" '
487 . 'id="checkbox_tbl_' . $curr . '" /></td>';
489 $html_output .= '<th>'
490 . $browse_table_label
491 . (! empty($tracking_icon) ? $tracking_icon : '')
492 . '</th>';
494 if ($server_slave_status) {
495 $html_output .= '<td class="center">'
496 . ($ignored
497 ? PMA_Util::getImage('s_cancel.png', 'NOT REPLICATED')
498 : '')
499 . ($do
500 ? PMA_Util::getImage('s_success.png', 'REPLICATED')
501 : '')
502 . '</td>';
504 //Favorite table anchor.
505 $html_output .= '<td class="center">'
506 . PMA_getHtmlForFavoriteAnchor($db, $current_table, $titles)
507 . '</td>';
509 $html_output .= '<td class="center">' . $browse_table . '</td>';
510 $html_output .= '<td class="center">'
511 . '<a href="tbl_structure.php?' . $tbl_url_query . '">'
512 . $titles['Structure'] . '</a></td>';
513 $html_output .= '<td class="center">' . $search_table . '</td>';
515 if (! $db_is_system_schema) {
516 $html_output .= PMA_getHtmlForInsertEmptyDropActionLinks(
517 $tbl_url_query, $table_is_view,
518 $titles, $empty_table, $current_table, $drop_query, $drop_message
520 } // end if (! $db_is_system_schema)
522 // there is a null value in the ENGINE
523 // - when the table needs to be repaired, or
524 // - when it's a view
525 // so ensure that we'll display "in use" below for a table
526 // that needs to be repaired
527 $approx_rows = false;
528 if (isset($current_table['TABLE_ROWS'])
529 && ($current_table['ENGINE'] != null
530 || $table_is_view)
532 list($html_view_table, $approx_rows) = PMA_getHtmlForNotNullEngineViewTable(
533 $table_is_view, $current_table, $collation, $is_show_stats,
534 $tbl_url_query, $formatted_size, $unit, $overhead, $create_time,
535 $update_time, $check_time
537 $html_output .= $html_view_table;
538 } elseif ($table_is_view) {
539 $html_output .= PMA_getHtmlForViewTable($is_show_stats);
540 } else {
541 $html_output .= PMA_getHtmlForRepairtable(
542 $colspan_for_structure,
543 $db_is_system_schema
545 } // end if (isset($current_table['TABLE_ROWS'])) else
546 $html_output .= '</tr>';
548 return array($html_output, $odd_row, $approx_rows);
552 * Get HTML for Insert/Empty/Drop action links
554 * @param string $tbl_url_query table url query
555 * @param boolean $table_is_view whether table is view or not
556 * @param array $titles titles array
557 * @param string $empty_table HTML link for empty table
558 * @param array $current_table current table
559 * @param string $drop_query query for drop table
560 * @param string $drop_message table drop message
562 * @return string $html_output
564 function PMA_getHtmlForInsertEmptyDropActionLinks($tbl_url_query, $table_is_view,
565 $titles, $empty_table, $current_table, $drop_query, $drop_message
567 $html_output = '<td class="insert_table center">'
568 . '<a href="tbl_change.php?' . $tbl_url_query . '">'
569 . $titles['Insert']
570 . '</a></td>';
571 $html_output .= '<td class="center">' . $empty_table . '</td>';
572 $html_output .= '<td class="center">';
573 $html_output .= '<a ';
574 $html_output .= 'class="ajax drop_table_anchor';
575 if ($table_is_view || $current_table['ENGINE'] == null) {
576 // this class is used in db_structure.js to display the
577 // correct confirmation message
578 $html_output .= ' view';
580 $html_output .= '" ';
581 $html_output .= 'href="sql.php?' . $tbl_url_query
582 . '&amp;reload=1&amp;purge=1&amp;sql_query='
583 . urlencode($drop_query) . '&amp;message_to_show='
584 . urlencode($drop_message) . '" >'
585 . $titles['Drop'] . '</a></td>';
587 return $html_output;
591 * Get HTML for show stats
593 * @param string $tbl_url_query tabel url query
594 * @param string $formatted_size formatted size
595 * @param string $unit unit
596 * @param string $overhead overhead
598 * @return string $html_output
600 function PMA_getHtmlForShowStats($tbl_url_query, $formatted_size,
601 $unit, $overhead
603 $html_output = '<td class="value tbl_size"><a '
604 . 'href="tbl_structure.php?' . $tbl_url_query . '#showusage" >'
605 . '<span>' . $formatted_size . '</span> '
606 . '<span class="unit">' . $unit . '</span>'
607 . '</a></td>';
608 $html_output .= '<td class="value tbl_overhead">' . $overhead . '</td>';
610 return $html_output;
614 * Get HTML to show database structure creation, last update and last checkx time
616 * @param string $create_time create time
617 * @param string $update_time last update time
618 * @param string $check_time last check time
620 * @return string $html_output
622 function PMA_getHtmlForStructureTimes($create_time, $update_time, $check_time)
624 $html_output = '';
625 if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
626 $html_output .= '<td class="value tbl_creation">'
627 . ($create_time
628 ? PMA_Util::localisedDate(strtotime($create_time))
629 : '-' )
630 . '</td>';
631 } // end if
632 if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
633 $html_output .= '<td class="value tbl_last_update">'
634 . ($update_time
635 ? PMA_Util::localisedDate(strtotime($update_time))
636 : '-' )
637 . '</td>';
638 } // end if
639 if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
640 $html_output .= '<td class="value tbl_last_check">'
641 . ($check_time
642 ? PMA_Util::localisedDate(strtotime($check_time))
643 : '-' )
644 . '</td>';
646 return $html_output;
650 * Get HTML for ENGINE value not null or view tables that are not empty tables
652 * @param boolean $table_is_view whether table is view
653 * @param array $current_table current table
654 * @param string $collation collation
655 * @param boolean $is_show_stats whether atats show or not
656 * @param string $tbl_url_query table url query
657 * @param string $formatted_size formatted size
658 * @param string $unit unit
659 * @param string $overhead overhead
660 * @param string $create_time create time
661 * @param string $update_time update time
662 * @param string $check_time check time
664 * @return string $html_output
666 function PMA_getHtmlForNotNullEngineViewTable($table_is_view, $current_table,
667 $collation, $is_show_stats, $tbl_url_query, $formatted_size, $unit,
668 $overhead, $create_time, $update_time, $check_time
670 $html_output = '';
671 $row_count_pre = '';
672 $show_superscript = '';
673 if ($table_is_view) {
674 // Drizzle views use FunctionEngine, and the only place where they are
675 // available are I_S and D_D schemas, where we do exact counting
676 if ($current_table['TABLE_ROWS'] >= $GLOBALS['cfg']['MaxExactCountViews']
677 && $current_table['ENGINE'] != 'FunctionEngine'
679 $row_count_pre = '~';
680 $show_superscript = PMA_Util::showHint(
681 PMA_sanitize(
682 sprintf(
683 __('This view has at least this number of rows. Please refer to %sdocumentation%s.'),
684 '[doc@cfg_MaxExactCountViews]',
685 '[/doc]'
690 } elseif ($current_table['ENGINE'] == 'InnoDB'
691 && (! $current_table['COUNTED'])
693 // InnoDB table: we did not get an accurate row count
694 $row_count_pre = '~';
695 $show_superscript = '';
698 // Set a flag if there are approximate row counts on page.
699 if (! empty($row_count_pre)) {
700 $approx_rows = true;
701 } else {
702 // this happens for information_schema, performance_schema,
703 // and in case there is no InnoDB table on this page
704 $approx_rows = false;
706 // Get the row count.
707 $row_count = $row_count_pre
708 . PMA_Util::formatNumber($current_table['TABLE_ROWS'], 0);
709 // URL parameters to fetch the real row count.
710 $real_count_url = array(
711 'ajax_request' => true,
712 'db' => $GLOBALS['db'],
713 'table' => $current_table['TABLE_NAME'],
714 'real_row_count' => 'true'
716 // Content to be appended into 'tbl_rows' cell.
717 // If row count is approximate, display it as an anchor to get real count.
718 $cell_text = (! empty($row_count_pre))
719 ? '<a href="db_structure.php' . PMA_URL_getCommon($real_count_url)
720 . '" class="ajax real_row_count">' . $row_count . '</a>'
721 : $row_count;
722 $html_output .= '<td class="value tbl_rows" data-table="'
723 . htmlspecialchars($current_table['TABLE_NAME']) . '">'
724 . $cell_text
725 . $show_superscript
726 . '</td>';
728 if (!($GLOBALS['cfg']['PropertiesNumColumns'] > 1)) {
729 $html_output .= '<td class="nowrap">'
730 . ($table_is_view ? __('View') : $current_table['ENGINE'])
731 . '</td>';
732 if (strlen($collation)) {
733 $html_output .= '<td class="nowrap">' . $collation . '</td>';
737 if ($is_show_stats) {
738 $html_output .= PMA_getHtmlForShowStats(
739 $tbl_url_query, $formatted_size, $unit, $overhead
743 $html_output .= PMA_getHtmlForStructureTimes(
744 $create_time, $update_time, $check_time
747 return array($html_output, $approx_rows);
751 * Get HTML snippet view table
753 * @param boolean $is_show_stats whether stats show or not
755 * @return string $html_output
757 function PMA_getHtmlForViewTable($is_show_stats)
759 $html_output = '<td class="value">-</td>'
760 . '<td>' . __('View') . '</td>'
761 . '<td>---</td>';
762 if ($is_show_stats) {
763 $html_output .= '<td class="value">-</td>'
764 . '<td class="value">-</td>';
766 return $html_output;
770 * display "in use" below for a table that needs to be repaired
772 * @param integer $colspan_for_structure colspan for structure
773 * @param boolean $db_is_system_schema whether db is information schema or not
775 * @return string HTML snippet
777 function PMA_getHtmlForRepairtable(
778 $colspan_for_structure,
779 $db_is_system_schema
781 return '<td colspan="'
782 . ($colspan_for_structure - ($db_is_system_schema ? 5 : 8)) . '"'
783 . 'class="center">'
784 . __('in use')
785 . '</td>';
789 * display table header (<table><thead>...</thead><tbody>)
791 * @param boolean $db_is_system_schema whether db is information schema or not
792 * @param boolean $replication whether to sho replication status
794 * @return string html data
796 function PMA_tableHeader($db_is_system_schema = false, $replication = false)
798 $cnt = 0; // Let's count the columns...
800 if ($db_is_system_schema) {
801 $action_colspan = 4;
802 } else {
803 $action_colspan = 7;
806 $html_output = '<table class="data">' . "\n"
807 . '<thead>' . "\n"
808 . '<tr><th></th>' . "\n"
809 . '<th>'
810 . PMA_sortableTableHeader(__('Table'), 'table')
811 . '</th>' . "\n";
812 if ($replication) {
813 $html_output .= '<th>' . "\n"
814 . ' ' . __('Replication') . "\n"
815 . '</th>';
817 $html_output .= '<th colspan="' . $action_colspan . '">' . "\n"
818 . ' ' . __('Action') . "\n"
819 . '</th>'
820 // larger values are more interesting so default sort order is DESC
821 . '<th>' . PMA_sortableTableHeader(__('Rows'), 'records', 'DESC')
822 . PMA_Util::showHint(
823 PMA_sanitize(
825 'May be approximate. Click on the number to get the exact'
826 . ' count. See [doc@faq3-11]FAQ 3.11[/doc].'
829 ) . "\n"
830 . '</th>' . "\n";
831 if (!($GLOBALS['cfg']['PropertiesNumColumns'] > 1)) {
832 $html_output .= '<th>' . PMA_sortableTableHeader(__('Type'), 'type')
833 . '</th>' . "\n";
834 $cnt++;
835 $html_output .= '<th>'
836 . PMA_sortableTableHeader(__('Collation'), 'collation')
837 . '</th>' . "\n";
838 $cnt++;
840 if ($GLOBALS['is_show_stats']) {
841 // larger values are more interesting so default sort order is DESC
842 $html_output .= '<th>'
843 . PMA_sortableTableHeader(__('Size'), 'size', 'DESC')
844 . '</th>' . "\n"
845 // larger values are more interesting so default sort order is DESC
846 . '<th>'
847 . PMA_sortableTableHeader(__('Overhead'), 'overhead', 'DESC')
848 . '</th>' . "\n";
849 $cnt += 2;
851 if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
852 // larger values are more interesting so default sort order is DESC
853 $html_output .= '<th>'
854 . PMA_sortableTableHeader(__('Creation'), 'creation', 'DESC')
855 . '</th>' . "\n";
856 $cnt += 2;
858 if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
859 // larger values are more interesting so default sort order is DESC
860 $html_output .= '<th>'
861 . PMA_sortableTableHeader(__('Last update'), 'last_update', 'DESC')
862 . '</th>' . "\n";
863 $cnt += 2;
865 if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
866 // larger values are more interesting so default sort order is DESC
867 $html_output .= '<th>'
868 . PMA_sortableTableHeader(__('Last check'), 'last_check', 'DESC')
869 . '</th>' . "\n";
870 $cnt += 2;
872 $html_output .= '</tr>' . "\n";
873 $html_output .= '</thead>' . "\n";
874 $html_output .= '<tbody>' . "\n";
875 $GLOBALS['colspan_for_structure'] = $cnt + $action_colspan + 3;
877 return $html_output;
881 * Creates a clickable column header for table information
883 * @param string $title title to use for the link
884 * @param string $sort corresponds to sortable data name mapped in
885 * libraries/db_info.inc.php
886 * @param string $initial_sort_order initial sort order
888 * @return string link to be displayed in the table header
890 function PMA_sortableTableHeader($title, $sort, $initial_sort_order = 'ASC')
892 // Set some defaults
893 $requested_sort = 'table';
894 $requested_sort_order = $future_sort_order = $initial_sort_order;
896 // If the user requested a sort
897 if (isset($_REQUEST['sort'])) {
898 $requested_sort = $_REQUEST['sort'];
900 if (isset($_REQUEST['sort_order'])) {
901 $requested_sort_order = $_REQUEST['sort_order'];
905 $order_img = '';
906 $order_link_params = array();
907 $order_link_params['title'] = __('Sort');
909 // If this column was requested to be sorted.
910 if ($requested_sort == $sort) {
911 if ($requested_sort_order == 'ASC') {
912 $future_sort_order = 'DESC';
913 // current sort order is ASC
914 $order_img = ' ' . PMA_Util::getImage(
915 's_asc.png',
916 __('Ascending'),
917 array('class' => 'sort_arrow', 'title' => '')
919 $order_img .= ' ' . PMA_Util::getImage(
920 's_desc.png',
921 __('Descending'),
922 array('class' => 'sort_arrow hide', 'title' => '')
924 // but on mouse over, show the reverse order (DESC)
925 $order_link_params['onmouseover'] = "$('.sort_arrow').toggle();";
926 // on mouse out, show current sort order (ASC)
927 $order_link_params['onmouseout'] = "$('.sort_arrow').toggle();";
928 } else {
929 $future_sort_order = 'ASC';
930 // current sort order is DESC
931 $order_img = ' ' . PMA_Util::getImage(
932 's_asc.png',
933 __('Ascending'),
934 array('class' => 'sort_arrow hide', 'title' => '')
936 $order_img .= ' ' . PMA_Util::getImage(
937 's_desc.png',
938 __('Descending'),
939 array('class' => 'sort_arrow', 'title' => '')
941 // but on mouse over, show the reverse order (ASC)
942 $order_link_params['onmouseover'] = "$('.sort_arrow').toggle();";
943 // on mouse out, show current sort order (DESC)
944 $order_link_params['onmouseout'] = "$('.sort_arrow').toggle();";
948 $_url_params = array(
949 'db' => $_REQUEST['db'],
952 $url = 'db_structure.php' . PMA_URL_getCommon($_url_params);
953 // We set the position back to 0 every time they sort.
954 $url .= "&amp;pos=0&amp;sort=$sort&amp;sort_order=$future_sort_order";
955 if (! empty($_REQUEST['tbl_type'])) {
956 $url .= "&amp;tbl_type=" . $_REQUEST['tbl_type'];
958 if (! empty($_REQUEST['tbl_group'])) {
959 $url .= "&amp;tbl_group=" . $_REQUEST['tbl_group'];
962 return PMA_Util::linkOrButton(
963 $url, $title . $order_img, $order_link_params
968 * Get the alias ant truname
970 * @param string $tooltip_aliasname tooltip alias name
971 * @param array $current_table current table
972 * @param string $tooltip_truename tooltip true name
974 * @return array ($alias, $truename)
976 function PMA_getAliasAndTrueName($tooltip_aliasname, $current_table,
977 $tooltip_truename
979 $alias = (! empty($tooltip_aliasname)
980 && isset($tooltip_aliasname[$current_table['TABLE_NAME']])
982 ? str_replace(
983 ' ', '&nbsp;',
984 htmlspecialchars($tooltip_truename[$current_table['TABLE_NAME']])
986 : str_replace(
987 ' ', '&nbsp;',
988 htmlspecialchars($current_table['TABLE_NAME'])
990 $truename = (! empty($tooltip_truename)
991 && isset($tooltip_truename[$current_table['TABLE_NAME']])
993 ? str_replace(
994 ' ', '&nbsp;',
995 htmlspecialchars($tooltip_truename[$current_table['TABLE_NAME']])
997 : str_replace(
998 ' ', '&nbsp;',
999 htmlspecialchars($current_table['TABLE_NAME'])
1002 return array($alias, $truename);
1006 * Get the server slave state
1008 * @param boolean $server_slave_status server slave state
1009 * @param string $truename true name
1011 * @return array ($do, $ignored)
1013 function PMA_getServerSlaveStatus($server_slave_status, $truename)
1015 $ignored = false;
1016 $do = false;
1017 include_once 'libraries/replication.inc.php';
1018 if ($server_slave_status) {
1019 $nbServerSlaveDoDb = count($server_slave_Do_DB);
1020 $nbServerSlaveIgnoreDb = count($server_slave_Ignore_DB);
1021 if ((strlen(array_search($truename, $server_slave_Do_Table)) > 0)
1022 || (strlen(array_search($GLOBALS['db'], $server_slave_Do_DB)) > 0)
1023 || ($nbServerSlaveDoDb == 1 && $nbServerSlaveIgnoreDb == 1)
1025 $do = true;
1027 foreach ($server_slave_Wild_Do_Table as $db_table) {
1028 $table_part = PMA_extractDbOrTable($db_table, 'table');
1029 $pattern = "@^" . substr($table_part, 0, strlen($table_part) - 1) . "@";
1030 if (($GLOBALS['db'] == PMA_extractDbOrTable($db_table, 'db'))
1031 && (preg_match($pattern, $truename))
1033 $do = true;
1037 if ((strlen(array_search($truename, $server_slave_Ignore_Table)) > 0)
1038 || (strlen(array_search($GLOBALS['db'], $server_slave_Ignore_DB)) > 0)
1040 $ignored = true;
1042 foreach ($server_slave_Wild_Ignore_Table as $db_table) {
1043 $table_part = PMA_extractDbOrTable($db_table, 'table');
1044 $pattern = "@^" . substr($table_part, 0, strlen($table_part) - 1) . "@";
1045 if (($db == PMA_extractDbOrTable($db_table))
1046 && (preg_match($pattern, $truename))
1048 $ignored = true;
1052 return array($do, $ignored);
1056 * Get the value set for ENGINE table,
1057 * $current_table, $formatted_size, $unit, $formatted_overhead,
1058 * $overhead_unit, $overhead_size, $table_is_view
1060 * @param array $current_table current table
1061 * @param boolean $db_is_system_schema whether db is information schema or not
1062 * @param boolean $is_show_stats whether stats show or not
1063 * @param boolean $table_is_view whether table is view or not
1064 * @param double $sum_size totle table size
1065 * @param double $overhead_size overhead size
1067 * @return array
1069 function PMA_getStuffForEngineTypeTable($current_table, $db_is_system_schema,
1070 $is_show_stats, $table_is_view, $sum_size, $overhead_size
1072 $formatted_size = '-';
1073 $unit = '';
1074 $formatted_overhead = '';
1075 $overhead_unit = '';
1077 switch ( $current_table['ENGINE']) {
1078 // MyISAM, ISAM or Heap table: Row count, data size and index size
1079 // are accurate; data size is accurate for ARCHIVE
1080 case 'MyISAM' :
1081 case 'ISAM' :
1082 case 'HEAP' :
1083 case 'MEMORY' :
1084 case 'ARCHIVE' :
1085 case 'Aria' :
1086 case 'Maria' :
1087 list($current_table, $formatted_size, $unit, $formatted_overhead,
1088 $overhead_unit, $overhead_size, $sum_size) = PMA_getValuesForAriaTable(
1089 $db_is_system_schema, $current_table, $is_show_stats,
1090 $sum_size, $overhead_size, $formatted_size, $unit,
1091 $formatted_overhead, $overhead_unit
1093 break;
1094 case 'InnoDB' :
1095 case 'PBMS' :
1096 // InnoDB table: Row count is not accurate but data and index sizes are.
1097 // PBMS table in Drizzle: TABLE_ROWS is taken from table cache,
1098 // so it may be unavailable
1099 list($current_table, $formatted_size, $unit, $sum_size)
1100 = PMA_getValuesForInnodbTable($current_table, $is_show_stats, $sum_size);
1101 //$display_rows = ' - ';
1102 break;
1103 // Mysql 5.0.x (and lower) uses MRG_MyISAM
1104 // and MySQL 5.1.x (and higher) uses MRG_MYISAM
1105 // Both are aliases for MERGE
1106 case 'MRG_MyISAM' :
1107 case 'MRG_MYISAM' :
1108 case 'MERGE' :
1109 case 'BerkeleyDB' :
1110 // Merge or BerkleyDB table: Only row count is accurate.
1111 if ($is_show_stats) {
1112 $formatted_size = ' - ';
1113 $unit = '';
1115 break;
1116 // for a view, the ENGINE is sometimes reported as null,
1117 // or on some servers it's reported as "SYSTEM VIEW"
1118 case null :
1119 case 'SYSTEM VIEW' :
1120 case 'FunctionEngine' :
1121 // if table is broken, Engine is reported as null, so one more test
1122 if ($current_table['TABLE_TYPE'] == 'VIEW') {
1123 // countRecords() takes care of $cfg['MaxExactCountViews']
1124 $current_table['TABLE_ROWS'] = PMA_Table::countRecords(
1125 $GLOBALS['db'], $current_table['TABLE_NAME'],
1126 true, true
1128 $table_is_view = true;
1130 break;
1131 default :
1132 // Unknown table type.
1133 if ($is_show_stats) {
1134 $formatted_size = __('unknown');
1135 $unit = '';
1137 } // end switch
1139 return array($current_table, $formatted_size, $unit, $formatted_overhead,
1140 $overhead_unit, $overhead_size, $table_is_view, $sum_size
1145 * Get values for ARIA/MARIA tables
1146 * $current_table, $formatted_size, $unit, $formatted_overhead,
1147 * $overhead_unit, $overhead_size
1149 * @param boolean $db_is_system_schema whether db is information schema or not
1150 * @param array $current_table current table
1151 * @param boolean $is_show_stats whether stats show or not
1152 * @param double $sum_size sum size
1153 * @param double $overhead_size overhead size
1154 * @param number $formatted_size formatted size
1155 * @param string $unit unit
1156 * @param number $formatted_overhead overhead formatted
1157 * @param string $overhead_unit overhead unit
1159 * @return array
1161 function PMA_getValuesForAriaTable($db_is_system_schema, $current_table,
1162 $is_show_stats, $sum_size, $overhead_size, $formatted_size, $unit,
1163 $formatted_overhead, $overhead_unit
1165 if ($db_is_system_schema) {
1166 $current_table['Rows'] = PMA_Table::countRecords(
1167 $GLOBALS['db'], $current_table['Name']
1171 if ($is_show_stats) {
1172 $tblsize = doubleval($current_table['Data_length'])
1173 + doubleval($current_table['Index_length']);
1174 $sum_size += $tblsize;
1175 list($formatted_size, $unit) = PMA_Util::formatByteDown(
1176 $tblsize, 3, ($tblsize > 0) ? 1 : 0
1178 if (isset($current_table['Data_free']) && $current_table['Data_free'] > 0) {
1179 list($formatted_overhead, $overhead_unit)
1180 = PMA_Util::formatByteDown(
1181 $current_table['Data_free'], 3,
1182 (($current_table['Data_free'] > 0) ? 1 : 0)
1184 $overhead_size += $current_table['Data_free'];
1187 return array($current_table, $formatted_size, $unit, $formatted_overhead,
1188 $overhead_unit, $overhead_size, $sum_size
1193 * Get values for InnoDB table
1194 * $current_table, $formatted_size, $unit, $sum_size
1196 * @param array $current_table current table
1197 * @param boolean $is_show_stats whether stats show or not
1198 * @param double $sum_size sum size
1200 * @return array
1202 function PMA_getValuesForInnodbTable($current_table, $is_show_stats, $sum_size)
1204 $formatted_size = $unit = '';
1206 if (($current_table['ENGINE'] == 'InnoDB'
1207 && $current_table['TABLE_ROWS'] < $GLOBALS['cfg']['MaxExactCount'])
1208 || !isset($current_table['TABLE_ROWS'])
1210 $current_table['COUNTED'] = true;
1211 $current_table['TABLE_ROWS'] = PMA_Table::countRecords(
1212 $GLOBALS['db'], $current_table['TABLE_NAME'],
1213 true, false
1215 } else {
1216 $current_table['COUNTED'] = false;
1219 // Drizzle doesn't provide data and index length, check for null
1220 if ($is_show_stats && $current_table['Data_length'] !== null) {
1221 $tblsize = $current_table['Data_length'] + $current_table['Index_length'];
1222 $sum_size += $tblsize;
1223 list($formatted_size, $unit) = PMA_Util::formatByteDown(
1224 $tblsize, 3, (($tblsize > 0) ? 1 : 0)
1228 return array($current_table, $formatted_size, $unit, $sum_size);
1232 * table structure
1236 * Get the HTML snippet for structure table table header
1238 * @param boolean $db_is_system_schema whether db is information schema or not
1239 * @param boolean $tbl_is_view whether table is view or not
1241 * @return string $html_output
1243 function PMA_getHtmlForTableStructureHeader(
1244 $db_is_system_schema,
1245 $tbl_is_view
1247 $html_output = '<thead>';
1248 $html_output .= '<tr>';
1249 $html_output .= '<th></th>'
1250 . '<th>#</th>'
1251 . '<th>' . __('Name') . '</th>'
1252 . '<th>' . __('Type') . '</th>'
1253 . '<th>' . __('Collation') . '</th>'
1254 . '<th>' . __('Attributes') . '</th>'
1255 . '<th>' . __('Null') . '</th>'
1256 . '<th>' . __('Default') . '</th>'
1257 . '<th>' . __('Extra') . '</th>';
1259 if ($db_is_system_schema || $tbl_is_view) {
1260 $html_output .= '<th>' . __('View') . '</th>';
1261 } else { /* see tbl_structure.js, function moreOptsMenuResize() */
1262 $colspan = 9;
1263 if (PMA_DRIZZLE) {
1264 $colspan -= 2;
1266 if (PMA_Util::showIcons('ActionLinksMode')) {
1267 $colspan--;
1269 $html_output .= '<th colspan="' . $colspan . '" '
1270 . 'class="action">' . __('Action') . '</th>';
1272 $html_output .= '</tr>'
1273 . '</thead>';
1275 return $html_output;
1279 * Get HTML for structure table's rows and return $odd_row parameter also
1280 * For "Action" Column, this function contains only HTML code for "Change"
1281 * and "Drop"
1283 * @param array $row current row
1284 * @param string $rownum row number
1285 * @param string $displayed_field_name displayed field name
1286 * @param string $type_nowrap type nowrap
1287 * @param array $extracted_columnspec associative array containing type,
1288 * spec_in_brackets and possibly
1289 * enum_set_values (another array)
1290 * @param string $type_mime mime type
1291 * @param string $field_charset field charset
1292 * @param string $attribute attribute (BINARY, UNSIGNED,
1293 * UNSIGNED ZEROFILL,
1294 * on update CURRENT_TIMESTAMP)
1295 * @param boolean $tbl_is_view whether tables is view or not
1296 * @param boolean $db_is_system_schema whether db is information schema or not
1297 * @param string $url_query url query
1298 * @param string $field_encoded field encoded
1299 * @param array $titles titles array
1300 * @param string $table table
1302 * @return array ($html_output, $odd_row)
1304 function PMA_getHtmlTableStructureRow($row, $rownum,
1305 $displayed_field_name, $type_nowrap, $extracted_columnspec, $type_mime,
1306 $field_charset, $attribute, $tbl_is_view, $db_is_system_schema,
1307 $url_query, $field_encoded, $titles, $table
1309 $html_output = '<td class="center">'
1310 . '<input type="checkbox" class="checkall" name="selected_fld[]" '
1311 . 'value="' . htmlspecialchars($row['Field']) . '" '
1312 . 'id="checkbox_row_' . $rownum . '"/>'
1313 . '</td>';
1315 $html_output .= '<td class="right">'
1316 . $rownum
1317 . '</td>';
1319 $html_output .= '<th class="nowrap">'
1320 . '<label for="checkbox_row_' . $rownum . '">'
1321 . $displayed_field_name . '</label>'
1322 . '</th>';
1324 $html_output .= '<td' . $type_nowrap . '>'
1325 . '<bdo dir="ltr" lang="en">'
1326 . $extracted_columnspec['displayed_type'] . $type_mime
1327 . '</bdo></td>';
1329 $html_output .= '<td>' .
1330 (empty($field_charset)
1331 ? ''
1332 : '<dfn title="' . PMA_getCollationDescr($field_charset) . '">'
1333 . $field_charset . '</dfn>'
1335 . '</td>';
1337 $html_output .= '<td class="column_attribute nowrap">'
1338 . $attribute . '</td>';
1339 $html_output .= '<td>'
1340 . (($row['Null'] == 'YES') ? __('Yes') : __('No')) . ' </td>';
1342 $html_output .= '<td class="nowrap">';
1343 if (isset($row['Default'])) {
1344 if ($extracted_columnspec['type'] == 'bit') {
1345 // here, $row['Default'] contains something like b'010'
1346 $html_output .= PMA_Util::convertBitDefaultValue($row['Default']);
1347 } else {
1348 $html_output .= $row['Default'];
1350 } else {
1351 $html_output .= '<i>' . _pgettext('None for default', 'None') . '</i>';
1353 $html_output .= '</td>';
1355 $html_output .= '<td class="nowrap">' . strtoupper($row['Extra']) . '</td>';
1357 $html_output .= PMA_getHtmlForDropColumn(
1358 $tbl_is_view, $db_is_system_schema,
1359 $url_query, $field_encoded,
1360 $titles, $table, $row
1363 return $html_output;
1367 * Get HTML code for "Drop" Action link
1369 * @param boolean $tbl_is_view whether tables is view or not
1370 * @param boolean $db_is_system_schema whether db is information schema or not
1371 * @param string $url_query url query
1372 * @param string $field_encoded field encoded
1373 * @param array $titles tittles array
1374 * @param string $table table
1375 * @param array $row current row
1377 * @return string $html_output
1379 function PMA_getHtmlForDropColumn($tbl_is_view, $db_is_system_schema,
1380 $url_query, $field_encoded, $titles, $table, $row
1382 $html_output = '';
1384 if (! $tbl_is_view && ! $db_is_system_schema) {
1385 $html_output .= '<td class="edit center">'
1386 . '<a class="change_column_anchor ajax"'
1387 . ' href="tbl_structure.php?'
1388 . $url_query . '&amp;field=' . $field_encoded
1389 . '&amp;change_column=1">'
1390 . $titles['Change'] . '</a>' . '</td>';
1391 $html_output .= '<td class="drop center">'
1392 . '<a class="drop_column_anchor ajax"'
1393 . ' href="sql.php?' . $url_query . '&amp;sql_query='
1394 . urlencode(
1395 'ALTER TABLE ' . PMA_Util::backquote($table)
1396 . ' DROP ' . PMA_Util::backquote($row['Field']) . ';'
1398 . '&amp;dropped_column=' . urlencode($row['Field'])
1399 . '&amp;message_to_show=' . urlencode(
1400 sprintf(
1401 __('Column %s has been dropped.'),
1402 htmlspecialchars($row['Field'])
1404 ) . '" >'
1405 . $titles['Drop'] . '</a>'
1406 . '</td>';
1409 return $html_output;
1413 * Get HTML for "check all" check box with "with selected" actions in table
1414 * structure
1416 * @param string $pmaThemeImage pma theme image url
1417 * @param string $text_dir test directory
1418 * @param boolean $tbl_is_view whether table is view or not
1419 * @param boolean $db_is_system_schema whether db is information schema or not
1420 * @param string $tbl_storage_engine table storage engine
1422 * @return string $html_output
1424 function PMA_getHtmlForCheckAllTableColumn($pmaThemeImage, $text_dir,
1425 $tbl_is_view, $db_is_system_schema, $tbl_storage_engine
1427 $html_output = '<img class="selectallarrow" '
1428 . 'src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png" '
1429 . 'width="38" height="22" alt="' . __('With selected:') . '" />';
1431 $html_output .= '<input type="checkbox" id="fieldsForm_checkall" '
1432 . 'class="checkall_box" title="' . __('Check All') . '" />'
1433 . '<label for="fieldsForm_checkall">' . __('Check All') . '</label>';
1435 $html_output .= '<i style="margin-left: 2em">'
1436 . __('With selected:') . '</i>';
1438 $html_output .= PMA_Util::getButtonOrImage(
1439 'submit_mult', 'mult_submit', 'submit_mult_browse',
1440 __('Browse'), 'b_browse.png', 'browse'
1443 if (! $tbl_is_view && ! $db_is_system_schema) {
1444 $html_output .= PMA_Util::getButtonOrImage(
1445 'submit_mult', 'mult_submit change_columns_anchor ajax',
1446 'submit_mult_change', __('Change'), 'b_edit.png', 'change'
1448 $html_output .= PMA_Util::getButtonOrImage(
1449 'submit_mult', 'mult_submit', 'submit_mult_drop',
1450 __('Drop'), 'b_drop.png', 'drop'
1452 if ('ARCHIVE' != $tbl_storage_engine) {
1453 $html_output .= PMA_Util::getButtonOrImage(
1454 'submit_mult', 'mult_submit', 'submit_mult_primary',
1455 __('Primary'), 'b_primary.png', 'primary'
1457 $html_output .= PMA_Util::getButtonOrImage(
1458 'submit_mult', 'mult_submit', 'submit_mult_unique',
1459 __('Unique'), 'b_unique.png', 'unique'
1461 $html_output .= PMA_Util::getButtonOrImage(
1462 'submit_mult', 'mult_submit', 'submit_mult_index',
1463 __('Index'), 'b_index.png', 'index'
1467 if (! empty($tbl_storage_engine) && $tbl_storage_engine == 'MYISAM') {
1468 $html_output .= PMA_Util::getButtonOrImage(
1469 'submit_mult', 'mult_submit', 'submit_mult_spatial',
1470 __('Spatial'), 'b_spatial.png', 'spatial'
1473 if (! empty($tbl_storage_engine)
1474 && ($tbl_storage_engine == 'MYISAM'
1475 || $tbl_storage_engine == 'ARIA'
1476 || $tbl_storage_engine == 'MARIA')
1478 $html_output .= PMA_Util::getButtonOrImage(
1479 'submit_mult', 'mult_submit', 'submit_mult_fulltext',
1480 __('Fulltext'), 'b_ftext.png', 'ftext'
1483 if ($GLOBALS['cfgRelation']['central_columnswork']) {
1484 $html_output .= PMA_Util::getButtonOrImage(
1485 'submit_mult', 'mult_submit', 'submit_mult_central_columns_add',
1486 __('Add to central columns'), 'centralColumns_add.png',
1487 'add_to_central_columns'
1489 $html_output .= PMA_Util::getButtonOrImage(
1490 'submit_mult', 'mult_submit', 'submit_mult_central_columns_remove',
1491 __('Remove from central columns'), 'centralColumns_delete.png',
1492 'remove_from_central_columns'
1496 return $html_output;
1500 * Get HTML for move columns dialog
1502 * @return string $html_output
1504 function PMA_getHtmlDivForMoveColumnsDialog()
1506 $html_output = '<div id="move_columns_dialog" '
1507 . 'title="' . __('Move columns') . '" style="display: none">';
1509 $html_output .= '<p>'
1510 . __('Move the columns by dragging them up and down.') . '</p>';
1512 $html_output .= '<form action="tbl_structure.php">'
1513 . '<div>'
1514 . PMA_URL_getHiddenInputs($GLOBALS['db'], $GLOBALS['table'])
1515 . '<ul></ul>'
1516 . '</div>'
1517 . '</form>'
1518 . '</div>';
1520 return $html_output;
1524 * Get HTML for edit views'
1526 * @param string $url_params URL parameters
1528 * @return string $html_output
1530 function PMA_getHtmlForEditView($url_params)
1532 $query = "SELECT `VIEW_DEFINITION`, `CHECK_OPTION`, `DEFINER`, `SECURITY_TYPE`"
1533 . " FROM `INFORMATION_SCHEMA`.`VIEWS`"
1534 . " WHERE TABLE_SCHEMA='" . PMA_Util::sqlAddSlashes($GLOBALS['db']) . "'"
1535 . " AND TABLE_NAME='" . PMA_Util::sqlAddSlashes($GLOBALS['table']) . "';";
1536 $item = $GLOBALS['dbi']->fetchSingleRow($query);
1538 $view = array(
1539 'operation' => 'alter',
1540 'definer' => $item['DEFINER'],
1541 'sql_security' => $item['SECURITY_TYPE'],
1542 'name' => $GLOBALS['table'],
1543 'as' => $item['VIEW_DEFINITION'],
1544 'with' => $item['CHECK_OPTION'],
1546 $url = 'view_create.php' . PMA_URL_getCommon($url_params) . '&amp;';
1547 $url .= implode(
1548 '&amp;',
1549 array_map(
1550 function ($key, $val) {
1551 return 'view[' . urlencode($key) . ']=' . urlencode($val);
1553 array_keys($view),
1554 $view
1557 $html_output = PMA_Util::linkOrButton(
1558 $url,
1559 PMA_Util::getIcon('b_edit.png', __('Edit view'), true)
1561 return $html_output;
1565 * Get HTML links for 'Print view', 'Relation view', 'Propose table structure',
1566 * 'Track table' and 'Move columns'
1568 * @param string $url_query url query
1569 * @param boolean $tbl_is_view whether table is view or not
1570 * @param boolean $db_is_system_schema whether db is information schema or not
1571 * @param string $tbl_storage_engine table storage engine
1572 * @param array $cfgRelation current relation parameters
1574 * @return string $html_output
1576 function PMA_getHtmlForOptionalActionLinks($url_query, $tbl_is_view,
1577 $db_is_system_schema, $tbl_storage_engine, $cfgRelation
1579 $html_output = '<a href="tbl_printview.php?' . $url_query
1580 . '" target="print_view">'
1581 . PMA_Util::getIcon('b_print.png', __('Print view'), true)
1582 . '</a>';
1584 if (! $tbl_is_view && ! $db_is_system_schema) {
1585 // if internal relations are available, or foreign keys are supported
1586 // ($tbl_storage_engine comes from libraries/tbl_info.inc.php
1588 if ($cfgRelation['relwork']
1589 || PMA_Util::isForeignKeySupported($tbl_storage_engine)
1591 $html_output .= '<a href="tbl_relation.php?' . $url_query . '">'
1592 . PMA_Util::getIcon(
1593 'b_relations.png', __('Relation view'), true
1595 . '</a>';
1597 if (!PMA_DRIZZLE) {
1598 $html_output .= '<a href="sql.php?' . $url_query
1599 . '&amp;session_max_rows=all&amp;sql_query=' . urlencode(
1600 'SELECT * FROM ' . PMA_Util::backquote($GLOBALS['table'])
1601 . ' PROCEDURE ANALYSE()'
1602 ) . '">'
1603 . PMA_Util::getIcon(
1604 'b_tblanalyse.png',
1605 __('Propose table structure'),
1606 true
1608 . '</a>';
1609 $html_output .= PMA_Util::showMySQLDocu('procedure_analyse') . "\n";
1611 if (PMA_Tracker::isActive()) {
1612 $html_output .= '<a href="tbl_tracking.php?' . $url_query . '">'
1613 . PMA_Util::getIcon('eye.png', __('Track table'), true)
1614 . '</a>';
1616 $html_output .= '<a href="#" id="move_columns_anchor">'
1617 . PMA_Util::getIcon('b_move.png', __('Move columns'), true)
1618 . '</a>';
1619 $html_output .= '<a href="normalization.php?' . $url_query . '">'
1620 . PMA_Util::getIcon('normalize.png', __('Improve table structure'), true)
1621 . '</a>';
1624 return $html_output;
1628 * Get HTML snippet for "Add column" feature in structure table
1630 * @param array $columns_list column list array
1632 * @return string $html_output
1634 function PMA_getHtmlForAddColumn($columns_list)
1636 $html_output = '<form method="post" action="tbl_addfield.php" '
1637 . 'id="addColumns" name="addColumns" '
1638 . 'onsubmit="return checkFormElementInRange('
1639 . 'this, \'num_fields\', \'' . str_replace(
1640 '\'',
1641 '\\\'',
1642 __('You have to add at least one column.')
1643 ) . '\', 1)'
1644 . '">';
1646 $html_output .= PMA_URL_getHiddenInputs(
1647 $GLOBALS['db'],
1648 $GLOBALS['table']
1650 if (PMA_Util::showIcons('ActionLinksMode')) {
1651 $html_output .=PMA_Util::getImage(
1652 'b_insrow.png',
1653 __('Add column')
1656 $num_fields = '<input type="number" name="num_fields" '
1657 . 'value="1" onfocus="this.select()" '
1658 . 'min="1" required />';
1659 $html_output .= sprintf(__('Add %s column(s)'), $num_fields);
1661 // I tried displaying the drop-down inside the label but with Firefox
1662 // the drop-down was blinking
1663 $column_selector = '<select name="after_field" '
1664 . 'onclick="this.form.field_where[2].checked=true" '
1665 . 'onchange="this.form.field_where[2].checked=true">';
1667 foreach ($columns_list as $one_column_name) {
1668 $column_selector .= '<option '
1669 . 'value="' . htmlspecialchars($one_column_name) . '">'
1670 . htmlspecialchars($one_column_name)
1671 . '</option>';
1673 $column_selector .= '</select>';
1675 $choices = array(
1676 'last' => __('At End of Table'),
1677 'first' => __('At Beginning of Table'),
1678 'after' => sprintf(__('After %s'), '')
1680 $html_output .= PMA_Util::getRadioFields(
1681 'field_where', $choices, 'last', false
1683 $html_output .= $column_selector;
1684 $html_output .= '<input type="submit" value="' . __('Go') . '" />'
1685 . '</form>';
1687 return $html_output;
1691 * Get HTML snippet for table rows in the Information ->Space usage table
1693 * @param boolean $odd_row whether current row is odd or even
1694 * @param string $name type of usage
1695 * @param string $value value of usage
1696 * @param string $unit unit
1698 * @return string $html_output
1700 function PMA_getHtmlForSpaceUsageTableRow($odd_row, $name, $value, $unit)
1702 $html_output = '<tr class="' . (($odd_row = !$odd_row) ? 'odd' : 'even') . '">';
1703 $html_output .= '<th class="name">' . $name . '</th>';
1704 $html_output .= '<td class="value">' . $value . '</td>';
1705 $html_output .= '<td class="unit">' . $unit . '</td>';
1706 $html_output .= '</tr>';
1708 return $html_output;
1712 * Get HTML for Optimize link if overhead in Information fieldset
1714 * @param string $url_query URL query
1716 * @return string $html_output
1718 function PMA_getHtmlForOptimizeLink($url_query)
1720 $html_output = '<tr class="tblFooters">';
1721 $html_output .= '<td colspan="3" class="center">';
1722 $html_output .= '<a href="sql.php?' . $url_query
1723 . '&pos=0&amp;sql_query=' . urlencode(
1724 'OPTIMIZE TABLE ' . PMA_Util::backquote($GLOBALS['table'])
1726 . '">'
1727 . PMA_Util::getIcon('b_tbloptimize.png', __('Optimize table'))
1728 . '</a>';
1729 $html_output .= '</td>';
1730 $html_output .= '</tr>';
1732 return $html_output;
1736 * Get HTML for 'Row statistics' table row
1738 * @param boolean $odd_row whether current row is odd or even
1739 * @param string $name statement name
1740 * @param mixed $value value
1742 * @return string $html_output
1744 function PMA_getHtmlForRowStatsTableRow($odd_row, $name, $value)
1746 $html_output = '<tr class="' . (($odd_row = !$odd_row) ? 'odd' : 'even') . '">';
1747 $html_output .= '<th class="name">' . $name . '</th>';
1748 $html_output .= '<td class="value">' . $value . '</td>';
1749 $html_output .= '</tr>';
1751 return $html_output;
1755 * Get HTML snippet for display Row statistics table
1757 * @param array $showtable show table array
1758 * @param string $tbl_collation table collation
1759 * @param boolean $is_innodb whether table is innob or not
1760 * @param boolean $mergetable Checks if current table is a merge table
1761 * @param integer $avg_size average size
1762 * @param string $avg_unit average unit
1764 * @return string $html_output
1766 function getHtmlForRowStatsTable($showtable, $tbl_collation,
1767 $is_innodb, $mergetable, $avg_size, $avg_unit
1769 $odd_row = false;
1770 $html_output = '<table id="tablerowstats" class="data">';
1771 $html_output .= '<caption class="tblHeaders">'
1772 . __('Row statistics') . '</caption>';
1773 $html_output .= '<tbody>';
1775 if (isset($showtable['Row_format'])) {
1776 if ($showtable['Row_format'] == 'Fixed') {
1777 $value = __('static');
1778 } elseif ($showtable['Row_format'] == 'Dynamic') {
1779 $value = __('dynamic');
1780 } else {
1781 $value = $showtable['Row_format'];
1783 $html_output .= PMA_getHtmlForRowStatsTableRow(
1784 $odd_row, __('Format'), $value
1786 $odd_row = !$odd_row;
1788 if (! empty($showtable['Create_options'])) {
1789 if ($showtable['Create_options'] == 'partitioned') {
1790 $value = __('partitioned');
1791 } else {
1792 $value = $showtable['Create_options'];
1794 $html_output .= PMA_getHtmlForRowStatsTableRow(
1795 $odd_row, __('Options'), $value
1797 $odd_row = !$odd_row;
1799 if (!empty($tbl_collation)) {
1800 $value = '<dfn title="' . PMA_getCollationDescr($tbl_collation) . '">'
1801 . $tbl_collation . '</dfn>';
1802 $html_output .= PMA_getHtmlForRowStatsTableRow(
1803 $odd_row, __('Collation'), $value
1805 $odd_row = !$odd_row;
1807 if (!$is_innodb && isset($showtable['Rows'])) {
1808 $html_output .= PMA_getHtmlForRowStatsTableRow(
1809 $odd_row,
1810 __('Rows'),
1811 PMA_Util::formatNumber($showtable['Rows'], 0)
1813 $odd_row = !$odd_row;
1815 if (!$is_innodb
1816 && isset($showtable['Avg_row_length'])
1817 && $showtable['Avg_row_length'] > 0
1819 list($avg_row_length_value, $avg_row_length_unit)
1820 = PMA_Util::formatByteDown(
1821 $showtable['Avg_row_length'],
1825 $html_output .= PMA_getHtmlForRowStatsTableRow(
1826 $odd_row,
1827 __('Row length'),
1828 ($avg_row_length_value . ' ' . $avg_row_length_unit)
1830 unset($avg_row_length_value, $avg_row_length_unit);
1831 $odd_row = !$odd_row;
1833 if (!$is_innodb
1834 && isset($showtable['Data_length'])
1835 && $showtable['Rows'] > 0
1836 && $mergetable == false
1838 $html_output .= PMA_getHtmlForRowStatsTableRow(
1839 $odd_row,
1840 __('Row size'),
1841 ($avg_size . ' ' . $avg_unit)
1843 $odd_row = !$odd_row;
1845 if (isset($showtable['Auto_increment'])) {
1846 $html_output .= PMA_getHtmlForRowStatsTableRow(
1847 $odd_row,
1848 __('Next autoindex'),
1849 PMA_Util::formatNumber($showtable['Auto_increment'], 0)
1851 $odd_row = !$odd_row;
1853 if (isset($showtable['Create_time'])) {
1854 $html_output .= PMA_getHtmlForRowStatsTableRow(
1855 $odd_row,
1856 __('Creation'),
1857 PMA_Util::localisedDate(strtotime($showtable['Create_time']))
1859 $odd_row = !$odd_row;
1861 if (isset($showtable['Update_time'])) {
1862 $html_output .= PMA_getHtmlForRowStatsTableRow(
1863 $odd_row,
1864 __('Last update'),
1865 PMA_Util::localisedDate(strtotime($showtable['Update_time']))
1867 $odd_row = !$odd_row;
1869 if (isset($showtable['Check_time'])) {
1870 $html_output .= PMA_getHtmlForRowStatsTableRow(
1871 $odd_row,
1872 __('Last check'),
1873 PMA_Util::localisedDate(strtotime($showtable['Check_time']))
1876 $html_output .= '</tbody>'
1877 . '</table>';
1879 return $html_output;
1883 * Get HTML snippet for action row in structure table,
1884 * This function returns common HTML <td> for Primary, Unique, Index,
1885 * Spatial actions
1887 * @param string $type column type
1888 * @param string $tbl_storage_engine table storage engine
1889 * @param string $class class attribute for <td>
1890 * @param boolean $hasField has field
1891 * @param boolean $hasLinkClass has <a> the class attribute
1892 * @param string $url_query url query
1893 * @param object|boolean $primary primary if set, false otherwise
1894 * @param string $syntax Sql syntax
1895 * @param string $message message to show
1896 * @param string $action action
1897 * @param array $titles titles array
1898 * @param array $row current row
1899 * @param boolean $isPrimary is primary action
1901 * @return string $html_output
1903 function PMA_getHtmlForActionRowInStructureTable($type, $tbl_storage_engine,
1904 $class, $hasField, $hasLinkClass, $url_query, $primary, $syntax,
1905 $message, $action, $titles, $row, $isPrimary
1907 $html_output = '<li class="' . $class . '">';
1909 if ($type == 'text'
1910 || $type == 'blob'
1911 || 'ARCHIVE' == $tbl_storage_engine
1912 || $hasField
1914 $html_output .= $titles['No' . $action];
1915 } else {
1916 $html_output .= '<a rel="samepage" '
1917 . ($hasLinkClass ? 'class="ajax add_primary_key_anchor" ' :
1918 ($action=='Index' ? 'class="ajax add_index_anchor"' :
1919 ($action=='Unique' ? 'class="ajax add_unique_anchor"' : ' ')
1922 . ' href="sql.php?' . $url_query . '&amp;sql_query='
1923 . urlencode(
1924 'ALTER TABLE ' . PMA_Util::backquote($GLOBALS['table'])
1925 . ($isPrimary ? ($primary ? ' DROP PRIMARY KEY,' : '') : '')
1926 . ' ' . $syntax . '('
1927 . PMA_Util::backquote($row['Field']) . ');'
1929 . '&amp;message_to_show=' . urlencode(
1930 sprintf(
1931 $message,
1932 htmlspecialchars($row['Field'])
1934 ) . '" >'
1935 . $titles[$action] . '</a>';
1937 $html_output .= '</li>';
1939 return $html_output;
1943 * Get HTML for fulltext action
1945 * @param string $tbl_storage_engine table storage engine
1946 * @param string $type column type
1947 * @param string $url_query url query
1948 * @param array $row current row
1949 * @param array $titles titles array
1951 * @return string $html_output
1953 function PMA_getHtmlForFullTextAction($tbl_storage_engine, $type, $url_query,
1954 $row, $titles
1956 $html_output = '<li class="fulltext nowrap">';
1957 if (! empty($tbl_storage_engine)
1958 && ($tbl_storage_engine == 'MYISAM'
1959 || $tbl_storage_engine == 'ARIA'
1960 || $tbl_storage_engine == 'MARIA'
1961 || ($tbl_storage_engine == 'INNODB' && PMA_MYSQL_INT_VERSION >= 50604))
1962 && (strpos($type, 'text') !== false || strpos($type, 'char') !== false)
1964 $html_output .= '<a rel="samepage" href="sql.php?' . $url_query
1965 . '&amp;sql_query='
1966 . urlencode(
1967 'ALTER TABLE ' . PMA_Util::backquote($GLOBALS['table'])
1968 . ' ADD FULLTEXT(' . PMA_Util::backquote($row['Field'])
1969 . ');'
1971 . '&amp;message_to_show='
1972 . urlencode(
1973 sprintf(
1974 __('An index has been added on %s.'),
1975 htmlspecialchars($row['Field'])
1978 . '">';
1979 $html_output .= $titles['IdxFulltext'] . '</a>';
1980 } else {
1981 $html_output .= $titles['NoIdxFulltext'];
1983 $html_output .= '</li>';
1984 return $html_output;
1988 * Get HTML snippet for "Distinc Value" action
1990 * @param string $url_query url query
1991 * @param array $row current row
1992 * @param array $titles titles array
1994 * @return string $html_output
1996 function PMA_getHtmlForDistinctValueAction($url_query, $row, $titles)
1998 $html_output = '<li class="browse nowrap">';
1999 $html_output .= '<a href="sql.php?' . $url_query . '&amp;sql_query='
2000 . urlencode(
2001 'SELECT COUNT(*) AS ' . PMA_Util::backquote(__('Rows'))
2002 . ', ' . PMA_Util::backquote($row['Field'])
2003 . ' FROM ' . PMA_Util::backquote($GLOBALS['table'])
2004 . ' GROUP BY ' . PMA_Util::backquote($row['Field'])
2005 . ' ORDER BY ' . PMA_Util::backquote($row['Field'])
2007 . '">'
2008 . $titles['DistinctValues']
2009 . '</a>';
2010 $html_output .= '</li>';
2012 return $html_output;
2016 * Get HTML snippet for Actions in table structure
2018 * @param string $type column type
2019 * @param string $tbl_storage_engine table storage engine
2020 * @param object|boolean $primary primary if set,
2021 * false otherwise
2022 * @param string $field_name column name
2023 * @param string $url_query url query
2024 * @param array $titles titles array
2025 * @param array $row current row
2026 * @param string $rownum row number
2027 * @param array $hidden_titles hidden titles
2028 * @param array $columns_with_unique_index columns with unique index
2029 * @param boolean $isInCentralColumns set if column in central
2030 * columns list
2032 * @return string $html_output;
2034 function PMA_getHtmlForActionsInTableStructure($type, $tbl_storage_engine,
2035 $primary, $field_name, $url_query, $titles, $row, $rownum, $hidden_titles,
2036 $columns_with_unique_index, $isInCentralColumns
2038 $html_output = '<td><ul class="table-structure-actions resizable-menu">';
2039 $html_output .= PMA_getHtmlForActionRowInStructureTable(
2040 $type, $tbl_storage_engine,
2041 'primary nowrap',
2042 ($primary && $primary->hasColumn($field_name)),
2043 true, $url_query, $primary,
2044 'ADD PRIMARY KEY',
2045 __('A primary key has been added on %s.'),
2046 'Primary', $titles, $row, true
2048 $html_output .= PMA_getHtmlForActionRowInStructureTable(
2049 $type, $tbl_storage_engine,
2050 'add_unique unique nowrap',
2051 isset($columns_with_unique_index[$field_name]),
2052 false, $url_query, $primary, 'ADD UNIQUE',
2053 __('An index has been added on %s.'),
2054 'Unique', $titles, $row, false
2056 $html_output .= PMA_getHtmlForActionRowInStructureTable(
2057 $type, $tbl_storage_engine,
2058 'add_index nowrap', false, false, $url_query,
2059 $primary, 'ADD INDEX', __('An index has been added on %s.'),
2060 'Index', $titles, $row, false
2062 if (!PMA_DRIZZLE) {
2063 $spatial_types = array(
2064 'geometry', 'point', 'linestring', 'polygon', 'multipoint',
2065 'multilinestring', 'multipolygon', 'geomtrycollection'
2067 $html_output .= PMA_getHtmlForActionRowInStructureTable(
2068 $type, $tbl_storage_engine,
2069 'spatial nowrap',
2070 (! in_array($type, $spatial_types)
2071 || 'MYISAM' != $tbl_storage_engine
2073 false, $url_query, $primary, 'ADD SPATIAL',
2074 __('An index has been added on %s.'), 'Spatial',
2075 $titles, $row, false
2078 // FULLTEXT is possible on TEXT, CHAR and VARCHAR
2079 $html_output .= PMA_getHtmlForFullTextAction(
2080 $tbl_storage_engine, $type, $url_query, $row, $titles
2083 $html_output .= PMA_getHtmlForDistinctValueAction($url_query, $row, $titles);
2084 if ($GLOBALS['cfgRelation']['central_columnswork']) {
2085 $html_output .= '<li class="browse nowrap">';
2086 if ($isInCentralColumns) {
2087 $html_output .=
2088 '<a href="#" onclick=$("input:checkbox").removeAttr("checked");'
2089 . '$("#checkbox_row_' . $rownum . '").attr("checked","checked");'
2090 . '$("button[value=remove_from_central_columns]").click();>'
2091 . PMA_Util::getIcon(
2092 'centralColumns_delete.png',
2093 __('Remove from central columns')
2095 . '</a>';
2096 } else {
2097 $html_output .=
2098 '<a href="#" onclick=$("input:checkbox").removeAttr("checked");'
2099 . '$("#checkbox_row_' . $rownum . '").attr("checked","checked");'
2100 . '$("button[value=add_to_central_columns]").click();>'
2101 . PMA_Util::getIcon(
2102 'centralColumns_add.png',
2103 __('Add to central columns')
2105 . '</a>';
2107 $html_output .= '</li>';
2109 $html_output .= '<div class="clearfloat"></div></ul></td>';
2110 return $html_output;
2114 * Get hidden action titles (image and string)
2116 * @return array $hidden_titles
2118 function PMA_getHiddenTitlesArray()
2120 $hidden_titles = array();
2121 $hidden_titles['DistinctValues'] = PMA_Util::getIcon(
2122 'b_browse.png', __('Distinct values'), true
2124 $hidden_titles['Primary'] = PMA_Util::getIcon(
2125 'b_primary.png', __('Add primary key'), true
2127 $hidden_titles['NoPrimary'] = PMA_Util::getIcon(
2128 'bd_primary.png', __('Add primary key'), true
2130 $hidden_titles['Index'] = PMA_Util::getIcon(
2131 'b_index.png', __('Add index'), true
2133 $hidden_titles['NoIndex'] = PMA_Util::getIcon(
2134 'bd_index.png', __('Add index'), true
2136 $hidden_titles['Unique'] = PMA_Util::getIcon(
2137 'b_unique.png', __('Add unique index'), true
2139 $hidden_titles['NoUnique'] = PMA_Util::getIcon(
2140 'bd_unique.png', __('Add unique index'), true
2142 $hidden_titles['Spatial'] = PMA_Util::getIcon(
2143 'b_spatial.png', __('Add SPATIAL index'), true
2145 $hidden_titles['NoSpatial'] = PMA_Util::getIcon(
2146 'bd_spatial.png', __('Add SPATIAL index'), true
2148 $hidden_titles['IdxFulltext'] = PMA_Util::getIcon(
2149 'b_ftext.png', __('Add FULLTEXT index'), true
2151 $hidden_titles['NoIdxFulltext'] = PMA_Util::getIcon(
2152 'bd_ftext.png', __('Add FULLTEXT index'), true
2155 return $hidden_titles;
2159 * Get action titles (image or string array
2161 * @return array $titles
2163 function PMA_getActionTitlesArray()
2165 $titles = array();
2166 $titles['Change']
2167 = PMA_Util::getIcon('b_edit.png', __('Change'));
2168 $titles['Drop']
2169 = PMA_Util::getIcon('b_drop.png', __('Drop'));
2170 $titles['NoDrop']
2171 = PMA_Util::getIcon('b_drop.png', __('Drop'));
2172 $titles['Primary']
2173 = PMA_Util::getIcon('b_primary.png', __('Primary'));
2174 $titles['Index']
2175 = PMA_Util::getIcon('b_index.png', __('Index'));
2176 $titles['Unique']
2177 = PMA_Util::getIcon('b_unique.png', __('Unique'));
2178 $titles['Spatial']
2179 = PMA_Util::getIcon('b_spatial.png', __('Spatial'));
2180 $titles['IdxFulltext']
2181 = PMA_Util::getIcon('b_ftext.png', __('Fulltext'));
2182 $titles['NoPrimary']
2183 = PMA_Util::getIcon('bd_primary.png', __('Primary'));
2184 $titles['NoIndex']
2185 = PMA_Util::getIcon('bd_index.png', __('Index'));
2186 $titles['NoUnique']
2187 = PMA_Util::getIcon('bd_unique.png', __('Unique'));
2188 $titles['NoSpatial']
2189 = PMA_Util::getIcon('bd_spatial.png', __('Spatial'));
2190 $titles['NoIdxFulltext']
2191 = PMA_Util::getIcon('bd_ftext.png', __('Fulltext'));
2192 $titles['DistinctValues']
2193 = PMA_Util::getIcon('b_browse.png', __('Distinct values'));
2195 return $titles;
2199 * Get HTML snippet for display table statistics
2201 * @param array $showtable full table status info
2202 * @param integer $table_info_num_rows table info number of rows
2203 * @param boolean $tbl_is_view whether table is view or not
2204 * @param boolean $db_is_system_schema whether db is information schema or not
2205 * @param string $tbl_storage_engine table storage engine
2206 * @param string $url_query url query
2207 * @param string $tbl_collation table collation
2209 * @return string $html_output
2211 function PMA_getHtmlForDisplayTableStats($showtable, $table_info_num_rows,
2212 $tbl_is_view, $db_is_system_schema, $tbl_storage_engine, $url_query,
2213 $tbl_collation
2215 $html_output = '<div id="tablestatistics">';
2216 if (empty($showtable)) {
2217 $showtable = PMA_Table::sGetStatusInfo(
2218 $GLOBALS['db'], $GLOBALS['table'], null, true
2222 $is_innodb = (isset($showtable['Type']) && $showtable['Type'] == 'InnoDB');
2224 // Gets some sizes
2226 $mergetable = PMA_Table::isMerge($GLOBALS['db'], $GLOBALS['table']);
2228 // this is to display for example 261.2 MiB instead of 268k KiB
2229 $max_digits = 3;
2230 $decimals = 1;
2231 list($data_size, $data_unit) = PMA_Util::formatByteDown(
2232 $showtable['Data_length'], $max_digits, $decimals
2234 if ($mergetable == false) {
2235 list($index_size, $index_unit) = PMA_Util::formatByteDown(
2236 $showtable['Index_length'], $max_digits, $decimals
2239 // InnoDB returns a huge value in Data_free, do not use it
2240 if (! $is_innodb
2241 && isset($showtable['Data_free'])
2242 && $showtable['Data_free'] > 0
2244 list($free_size, $free_unit) = PMA_Util::formatByteDown(
2245 $showtable['Data_free'], $max_digits, $decimals
2247 list($effect_size, $effect_unit) = PMA_Util::formatByteDown(
2248 $showtable['Data_length'] + $showtable['Index_length']
2249 - $showtable['Data_free'],
2250 $max_digits, $decimals
2252 } else {
2253 list($effect_size, $effect_unit) = PMA_Util::formatByteDown(
2254 $showtable['Data_length'] + $showtable['Index_length'],
2255 $max_digits, $decimals
2258 list($tot_size, $tot_unit) = PMA_Util::formatByteDown(
2259 $showtable['Data_length'] + $showtable['Index_length'],
2260 $max_digits, $decimals
2262 if ($table_info_num_rows > 0) {
2263 list($avg_size, $avg_unit) = PMA_Util::formatByteDown(
2264 ($showtable['Data_length'] + $showtable['Index_length'])
2265 / $showtable['Rows'],
2266 6, 1
2270 // Displays them
2271 $odd_row = false;
2273 $html_output .= '<fieldset>'
2274 . '<legend>' . __('Information') . '</legend>'
2275 . '<a id="showusage"></a>';
2277 if (! $tbl_is_view && ! $db_is_system_schema) {
2278 $html_output .= '<table id="tablespaceusage" class="data">'
2279 . '<caption class="tblHeaders">' . __('Space usage') . '</caption>'
2280 . '<tbody>';
2282 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2283 $odd_row, __('Data'), $data_size, $data_unit
2285 $odd_row = !$odd_row;
2287 if (isset($index_size)) {
2288 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2289 $odd_row, __('Index'), $index_size, $index_unit
2291 $odd_row = !$odd_row;
2294 if (isset($free_size)) {
2295 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2296 $odd_row, __('Overhead'), $free_size, $free_unit
2298 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2299 $odd_row, __('Effective'), $effect_size, $effect_unit
2301 $odd_row = !$odd_row;
2303 if (isset($tot_size) && $mergetable == false) {
2304 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2305 $odd_row, __('Total'), $tot_size, $tot_unit
2307 $odd_row = !$odd_row;
2309 // Optimize link if overhead
2310 if (isset($free_size) && !PMA_DRIZZLE
2311 && ($tbl_storage_engine == 'MYISAM'
2312 || $tbl_storage_engine == 'ARIA'
2313 || $tbl_storage_engine == 'MARIA'
2314 || $tbl_storage_engine == 'BDB')
2316 $html_output .= PMA_getHtmlForOptimizeLink($url_query);
2318 $html_output .= '</tbody>'
2319 . '</table>';
2322 $html_output .= getHtmlForRowStatsTable(
2323 $showtable, $tbl_collation,
2324 $is_innodb, $mergetable,
2325 (isset ($avg_size) ? $avg_size : ''),
2326 (isset ($avg_unit) ? $avg_unit : '')
2329 $html_output .= '</fieldset>'
2330 . '</div>';
2332 return $html_output;
2336 * Displays HTML for changing one or more columns
2338 * @param string $db database name
2339 * @param string $table table name
2340 * @param array $selected the selected columns
2341 * @param string $action target script to call
2343 * @return boolean $regenerate true if error occurred
2346 function PMA_displayHtmlForColumnChange($db, $table, $selected, $action)
2348 // $selected comes from multi_submits.inc.php
2349 if (empty($selected)) {
2350 $selected[] = $_REQUEST['field'];
2351 $selected_cnt = 1;
2352 } else { // from a multiple submit
2353 $selected_cnt = count($selected);
2357 * @todo optimize in case of multiple fields to modify
2359 $fields_meta = array();
2360 for ($i = 0; $i < $selected_cnt; $i++) {
2361 $fields_meta[] = $GLOBALS['dbi']->getColumns(
2362 $db, $table, $selected[$i], true
2365 $num_fields = count($fields_meta);
2366 // set these globals because tbl_columns_definition_form.inc.php
2367 // verifies them
2368 // @todo: refactor tbl_columns_definition_form.inc.php so that it uses
2369 // function params
2370 $GLOBALS['action'] = 'tbl_structure.php';
2371 $GLOBALS['num_fields'] = $num_fields;
2373 // Get more complete field information.
2374 // For now, this is done to obtain MySQL 4.1.2+ new TIMESTAMP options
2375 // and to know when there is an empty DEFAULT value.
2376 // Later, if the analyser returns more information, it
2377 // could be executed to replace the info given by SHOW FULL COLUMNS FROM.
2379 * @todo put this code into a require()
2380 * or maybe make it part of $GLOBALS['dbi']->getColumns();
2383 // We also need this to correctly learn if a TIMESTAMP is NOT NULL, since
2384 // SHOW FULL COLUMNS says NULL and SHOW CREATE TABLE says NOT NULL (tested
2385 // in MySQL 4.0.25).
2387 $show_create_table = $GLOBALS['dbi']->fetchValue(
2388 'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.'
2389 . PMA_Util::backquote($table),
2390 0, 1
2392 $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
2393 unset($show_create_table);
2395 * Form for changing properties.
2397 include 'libraries/tbl_columns_definition_form.inc.php';
2401 * Verifies if some elements of a column have changed
2403 * @param integer $i column index in the request
2405 * @return boolean $alterTableNeeded true if we need to generate ALTER TABLE
2408 function PMA_columnNeedsAlterTable($i)
2410 // these two fields are checkboxes so might not be part of the
2411 // request; therefore we define them to avoid notices below
2412 if (! isset($_REQUEST['field_null'][$i])) {
2413 $_REQUEST['field_null'][$i] = 'NO';
2415 if (! isset($_REQUEST['field_extra'][$i])) {
2416 $_REQUEST['field_extra'][$i] = '';
2419 // field_name does not follow the convention (corresponds to field_orig)
2420 if ($_REQUEST['field_attribute'][$i] != $_REQUEST['field_attribute_orig'][$i]
2421 || $_REQUEST['field_collation'][$i] != $_REQUEST['field_collation_orig'][$i]
2422 || $_REQUEST['field_comments'][$i] != $_REQUEST['field_comments_orig'][$i]
2423 || $_REQUEST['field_default_value'][$i] != $_REQUEST['field_default_value_orig'][$i]
2424 || $_REQUEST['field_default_type'][$i] != $_REQUEST['field_default_type_orig'][$i]
2425 || $_REQUEST['field_extra'][$i] != $_REQUEST['field_extra_orig'][$i]
2426 || $_REQUEST['field_length'][$i] != $_REQUEST['field_length_orig'][$i]
2427 || $_REQUEST['field_name'][$i] != $_REQUEST['field_orig'][$i]
2428 || $_REQUEST['field_null'][$i] != $_REQUEST['field_null_orig'][$i]
2429 || $_REQUEST['field_type'][$i] != $_REQUEST['field_type_orig'][$i]
2430 || ! empty($_REQUEST['field_move_to'][$i])
2432 return true;
2433 } else {
2434 return false;
2439 * Update the table's structure based on $_REQUEST
2441 * @param string $db database name
2442 * @param string $table table name
2444 * @return boolean $regenerate true if error occurred
2447 function PMA_updateColumns($db, $table)
2449 $err_url = 'tbl_structure.php?' . PMA_URL_getCommon($db, $table);
2450 $regenerate = false;
2451 $field_cnt = count($_REQUEST['field_name']);
2452 $key_fields = array();
2453 $changes = array();
2455 for ($i = 0; $i < $field_cnt; $i++) {
2456 if (PMA_columnNeedsAlterTable($i)) {
2457 $changes[] = 'CHANGE ' . PMA_Table::generateAlter(
2458 isset($_REQUEST['field_orig'][$i])
2459 ? $_REQUEST['field_orig'][$i]
2460 : '',
2461 $_REQUEST['field_name'][$i],
2462 $_REQUEST['field_type'][$i],
2463 $_REQUEST['field_length'][$i],
2464 $_REQUEST['field_attribute'][$i],
2465 isset($_REQUEST['field_collation'][$i])
2466 ? $_REQUEST['field_collation'][$i]
2467 : '',
2468 isset($_REQUEST['field_null'][$i])
2469 ? $_REQUEST['field_null'][$i]
2470 : 'NOT NULL',
2471 $_REQUEST['field_default_type'][$i],
2472 $_REQUEST['field_default_value'][$i],
2473 isset($_REQUEST['field_extra'][$i])
2474 ? $_REQUEST['field_extra'][$i]
2475 : false,
2476 isset($_REQUEST['field_comments'][$i])
2477 ? $_REQUEST['field_comments'][$i]
2478 : '',
2479 $key_fields,
2481 isset($_REQUEST['field_move_to'][$i])
2482 ? $_REQUEST['field_move_to'][$i]
2483 : ''
2486 } // end for
2488 $response = PMA_Response::getInstance();
2490 if (count($changes) > 0 || isset($_REQUEST['preview_sql'])) {
2491 // Builds the primary keys statements and updates the table
2492 $key_query = '';
2494 * this is a little bit more complex
2496 * @todo if someone selects A_I when altering a column we need to check:
2497 * - no other column with A_I
2498 * - the column has an index, if not create one
2502 // To allow replication, we first select the db to use
2503 // and then run queries on this db.
2504 if (! $GLOBALS['dbi']->selectDb($db)) {
2505 PMA_Util::mysqlDie(
2506 $GLOBALS['dbi']->getError(),
2507 'USE ' . PMA_Util::backquote($db) . ';',
2508 false,
2509 $err_url
2512 $sql_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ';
2513 $sql_query .= implode(', ', $changes) . $key_query;
2514 $sql_query .= ';';
2516 // If there is a request for SQL previewing.
2517 if (isset($_REQUEST['preview_sql'])) {
2518 PMA_previewSQL(count($changes) > 0 ? $sql_query : '');
2521 $result = $GLOBALS['dbi']->tryQuery($sql_query);
2523 if ($result !== false) {
2524 $message = PMA_Message::success(
2525 __('Table %1$s has been altered successfully.')
2527 $message->addParam($table);
2529 $response->addHTML(
2530 PMA_Util::getMessage($message, $sql_query, 'success')
2532 } else {
2533 // An error happened while inserting/updating a table definition
2534 $response->isSuccess(false);
2535 $response->addJSON(
2536 'message',
2537 PMA_Message::rawError(__('Query error') . ':<br />' . $GLOBALS['dbi']->getError())
2539 $regenerate = true;
2543 include_once 'libraries/transformations.lib.php';
2545 // update field names in relation
2546 if (isset($_REQUEST['field_orig']) && is_array($_REQUEST['field_orig'])) {
2547 foreach ($_REQUEST['field_orig'] as $fieldindex => $fieldcontent) {
2548 if ($_REQUEST['field_name'][$fieldindex] != $fieldcontent) {
2549 PMA_REL_renameField(
2550 $db, $table, $fieldcontent,
2551 $_REQUEST['field_name'][$fieldindex]
2557 // update mime types
2558 if (isset($_REQUEST['field_mimetype'])
2559 && is_array($_REQUEST['field_mimetype'])
2560 && $GLOBALS['cfg']['BrowseMIME']
2562 foreach ($_REQUEST['field_mimetype'] as $fieldindex => $mimetype) {
2563 if (isset($_REQUEST['field_name'][$fieldindex])
2564 && strlen($_REQUEST['field_name'][$fieldindex])
2566 PMA_setMIME(
2567 $db, $table, $_REQUEST['field_name'][$fieldindex],
2568 $mimetype,
2569 $_REQUEST['field_transformation'][$fieldindex],
2570 $_REQUEST['field_transformation_options'][$fieldindex],
2571 $_REQUEST['field_input_transformation'][$fieldindex],
2572 $_REQUEST['field_input_transformation_options'][$fieldindex]
2577 return $regenerate;
2581 * Moves columns in the table's structure based on $_REQUEST
2583 * @param string $db database name
2584 * @param string $table table name
2586 * @return void
2588 function PMA_moveColumns($db, $table)
2590 $GLOBALS['dbi']->selectDb($db);
2593 * load the definitions for all columns
2595 $columns = $GLOBALS['dbi']->getColumnsFull($db, $table);
2596 $column_names = array_keys($columns);
2597 $changes = array();
2598 $we_dont_change_keys = array();
2600 // move columns from first to last
2601 for ($i = 0, $l = count($_REQUEST['move_columns']); $i < $l; $i++) {
2602 $column = $_REQUEST['move_columns'][$i];
2603 // is this column already correctly placed?
2604 if ($column_names[$i] == $column) {
2605 continue;
2608 // it is not, let's move it to index $i
2609 $data = $columns[$column];
2610 $extracted_columnspec = PMA_Util::extractColumnSpec($data['Type']);
2611 if (isset($data['Extra'])
2612 && $data['Extra'] == 'on update CURRENT_TIMESTAMP'
2614 $extracted_columnspec['attribute'] = $data['Extra'];
2615 unset($data['Extra']);
2617 $current_timestamp = false;
2618 if (($data['Type'] == 'timestamp' || $data['Type'] == 'datetime')
2619 && $data['Default'] == 'CURRENT_TIMESTAMP'
2621 $current_timestamp = true;
2623 $default_type
2624 = $data['Null'] === 'YES' && $data['Default'] === null
2625 ? 'NULL'
2626 : ($current_timestamp
2627 ? 'CURRENT_TIMESTAMP'
2628 : ($data['Default'] === null
2629 ? 'NONE'
2630 : 'USER_DEFINED'));
2632 $changes[] = 'CHANGE ' . PMA_Table::generateAlter(
2633 $column,
2634 $column,
2635 strtoupper($extracted_columnspec['type']),
2636 $extracted_columnspec['spec_in_brackets'],
2637 $extracted_columnspec['attribute'],
2638 isset($data['Collation']) ? $data['Collation'] : '',
2639 $data['Null'] === 'YES' ? 'NULL' : 'NOT NULL',
2640 $default_type,
2641 $current_timestamp ? '' : $data['Default'],
2642 isset($data['Extra']) && $data['Extra'] !== '' ? $data['Extra'] : false,
2643 isset($data['COLUMN_COMMENT']) && $data['COLUMN_COMMENT'] !== ''
2644 ? $data['COLUMN_COMMENT'] : false,
2645 $we_dont_change_keys,
2647 $i === 0 ? '-first' : $column_names[$i - 1]
2649 // update current column_names array, first delete old position
2650 for ($j = 0, $ll = count($column_names); $j < $ll; $j++) {
2651 if ($column_names[$j] == $column) {
2652 unset($column_names[$j]);
2655 // insert moved column
2656 array_splice($column_names, $i, 0, $column);
2658 $response = PMA_Response::getInstance();
2659 if (empty($changes)) { // should never happen
2660 $response->isSuccess(false);
2661 exit;
2663 $move_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ';
2664 $move_query .= implode(', ', $changes);
2665 // move columns
2666 $GLOBALS['dbi']->tryQuery($move_query);
2667 $tmp_error = $GLOBALS['dbi']->getError();
2668 if ($tmp_error) {
2669 $response->isSuccess(false);
2670 $response->addJSON('message', PMA_Message::error($tmp_error));
2671 } else {
2672 $message = PMA_Message::success(
2673 __('The columns have been moved successfully.')
2675 $response->addJSON('message', $message);
2676 $response->addJSON('columns', $column_names);
2678 exit;
2682 * Get columns with unique index
2684 * @param string $db database name
2685 * @param string $table tablename
2687 * @return array $columns_with_unique_index An array of columns with unique index,
2688 * with $column name as the array key
2690 function PMA_getColumnsWithUniqueIndex($db ,$table)
2692 $columns_with_unique_index = array();
2693 foreach (PMA_Index::getFromTable($table, $db) as $index) {
2694 if ($index->isUnique() && $index->getChoice() == 'UNIQUE') {
2695 $columns = $index->getColumns();
2696 foreach ($columns as $column_name => $dummy) {
2697 $columns_with_unique_index[$column_name] = 1;
2701 return $columns_with_unique_index;
2705 * Check column names for MySQL reserved words
2707 * @param string $db database name
2708 * @param string $table tablename
2710 * @return array $messages array of PMA_Messages
2712 function PMA_getReservedWordColumnNameMessages($db ,$table)
2714 $messages = array();
2715 if ($GLOBALS['cfg']['ReservedWordDisableWarning'] === false) {
2716 $pma_table = new PMA_Table($table, $db);
2717 $columns = $pma_table->getReservedColumnNames();
2718 if (!empty($columns)) {
2719 foreach ($columns as $column) {
2720 $msg = PMA_message::notice(
2721 __('The column name \'%s\' is a MySQL reserved keyword.')
2723 $msg->addParam($column);
2724 $messages[] = $msg;
2728 return $messages;
2732 * Function to get the type of command for multiple field handling
2734 * @return string
2736 function PMA_getMultipleFieldCommandType()
2738 $submit_mult = null;
2740 if (isset($_REQUEST['submit_mult_change_x'])) {
2741 $submit_mult = 'change';
2742 } elseif (isset($_REQUEST['submit_mult_drop_x'])) {
2743 $submit_mult = 'drop';
2744 } elseif (isset($_REQUEST['submit_mult_primary_x'])) {
2745 $submit_mult = 'primary';
2746 } elseif (isset($_REQUEST['submit_mult_index_x'])) {
2747 $submit_mult = 'index';
2748 } elseif (isset($_REQUEST['submit_mult_unique_x'])) {
2749 $submit_mult = 'unique';
2750 } elseif (isset($_REQUEST['submit_mult_spatial_x'])) {
2751 $submit_mult = 'spatial';
2752 } elseif (isset($_REQUEST['submit_mult_fulltext_x'])) {
2753 $submit_mult = 'ftext';
2754 } elseif (isset($_REQUEST['submit_mult_browse_x'])) {
2755 $submit_mult = 'browse';
2756 } elseif (isset($_REQUEST['submit_mult'])) {
2757 $submit_mult = $_REQUEST['submit_mult'];
2758 } elseif (isset($_REQUEST['mult_btn']) && $_REQUEST['mult_btn'] == __('Yes')) {
2759 $submit_mult = 'row_delete';
2760 if (isset($_REQUEST['selected'])) {
2761 $_REQUEST['selected_fld'] = $_REQUEST['selected'];
2765 return $submit_mult;
2769 * Function to display table browse for selected columns
2771 * @param string $db current database
2772 * @param string $table current table
2773 * @param string $goto goto page url
2774 * @param string $pmaThemeImage URI of the pma theme image
2776 * @return void
2778 function PMA_displayTableBrowseForSelectedColumns($db, $table, $goto,
2779 $pmaThemeImage
2781 $GLOBALS['active_page'] = 'sql.php';
2782 $sql_query = '';
2783 foreach ($_REQUEST['selected_fld'] as $sval) {
2784 if ($sql_query == '') {
2785 $sql_query .= 'SELECT ' . PMA_Util::backquote($sval);
2786 } else {
2787 $sql_query .= ', ' . PMA_Util::backquote($sval);
2790 $sql_query .= ' FROM ' . PMA_Util::backquote($db)
2791 . '.' . PMA_Util::backquote($table);
2793 // Parse and analyze the query
2794 include_once 'libraries/parse_analyze.inc.php';
2796 include_once 'libraries/sql.lib.php';
2798 PMA_executeQueryAndSendQueryResponse(
2799 $analyzed_sql_results, false, $db, $table, null, null, null, false,
2800 null, null, null, null, $goto, $pmaThemeImage, null, null,
2801 null, $sql_query, null, null
2806 * Function to check if a table is already in favorite list.
2808 * @param string $db current database
2809 * @param string $current_table current table
2811 * @return true|false
2813 function PMA_checkFavoriteTable($db, $current_table)
2815 foreach ($_SESSION['tmpval']['favorite_tables'][$GLOBALS['server']] as $key => $value) {
2816 if ($value['db'] == $db && $value['table'] == $current_table) {
2817 return true;
2820 return false;
2824 * Get HTML for favorite anchor.
2826 * @param string $db current database
2827 * @param string $current_table current table
2828 * @param string $titles titles
2830 * @return string The html output
2832 function PMA_getHtmlForFavoriteAnchor($db, $current_table, $titles)
2834 $html_output = '<a ';
2835 $html_output .= 'id="' . md5($current_table['TABLE_NAME'])
2836 . '_favorite_anchor" ';
2837 $html_output .= 'class="ajax favorite_table_anchor';
2839 // Check if current table is already in favorite list.
2840 $already_favorite = PMA_checkFavoriteTable($db, $current_table['TABLE_NAME']);
2841 $fav_params = array('db' => $db,
2842 'ajax_request' => true,
2843 'favorite_table' => $current_table['TABLE_NAME'],
2844 (($already_favorite?'remove':'add') . '_favorite') => true
2846 $fav_url = 'db_structure.php' . PMA_URL_getCommon($fav_params);
2847 $html_output .= '" ';
2848 $html_output .= 'href="' . $fav_url
2849 . '" title="' . ($already_favorite ? __("Remove from Favorites")
2850 : __("Add to Favorites"))
2851 . '" data-favtargets="'
2852 . md5($db . "." . $current_table['TABLE_NAME'])
2853 . '" >'
2854 . (!$already_favorite ? $titles['NoFavorite']
2855 : $titles['Favorite']) . '</a>';
2857 return $html_output;
2861 * Add or remove favorite tables
2863 * @param string $db current database
2865 * @return void
2867 function PMA_addRemoveFavoriteTables($db)
2869 $fav_instance = PMA_RecentFavoriteTable::getInstance('favorite');
2870 $favorite_tables = json_decode($_REQUEST['favorite_tables'], true);
2871 // Required to keep each user's preferences separate.
2872 $user = sha1($GLOBALS['cfg']['Server']['user']);
2874 // Request for Synchronization of favorite tables.
2875 if (isset($_REQUEST['sync_favorite_tables'])) {
2876 PMA_synchronizeFavoriteTables($fav_instance, $user);
2877 exit;
2879 $changes = true;
2880 $msg = '';
2881 $titles = PMA_Util::buildActionTitles();
2882 $favorite_table = $_REQUEST['favorite_table'];
2883 $already_favorite = PMA_checkFavoriteTable($db, $favorite_table);
2885 if (isset($_REQUEST['remove_favorite'])) {
2886 if ($already_favorite) {
2887 // If already in favorite list, remove it.
2888 $fav_instance->remove($db, $favorite_table);
2890 } elseif (isset($_REQUEST['add_favorite'])) {
2891 if (!$already_favorite) {
2892 if (count($fav_instance->getTables()) == $GLOBALS['cfg']['NumFavoriteTables']) {
2893 $changes = false;
2894 $msg = '<div class="error"><img src="themes/dot.gif" '
2895 . 'title="" alt="" class="icon ic_s_error" />'
2896 . __("Favorite List is full!")
2897 . '</div>';
2898 } else {
2899 // Otherwise add to favorite list.
2900 $fav_instance->add($db, $favorite_table);
2905 $favorite_tables[$user] = $fav_instance->getTables();
2906 $ajax_response = PMA_Response::getInstance();
2907 $ajax_response->addJSON(
2908 'changes',
2909 $changes
2911 if ($changes) {
2912 $ajax_response->addJSON(
2913 'user',
2914 $user
2916 $ajax_response->addJSON(
2917 'favorite_tables',
2918 json_encode($favorite_tables)
2920 $ajax_response->addJSON(
2921 'list',
2922 $fav_instance->getHtmlList()
2924 $ajax_response->addJSON(
2925 'anchor',
2926 PMA_getHtmlForFavoriteAnchor(
2927 $db, array('TABLE_NAME' => $favorite_table), $titles
2930 } else {
2931 $ajax_response->addJSON(
2932 'message',
2933 $msg
2939 * Synchronize favorite tables
2941 * @param string $fav_instance PMA_RecentFavoriteTable instance
2942 * @param string $user The user hash
2944 * @return void
2946 function PMA_synchronizeFavoriteTables($fav_instance, $user)
2948 $fav_instance_tables = $fav_instance->getTables();
2950 if (empty($fav_instance_tables)
2951 && isset($favorite_tables[$user])
2953 foreach ($favorite_tables[$user] as $key => $value) {
2954 $fav_instance->add($value['db'], $value['table']);
2957 $favorite_tables[$user] = $fav_instance->getTables();
2959 $ajax_response = PMA_Response::getInstance();
2960 $ajax_response->addJSON(
2961 'favorite_tables',
2962 json_encode($favorite_tables)
2964 $ajax_response->addJSON(
2965 'list',
2966 $fav_instance->getHtmlList()
2968 $server_id = $GLOBALS['server'];
2969 // Set flag when localStorage and pmadb(if present) are in sync.
2970 $_SESSION['tmpval']['favorites_synced'][$server_id] = true;
2974 * Returns Html for show create.
2976 * @param string $db Database name
2977 * @param array $db_objects Array containing DB objects
2979 * @return string Html
2981 function PMA_getHtmlShowCreate($db, $db_objects)
2983 // Main outer container.
2984 $html_output = '<div class="show_create_results">'
2985 . '<h2>' . __('Showing create queries') . '</h2>';
2986 // Table header.
2987 $output_table = '<fieldset>'
2988 . '<legend>%s</legend>'
2989 . '<table class="show_create">'
2990 . '<thead>'
2991 . '<tr>'
2992 . '<th>%s</th>'
2993 . '<th>Create %s</th>'
2994 . '</tr>'
2995 . '</thead>'
2996 . '<tbody>';
2997 // Holds rows html for views.
2998 $views = '';
2999 // Holds rows html for tables.
3000 $tables = '';
3001 // Handles odd, even classes for rows.
3002 // for 'Views'
3003 $odd1 = true;
3004 // for 'Tables'
3005 $odd2 = true;
3006 // Iterate through each object.
3007 foreach ($db_objects as $key => $object) {
3008 // Check if current object is a View or Table.
3009 $isView = PMA_Table::isView($db, $object);
3010 if ($isView) {
3011 $row_class = ($odd1) ? 'odd' : 'even';
3012 $create_data = PMA_getShowCreate($db, $object, 'view');
3013 $views .= '<tr class="' . $row_class . '">'
3014 . '<td><strong>'
3015 . PMA_mimeDefaultFunction($create_data['View'])
3016 . '</strong></td>'
3017 . '<td>'
3018 . PMA_mimeDefaultFunction($create_data['Create View'])
3019 . '</td>'
3020 . '</tr>';
3021 $odd1 = ! $odd1;
3022 } else {
3023 $row_class = ($odd2) ? 'odd' : 'even';
3024 $create_data = PMA_getShowCreate($db, $object, 'table');
3025 $tables .= '<tr class="' . $row_class . '">'
3026 . '<td><strong>'
3027 . PMA_mimeDefaultFunction($create_data['Table'])
3028 . '</strong></td>'
3029 . '<td>'
3030 . PMA_mimeDefaultFunction($create_data['Create Table'])
3031 . '</td>'
3032 . '</tr>';
3033 $odd2 = ! $odd2;
3036 // Prepare table header for each type of object.
3037 if (! empty($tables)) {
3038 $title = __('Tables');
3039 $tables = sprintf($output_table, $title, 'Table', 'Table')
3040 . $tables
3041 . '</tbody></table></fieldset>';
3043 if (! empty($views)) {
3044 $title = __('Views');
3045 $views = sprintf($output_table, $title, 'View', 'View')
3046 . $views
3047 . '</tbody></table></fieldset>';
3049 // Compile the final html.
3050 $html_output .= $tables . $views . '</div>';
3052 return $html_output;
3056 * Return 'SHOW CREATE' query for a DB object
3058 * @param string $db Database name
3059 * @param string $db_object Database object name
3060 * @param string $type Type of object (table or view)
3062 * @return mysqli_result collection | boolean(false)
3064 function PMA_getShowCreate($db, $db_object, $type = 'table')
3066 // 'SHOW CREATE' SQL query for specific type of DB object.
3067 switch ($type) {
3068 case 'table':
3069 $sql_query = 'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.'
3070 . PMA_Util::backquote($db_object);
3071 break;
3072 case 'view':
3073 $sql_query = 'SHOW CREATE VIEW ' . PMA_Util::backquote($db) . '.'
3074 . PMA_Util::backquote($db_object);
3075 break;
3077 // Execute the query.
3078 $result = $GLOBALS['dbi']->fetchSingleRow($sql_query);
3080 return $result;
3084 * Returns the real row count for a table
3086 * @param string $db Database name
3087 * @param string $table Table name
3089 * @return number
3091 function PMA_getRealRowCountTable($db, $table)
3093 // SQL query to get row count for a table.
3094 $sql_query = 'SELECT COUNT(*) AS ' . PMA_Util::backquote('row_count')
3095 . ' FROM ' . PMA_Util::backquote($db) . '.'
3096 . PMA_Util::backquote($table);
3097 $result = $GLOBALS['dbi']->fetchSingleRow($sql_query);
3098 $row_count = $result['row_count'];
3100 return $row_count;
3104 * Returns the real row count for all tables of a DB
3106 * @param string $db Database name
3107 * @param array $tables Array containing table names.
3109 * @return array
3111 function PMA_getRealRowCountDb($db, $tables)
3113 // Array to store the results.
3114 $row_count_all = array();
3115 // Iterate over each table and fetch real row count.
3116 foreach ($tables as $key => $table) {
3117 $row_count = PMA_getRealRowCountTable($db, $table['TABLE_NAME']);
3118 array_push(
3119 $row_count_all,
3120 array('table' => $table['TABLE_NAME'], 'row_count' => $row_count)
3124 return $row_count_all;
3128 * Handles request for real row count on database level view page.
3130 * @return boolean true
3132 function PMA_handleRealRowCountRequest()
3134 $ajax_response = PMA_Response::getInstance();
3135 // If there is a request to update all table's row count.
3136 if (isset($_REQUEST['real_row_count_all'])) {
3137 $real_row_count_all = PMA_getRealRowCountDb(
3138 $GLOBALS['db'],
3139 $GLOBALS['tables']
3141 $ajax_response->addJSON(
3142 'real_row_count_all',
3143 json_encode($real_row_count_all)
3145 return true;
3147 // Get the real row count for the table.
3148 $real_row_count = PMA_getRealRowCountTable(
3149 $GLOBALS['db'],
3150 $_REQUEST['table']
3152 // Format the number.
3153 $real_row_count = PMA_Util::formatNumber($real_row_count, 0);
3154 $ajax_response->addJSON('real_row_count', $real_row_count);
3155 return true;