Refactored ConfigFile class so that it is no longer a singleton
[phpmyadmin.git] / libraries / structure.lib.php
blob876468e1c8e1455b92238f7a7af694bd0684db36
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_information_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_information_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 . '&amp;pos=0">'
56 . $truename . '</a>';
58 if (!$db_is_information_schema) {
59 $empty_table = '<a class="truncate_table_anchor ajax"';
60 $empty_table .= ' href="sql.php?' . $tbl_url_query
61 . '&amp;sql_query=';
62 $empty_table .= urlencode(
63 'TRUNCATE ' . PMA_Util::backquote($current_table['TABLE_NAME'])
65 $empty_table .= '&amp;message_to_show='
66 . urlencode(
67 sprintf(
68 __('Table %s has been emptied'),
69 htmlspecialchars($current_table['TABLE_NAME'])
72 . '">';
73 if ($may_have_rows) {
74 $empty_table .= $titles['Empty'];
75 } else {
76 $empty_table .= $titles['NoEmpty'];
78 $empty_table .= '</a>';
79 // truncating views doesn't work
80 if ($table_is_view) {
81 $empty_table = '&nbsp;';
85 $tracking_icon = '';
86 if (PMA_Tracker::isActive()) {
87 if (PMA_Tracker::isTracked($GLOBALS["db"], $truename)) {
88 $tracking_icon = '<a href="tbl_tracking.php?' . $url_query
89 . '&amp;table=' . $truename . '">'
90 . PMA_Util::getImage(
91 'eye.png', __('Tracking is active.')
93 . '</a>';
94 } elseif (PMA_Tracker::getVersion($GLOBALS["db"], $truename) > 0) {
95 $tracking_icon = '<a href="tbl_tracking.php?' . $url_query
96 . '&amp;table=' . $truename . '">'
97 . PMA_Util::getImage(
98 'eye_grey.png', __('Tracking is not active.')
100 . '</a>';
104 return array($browse_table,
105 $search_table,
106 $browse_table_label,
107 $empty_table,
108 $tracking_icon
113 * Get table drop query and drop message
115 * @param boolean $table_is_view Is table view or not
116 * @param string $current_table current table
118 * @return array ($drop_query, $drop_message)
120 function PMA_getTableDropQueryAndMessage($table_is_view, $current_table)
122 $drop_query = 'DROP '
123 . (($table_is_view || $current_table['ENGINE'] == null) ? 'VIEW' : 'TABLE')
124 . ' ' . PMA_Util::backquote(
125 $current_table['TABLE_NAME']
127 $drop_message = sprintf(
128 (($table_is_view || $current_table['ENGINE'] == null)
129 ? __('View %s has been dropped')
130 : __('Table %s has been dropped')),
131 str_replace(
132 ' ',
133 '&nbsp;',
134 htmlspecialchars($current_table['TABLE_NAME'])
137 return array($drop_query, $drop_message);
141 * Get HTML body for table summery
143 * @param integer $num_tables number of tables
144 * @param boolean $server_slave_status server slave state
145 * @param boolean $db_is_information_schema whether database is information
146 * schema or not
147 * @param integer $sum_entries sum entries
148 * @param string $db_collation collation of given db
149 * @param boolean $is_show_stats whether stats is show or not
150 * @param double $sum_size sum size
151 * @param double $overhead_size overhead size
152 * @param string $create_time_all create time
153 * @param string $update_time_all update time
154 * @param string $check_time_all check time
155 * @param integer $sum_row_count_pre sum row count pre
157 * @return string $html_output
159 function PMA_getHtmlBodyForTableSummary($num_tables, $server_slave_status,
160 $db_is_information_schema, $sum_entries, $db_collation, $is_show_stats,
161 $sum_size, $overhead_size, $create_time_all, $update_time_all,
162 $check_time_all, $sum_row_count_pre
164 if ($is_show_stats) {
165 list($sum_formatted, $unit) = PMA_Util::formatByteDown(
166 $sum_size, 3, 1
168 list($overhead_formatted, $overhead_unit)
169 = PMA_Util::formatByteDown($overhead_size, 3, 1);
172 $html_output = '<tbody id="tbl_summary_row">'
173 . '<tr><th></th>';
174 $html_output .= '<th class="tbl_num nowrap">';
175 $html_output .= sprintf(
176 _ngettext('%s table', '%s tables', $num_tables),
177 PMA_Util::formatNumber($num_tables, 0)
179 $html_output .= '</th>';
181 if ($server_slave_status) {
182 $html_output .= '<th>' . __('Replication') . '</th>' . "\n";
184 $html_output .= '<th colspan="'. ($db_is_information_schema ? 3 : 6) . '">'
185 . __('Sum')
186 . '</th>';
187 $html_output .= '<th class="value tbl_rows">'
188 . $sum_row_count_pre . PMA_Util::formatNumber($sum_entries, 0)
189 . '</th>';
191 if (!($GLOBALS['cfg']['PropertiesNumColumns'] > 1)) {
192 $default_engine = $GLOBALS['dbi']->fetchValue(
193 'SHOW VARIABLES LIKE \'storage_engine\';',
197 $html_output .= '<th class="center">' . "\n"
198 . '<dfn title="'
199 . sprintf(
200 __('%s is the default storage engine on this MySQL server.'),
201 $default_engine
203 . '">' .$default_engine . '</dfn></th>' . "\n";
204 // we got a case where $db_collation was empty
205 $html_output .= '<th>' . "\n";
207 if (! empty($db_collation)) {
208 $html_output .= '<dfn title="'
209 . PMA_getCollationDescr($db_collation)
210 . ' (' . __('Default') . ')">'
211 . $db_collation
212 . '</dfn>';
214 $html_output .= '</th>';
216 if ($is_show_stats) {
217 $html_output .= '<th class="value tbl_size">'
218 . $sum_formatted . ' ' . $unit
219 . '</th>';
220 $html_output .= '<th class="value tbl_overhead">'
221 . $overhead_formatted . ' ' . $overhead_unit
222 . '</th>';
225 if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
226 $html_output .= '<th class="value tbl_creation">' . "\n"
227 . ' '
228 . ($create_time_all
229 ? PMA_Util::localisedDate(strtotime($create_time_all))
230 : '-'
232 . '</th>';
235 if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
236 $html_output .= '<th class="value tbl_last_update">' . "\n"
237 . ' '
238 . ($update_time_all
239 ? PMA_Util::localisedDate(strtotime($update_time_all))
240 : '-'
242 . '</th>';
245 if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
246 $html_output .= '<th class="value tbl_last_check">' . "\n"
247 . ' '
248 . ($check_time_all
249 ? PMA_Util::localisedDate(strtotime($check_time_all))
250 : '-'
252 . '</th>';
254 $html_output .= '</tr>'
255 . '</tbody>';
257 return $html_output;
261 * Get HTML for "check all" check box with "with selected" dropdown
263 * @param string $pmaThemeImage pma theme image url
264 * @param string $text_dir url for text directory
265 * @param string $overhead_check overhead check
266 * @param boolean $db_is_information_schema whether database is information
267 * schema or not
268 * @param string $hidden_fields hidden fields
270 * @return string $html_output
272 function PMA_getHtmlForCheckAllTables($pmaThemeImage, $text_dir,
273 $overhead_check, $db_is_information_schema, $hidden_fields
275 $html_output = '<div class="clearfloat">';
276 $html_output .= '<img class="selectallarrow" '
277 . 'src="' .$pmaThemeImage .'arrow_'.$text_dir.'.png' . '"'
278 . 'width="38" height="22" alt="' . __('With selected:') . '" />';
280 $html_output .= '<input type="checkbox" id="tablesForm_checkall" '
281 . 'class="checkall_box" title="' . __('Check All') .'" />';
282 $html_output .= '<label for="tablesForm_checkall">' .__('Check All') . '</label>';
284 if ($overhead_check != '') {
285 $html_output .= PMA_getHtmlForCheckTablesHavingOverheadlink(
286 $overhead_check
290 $html_output .= '<select name="submit_mult" class="autosubmit" '
291 . 'style="margin: 0 3em 0 3em;">';
293 $html_output .= '<option value="' . __('With selected:')
294 . '" selected="selected">'
295 . __('With selected:') . '</option>' . "\n";
296 $html_output .= '<option value="export" >'
297 . __('Export') . '</option>' . "\n";
298 $html_output .= '<option value="print" >'
299 . __('Print view') . '</option>' . "\n";
301 if (!$db_is_information_schema
302 && !$GLOBALS['cfg']['DisableMultiTableMaintenance']
304 $html_output .= '<option value="empty_tbl" >'
305 . __('Empty') . '</option>' . "\n";
306 $html_output .= '<option value="drop_tbl" >'
307 . __('Drop') . '</option>' . "\n";
308 $html_output .= '<option value="check_tbl" >'
309 . __('Check table') . '</option>' . "\n";
310 if (!PMA_DRIZZLE) {
311 $html_output .= '<option value="optimize_tbl" >'
312 . __('Optimize table') . '</option>' . "\n";
313 $html_output .= '<option value="repair_tbl" >'
314 . __('Repair table') . '</option>' . "\n";
316 $html_output .= '<option value="analyze_tbl" >'
317 . __('Analyze table') . '</option>' . "\n";
318 $html_output .= '<option value="add_prefix_tbl" >'
319 . __('Add prefix to table') . '</option>' . "\n";
320 $html_output .= '<option value="replace_prefix_tbl" >'
321 . __('Replace table prefix') . '</option>' . "\n";
322 $html_output .= '<option value="copy_tbl_change_prefix" >'
323 . __('Copy table with prefix') . '</option>' . "\n";
325 $html_output .= '</select>'
326 . implode("\n", $hidden_fields) . "\n";
327 $html_output .= '</div>';
329 return $html_output;
333 * Get HTML code for "Check tables having overhead" link
335 * @param string $overhead_check overhead check
337 * @return string $html_output
339 function PMA_getHtmlForCheckTablesHavingOverheadlink($overhead_check)
341 return ' / '
342 . '<a href="#" onclick="unMarkAllRows(\'tablesForm\');'
343 . $overhead_check . 'return false;">'
344 . __('Check tables having overhead')
345 . '</a>';
350 * Get HTML links for "Print view" options
352 * @param string $url_query url query
354 * @return string $html_output
356 function PMA_getHtmlForTablePrintViewLink($url_query)
358 return '<p>'
359 . '<a href="db_printview.php?' . $url_query . '" target="print_view">'
360 . PMA_Util::getIcon(
361 'b_print.png',
362 __('Print view'),
363 true
364 ) . '</a>';
368 * Get HTML links "Data Dictionary" options
370 * @param string $url_query url query
372 * @return string $html_output
374 function PMA_getHtmlForDataDictionaryLink($url_query)
376 return '<a href="db_datadict.php?' . $url_query . '" target="print_view">'
377 . PMA_Util::getIcon(
378 'b_tblanalyse.png',
379 __('Data Dictionary'),
380 true
381 ) . '</a>'
382 . '</p>';
386 * Get Time for Create time, update time and check time
388 * @param array $current_table current table
389 * @param string $time_label Create_time, Update_time, Check_time
390 * @param integer $time_all time
392 * @return array ($time, $time_all)
394 function PMA_getTimeForCreateUpdateCheck($current_table, $time_label, $time_all)
396 $showtable = PMA_Table::sGetStatusInfo(
397 $GLOBALS['db'],
398 $current_table['TABLE_NAME'],
399 null,
400 true
402 $time = isset($showtable[$time_label])
403 ? $showtable[$time_label]
404 : false;
406 // show oldest creation date in summary row
407 if ($time && (!$time_all || $time < $time_all)) {
408 $time_all = $time;
410 return array($time, $time_all);
414 * Get HTML for each table row of the database structure table,
415 * And this function returns $odd_row param also
417 * @param integer $curr current entry
418 * @param boolean $odd_row whether row is odd or not
419 * @param boolean $table_is_view whether table is view or not
420 * @param array $current_table current table
421 * @param string $browse_table_label browse table label action link
422 * @param string $tracking_icon tracking icon
423 * @param boolean $server_slave_status server slave state
424 * @param string $browse_table browse table action link
425 * @param string $tbl_url_query table url query
426 * @param string $search_table search table action link
427 * @param boolean $db_is_information_schema whether db is information schema or not
428 * @param array $titles titles array
429 * @param string $empty_table empty table action link
430 * @param string $drop_query table dropt query
431 * @param string $drop_message table drop message
432 * @param string $collation collation
433 * @param string $formatted_size formatted size
434 * @param string $unit unit
435 * @param string $overhead overhead
436 * @param string $create_time create time
437 * @param string $update_time last update time
438 * @param string $check_time last check time
439 * @param boolean $is_show_stats whether stats is show or not
440 * @param boolean $ignored ignored
441 * @param boolean $do do
442 * @param intger $colspan_for_structure colspan for structure
444 * @return array $html_output, $odd_row
446 function PMA_getHtmlForStructureTableRow(
447 $curr, $odd_row, $table_is_view, $current_table,
448 $browse_table_label, $tracking_icon,$server_slave_status,
449 $browse_table, $tbl_url_query, $search_table,
450 $db_is_information_schema,$titles, $empty_table, $drop_query, $drop_message,
451 $collation, $formatted_size, $unit, $overhead, $create_time, $update_time,
452 $check_time,$is_show_stats, $ignored, $do, $colspan_for_structure
454 $html_output = '<tr class="' . ($odd_row ? 'odd' : 'even');
455 $odd_row = ! $odd_row;
456 $html_output .= ($table_is_view ? ' is_view' : '')
457 .'" id="row_tbl_' . $curr . '">';
459 $html_output .= '<td class="center">'
460 . '<input type="checkbox" name="selected_tbl[]" class="checkall" '
461 . 'value="' . htmlspecialchars($current_table['TABLE_NAME']) . '" '
462 . 'id="checkbox_tbl_' . $curr .'" /></td>';
464 $html_output .= '<th>'
465 . $browse_table_label
466 . (! empty($tracking_icon) ? $tracking_icon : '')
467 . '</th>';
469 if ($server_slave_status) {
470 $html_output .= '<td class="center">'
471 . ($ignored
472 ? PMA_Util::getImage('s_cancel.png', 'NOT REPLICATED')
473 : '')
474 . ($do
475 ? PMA_Util::getImage('s_success.png', 'REPLICATED')
476 : '')
477 . '</td>';
480 $html_output .= '<td class="center">' . $browse_table . '</td>';
481 $html_output .= '<td class="center">'
482 . '<a href="tbl_structure.php?' . $tbl_url_query . '">'
483 . $titles['Structure'] . '</a></td>';
484 $html_output .= '<td class="center">' . $search_table . '</td>';
486 if (! $db_is_information_schema) {
487 $html_output .= PMA_getHtmlForInsertEmptyDropActionLinks(
488 $tbl_url_query, $table_is_view,
489 $titles, $empty_table, $current_table, $drop_query, $drop_message
491 } // end if (! $db_is_information_schema)
493 // there is a null value in the ENGINE
494 // - when the table needs to be repaired, or
495 // - when it's a view
496 // so ensure that we'll display "in use" below for a table
497 // that needs to be repaired
498 if (isset($current_table['TABLE_ROWS'])
499 && ($current_table['ENGINE'] != null
500 || $table_is_view)
502 $html_output .= PMA_getHtmlForNotNullEngineViewTable(
503 $table_is_view, $current_table, $collation, $is_show_stats,
504 $tbl_url_query, $formatted_size, $unit, $overhead, $create_time,
505 $update_time, $check_time
507 } elseif ($table_is_view) {
508 $html_output .= PMA_getHtmlForViewTable($is_show_stats);
509 } else {
510 $html_output .= PMA_getHtmlForRepairtable(
511 $colspan_for_structure,
512 $db_is_information_schema
514 } // end if (isset($current_table['TABLE_ROWS'])) else
515 $html_output .= '</tr>';
517 return array($html_output, $odd_row);
521 * Get HTML for Insert/Empty/Drop action links
523 * @param string $tbl_url_query table url query
524 * @param boolean $table_is_view whether table is view or not
525 * @param array $titles titles array
526 * @param string $empty_table HTML link for empty table
527 * @param array $current_table current table
528 * @param string $drop_query query for drop table
529 * @param string $drop_message table drop message
531 * @return string $html_output
533 function PMA_getHtmlForInsertEmptyDropActionLinks($tbl_url_query, $table_is_view,
534 $titles, $empty_table, $current_table, $drop_query, $drop_message
536 $html_output = '<td class="insert_table center">'
537 . '<a href="tbl_change.php?' . $tbl_url_query . '">'
538 . $titles['Insert']
539 . '</a></td>';
540 $html_output .= '<td class="center">' . $empty_table . '</td>';
541 $html_output .= '<td class="center">';
542 $html_output .= '<a ';
543 $html_output .= 'class="ajax drop_table_anchor';
544 if ($table_is_view || $current_table['ENGINE'] == null) {
545 // this class is used in db_structure.js to display the
546 // correct confirmation message
547 $html_output .= ' view';
549 $html_output .= '"';
550 $html_output .= 'href="sql.php?' . $tbl_url_query
551 . '&amp;reload=1&amp;purge=1&amp;sql_query='
552 . urlencode($drop_query) . '&amp;message_to_show='
553 . urlencode($drop_message) . '" >'
554 . $titles['Drop'] . '</a></td>';
556 return $html_output;
560 * Get HTML for show stats
562 * @param string $tbl_url_query tabel url query
563 * @param string $formatted_size formatted size
564 * @param string $unit unit
565 * @param string $overhead overhead
567 * @return string $html_output
569 function PMA_getHtmlForShowStats($tbl_url_query, $formatted_size,
570 $unit, $overhead
572 $html_output = '<td class="value tbl_size"><a'
573 . 'href="tbl_structure.php?' . $tbl_url_query . '#showusage" >'
574 . '<span>' . $formatted_size . '</span> '
575 . '<span class="unit">' . $unit . '</span>'
576 . '</a></td>';
577 $html_output .= '<td class="value tbl_overhead">' . $overhead . '</td>';
579 return $html_output;
583 * Get HTML to show database structure creation, last update and last checkx time
585 * @param string $create_time create time
586 * @param string $update_time last update time
587 * @param string $check_time last check time
589 * @return string $html_output
591 function PMA_getHtmlForStructureTimes($create_time, $update_time, $check_time)
593 $html_output = '';
594 if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
595 $html_output .= '<td class="value tbl_creation">'
596 . ($create_time
597 ? PMA_Util::localisedDate(strtotime($create_time))
598 : '-' )
599 . '</td>';
600 } // end if
601 if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
602 $html_output .= '<td class="value tbl_last_update">'
603 . ($update_time
604 ? PMA_Util::localisedDate(strtotime($update_time))
605 : '-' )
606 . '</td>';
607 } // end if
608 if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
609 $html_output .= '<td class="value tbl_last_check">'
610 . ($check_time
611 ? PMA_Util::localisedDate(strtotime($check_time))
612 : '-' )
613 . '</td>';
615 return $html_output;
619 * Get HTML for ENGINE value not null or view tables that are not empty tables
621 * @param boolean $table_is_view whether table is view
622 * @param array $current_table current table
623 * @param string $collation collation
624 * @param boolean $is_show_stats whether atats show or not
625 * @param string $tbl_url_query table url query
626 * @param string $formatted_size formatted size
627 * @param string $unit unit
628 * @param string $overhead overhead
629 * @param string $create_time create time
630 * @param string $update_time update time
631 * @param string $check_time check time
633 * @return string $html_output
635 function PMA_getHtmlForNotNullEngineViewTable($table_is_view, $current_table,
636 $collation, $is_show_stats, $tbl_url_query, $formatted_size, $unit,
637 $overhead, $create_time, $update_time, $check_time
639 $html_output = '';
640 $row_count_pre = '';
641 $show_superscript = '';
642 if ($table_is_view) {
643 // Drizzle views use FunctionEngine, and the only place where they are
644 // available are I_S and D_D schemas, where we do exact counting
645 if ($current_table['TABLE_ROWS'] >= $GLOBALS['cfg']['MaxExactCountViews']
646 && $current_table['ENGINE'] != 'FunctionEngine'
648 $row_count_pre = '~';
649 $sum_row_count_pre = '~';
650 $show_superscript = PMA_Util::showHint(
651 PMA_sanitize(
652 sprintf(
653 __('This view has at least this number of rows. Please refer to %sdocumentation%s.'),
654 '[doc@cfg_MaxExactCountViews]',
655 '[/doc]'
660 } elseif ($current_table['ENGINE'] == 'InnoDB'
661 && (! $current_table['COUNTED'])
663 // InnoDB table: we did not get an accurate row count
664 $row_count_pre = '~';
665 $sum_row_count_pre = '~';
666 $show_superscript = '';
669 $html_output .= '<td class="value tbl_rows">'
670 . $row_count_pre . PMA_Util::formatNumber(
671 $current_table['TABLE_ROWS'], 0
673 . $show_superscript . '</td>';
675 if (!($GLOBALS['cfg']['PropertiesNumColumns'] > 1)) {
676 $html_output .= '<td class="nowrap">'
677 . ($table_is_view ? __('View') : $current_table['ENGINE'])
678 . '</td>';
679 if (strlen($collation)) {
680 $html_output .= '<td class="nowrap">' . $collation . '</td>';
684 if ($is_show_stats) {
685 $html_output .= PMA_getHtmlForShowStats(
686 $tbl_url_query, $formatted_size, $unit, $overhead
690 $html_output .= PMA_getHtmlForStructureTimes(
691 $create_time, $update_time, $check_time
694 return $html_output;
698 * Get HTML snippet view table
700 * @param type $is_show_stats whether stats show or not
702 * @return string $html_output
704 function PMA_getHtmlForViewTable($is_show_stats)
706 $html_output = '<td class="value">-</td>'
707 . '<td>' . __('View') . '</td>'
708 . '<td>---</td>';
709 if ($is_show_stats) {
710 $html_output .= '<td class="value">-</td>'
711 . '<td class="value">-</td>';
713 return $html_output;
717 * display "in use" below for a table that needs to be repaired
719 * @param integer $colspan_for_structure colspan for structure
720 * @param boolean $db_is_information_schema whether db is information schema or not
722 * @return string HTML snippet
724 function PMA_getHtmlForRepairtable(
725 $colspan_for_structure,
726 $db_is_information_schema
728 return '<td colspan="'
729 . ($colspan_for_structure - ($db_is_information_schema ? 5 : 8)) . '"'
730 . 'class="center">'
731 . __('in use')
732 . '</td>';
736 * display table header (<table><thead>...</thead><tbody>)
738 * @param boolean $db_is_information_schema whether db is information schema or not
739 * @param boolean $replication whether to sho replication status
741 * @return html data
743 function PMA_tableHeader($db_is_information_schema = false, $replication = false)
745 $cnt = 0; // Let's count the columns...
747 if ($db_is_information_schema) {
748 $action_colspan = 3;
749 } else {
750 $action_colspan = 6;
753 $html_output = '<table class="data">' . "\n"
754 .'<thead>' . "\n"
755 .'<tr><th></th>' . "\n"
756 .'<th>'
757 . PMA_sortableTableHeader(__('Table'), 'table')
758 . '</th>' . "\n";
759 if ($replication) {
760 $html_output .= '<th>' . "\n"
761 .' ' . __('Replication') . "\n"
762 .'</th>';
764 $html_output .= '<th colspan="' . $action_colspan . '">' . "\n"
765 .' ' . __('Action') . "\n"
766 .'</th>'
767 // larger values are more interesting so default sort order is DESC
768 .'<th>' . PMA_sortableTableHeader(__('Rows'), 'records', 'DESC')
769 . PMA_Util::showHint(
770 PMA_sanitize(
771 __('May be approximate. See [doc@faq3-11]FAQ 3.11[/doc]')
773 ) . "\n"
774 .'</th>' . "\n";
775 if (!($GLOBALS['cfg']['PropertiesNumColumns'] > 1)) {
776 $html_output .= '<th>' . PMA_sortableTableHeader(__('Type'), 'type')
777 . '</th>' . "\n";
778 $cnt++;
779 $html_output .= '<th>'
780 . PMA_sortableTableHeader(__('Collation'), 'collation')
781 . '</th>' . "\n";
782 $cnt++;
784 if ($GLOBALS['is_show_stats']) {
785 // larger values are more interesting so default sort order is DESC
786 $html_output .= '<th>'
787 . PMA_sortableTableHeader(__('Size'), 'size', 'DESC')
788 . '</th>' . "\n"
789 // larger values are more interesting so default sort order is DESC
790 . '<th>'
791 . PMA_sortableTableHeader(__('Overhead'), 'overhead', 'DESC')
792 . '</th>' . "\n";
793 $cnt += 2;
795 if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
796 // larger values are more interesting so default sort order is DESC
797 $html_output .= '<th>'
798 . PMA_sortableTableHeader(__('Creation'), 'creation', 'DESC')
799 . '</th>' . "\n";
800 $cnt += 2;
802 if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
803 // larger values are more interesting so default sort order is DESC
804 $html_output .= '<th>'
805 . PMA_sortableTableHeader(__('Last update'), 'last_update', 'DESC')
806 . '</th>' . "\n";
807 $cnt += 2;
809 if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
810 // larger values are more interesting so default sort order is DESC
811 $html_output .= '<th>'
812 . PMA_sortableTableHeader(__('Last check'), 'last_check', 'DESC')
813 . '</th>' . "\n";
814 $cnt += 2;
816 $html_output .= '</tr>' . "\n";
817 $html_output .= '</thead>' . "\n";
818 $html_output .= '<tbody>' . "\n";
819 $GLOBALS['colspan_for_structure'] = $cnt + $action_colspan + 3;
821 return $html_output;
825 * Creates a clickable column header for table information
827 * @param string $title title to use for the link
828 * @param string $sort corresponds to sortable data name mapped in
829 * libraries/db_info.inc.php
830 * @param string $initial_sort_order initial sort order
832 * @return string link to be displayed in the table header
834 function PMA_sortableTableHeader($title, $sort, $initial_sort_order = 'ASC')
836 // Set some defaults
837 $requested_sort = 'table';
838 $requested_sort_order = $future_sort_order = $initial_sort_order;
840 // If the user requested a sort
841 if (isset($_REQUEST['sort'])) {
842 $requested_sort = $_REQUEST['sort'];
844 if (isset($_REQUEST['sort_order'])) {
845 $requested_sort_order = $_REQUEST['sort_order'];
849 $order_img = '';
850 $order_link_params = array();
851 $order_link_params['title'] = __('Sort');
853 // If this column was requested to be sorted.
854 if ($requested_sort == $sort) {
855 if ($requested_sort_order == 'ASC') {
856 $future_sort_order = 'DESC';
857 // current sort order is ASC
858 $order_img = ' ' . PMA_Util::getImage(
859 's_asc.png',
860 __('Ascending'),
861 array('class' => 'sort_arrow', 'title' => '')
863 $order_img .= ' ' . PMA_Util::getImage(
864 's_desc.png',
865 __('Descending'),
866 array('class' => 'sort_arrow hide', 'title' => '')
868 // but on mouse over, show the reverse order (DESC)
869 $order_link_params['onmouseover'] = "$('.sort_arrow').toggle();";
870 // on mouse out, show current sort order (ASC)
871 $order_link_params['onmouseout'] = "$('.sort_arrow').toggle();";
872 } else {
873 $future_sort_order = 'ASC';
874 // current sort order is DESC
875 $order_img = ' ' . PMA_Util::getImage(
876 's_asc.png',
877 __('Ascending'),
878 array('class' => 'sort_arrow hide', 'title' => '')
880 $order_img .= ' ' . PMA_Util::getImage(
881 's_desc.png',
882 __('Descending'),
883 array('class' => 'sort_arrow', 'title' => '')
885 // but on mouse over, show the reverse order (ASC)
886 $order_link_params['onmouseover'] = "$('.sort_arrow').toggle();";
887 // on mouse out, show current sort order (DESC)
888 $order_link_params['onmouseout'] = "$('.sort_arrow').toggle();";
892 $_url_params = array(
893 'db' => $_REQUEST['db'],
896 $url = 'db_structure.php'.PMA_URL_getCommon($_url_params);
897 // We set the position back to 0 every time they sort.
898 $url .= "&amp;pos=0&amp;sort=$sort&amp;sort_order=$future_sort_order";
900 return PMA_Util::linkOrButton(
901 $url, $title . $order_img, $order_link_params
906 * Get the alias ant truname
908 * @param string $tooltip_aliasname tooltip alias name
909 * @param array $current_table current table
910 * @param string $tooltip_truename tooltip true name
912 * @return array ($alias, $truename)
914 function PMA_getAliasAndTrueName($tooltip_aliasname, $current_table,
915 $tooltip_truename
917 $alias = (! empty($tooltip_aliasname)
918 && isset($tooltip_aliasname[$current_table['TABLE_NAME']])
920 ? str_replace(
921 ' ', '&nbsp;',
922 htmlspecialchars($tooltip_truename[$current_table['TABLE_NAME']])
924 : str_replace(
925 ' ', '&nbsp;',
926 htmlspecialchars($current_table['TABLE_NAME'])
928 $truename = (! empty($tooltip_truename)
929 && isset($tooltip_truename[$current_table['TABLE_NAME']])
931 ? str_replace(
932 ' ', '&nbsp;',
933 htmlspecialchars($tooltip_truename[$current_table['TABLE_NAME']])
935 : str_replace(
936 ' ', '&nbsp;',
937 htmlspecialchars($current_table['TABLE_NAME'])
940 return array($alias, $truename);
944 * Get the server slave state
946 * @param boolean $server_slave_status server slave state
947 * @param string $truename true name
949 * @return array ($do, $ignored)
951 function PMA_getServerSlaveStatus($server_slave_status, $truename)
953 $ignored = false;
954 $do = false;
955 include_once 'libraries/replication.inc.php';
956 if ($server_slave_status) {
957 if ((strlen(array_search($truename, $server_slave_Do_Table)) > 0)
958 || (strlen(array_search($GLOBALS['db'], $server_slave_Do_DB)) > 0)
959 || (count($server_slave_Do_DB) == 1 && count($server_slave_Ignore_DB) == 1)
961 $do = true;
963 foreach ($server_slave_Wild_Do_Table as $db_table) {
964 $table_part = PMA_extractDbOrTable($db_table, 'table');
965 if (($GLOBALS['db'] == PMA_extractDbOrTable($db_table, 'db'))
966 && (preg_match("@^" . substr($table_part, 0, strlen($table_part) - 1) . "@", $truename))
968 $do = true;
972 if ((strlen(array_search($truename, $server_slave_Ignore_Table)) > 0)
973 || (strlen(array_search($GLOBALS['db'], $server_slave_Ignore_DB)) > 0)
975 $ignored = true;
977 foreach ($server_slave_Wild_Ignore_Table as $db_table) {
978 $table_part = PMA_extractDbOrTable($db_table, 'table');
979 if (($db == PMA_extractDbOrTable($db_table))
980 && (preg_match("@^" . substr($table_part, 0, strlen($table_part) - 1) . "@", $truename))
982 $ignored = true;
986 return array($do, $ignored);
990 * Get the value set for ENGINE table,
991 * $current_table, $formatted_size, $unit, $formatted_overhead,
992 * $overhead_unit, $overhead_size, $table_is_view
994 * @param array $current_table current table
995 * @param boolean $db_is_information_schema whether db is information schema or not
996 * @param boolean $is_show_stats whether stats show or not
997 * @param boolean $table_is_view whether table is view or not
998 * @param double $sum_size totle table size
999 * @param double $overhead_size overhead size
1001 * @return array
1003 function PMA_getStuffForEngineTypeTable($current_table, $db_is_information_schema,
1004 $is_show_stats, $table_is_view, $sum_size, $overhead_size
1006 $formatted_size = '-';
1007 $unit = '';
1008 $formatted_overhead = '';
1009 $overhead_unit = '';
1011 switch ( $current_table['ENGINE']) {
1012 // MyISAM, ISAM or Heap table: Row count, data size and index size
1013 // are accurate; data size is accurate for ARCHIVE
1014 case 'MyISAM' :
1015 case 'ISAM' :
1016 case 'HEAP' :
1017 case 'MEMORY' :
1018 case 'ARCHIVE' :
1019 case 'Aria' :
1020 case 'Maria' :
1021 list($current_table, $formatted_size, $unit, $formatted_overhead,
1022 $overhead_unit, $overhead_size, $sum_size) = PMA_getValuesForAriaTable(
1023 $db_is_information_schema, $current_table, $is_show_stats,
1024 $sum_size, $overhead_size, $formatted_size, $unit,
1025 $formatted_overhead, $overhead_unit
1027 break;
1028 case 'InnoDB' :
1029 case 'PBMS' :
1030 // InnoDB table: Row count is not accurate but data and index sizes are.
1031 // PBMS table in Drizzle: TABLE_ROWS is taken from table cache,
1032 // so it may be unavailable
1033 list($current_table, $formatted_size, $unit, $sum_size)
1034 = PMA_getValuesForInnodbTable($current_table, $is_show_stats, $sum_size);
1035 //$display_rows = ' - ';
1036 break;
1037 // Mysql 5.0.x (and lower) uses MRG_MyISAM
1038 // and MySQL 5.1.x (and higher) uses MRG_MYISAM
1039 // Both are aliases for MERGE
1040 case 'MRG_MyISAM' :
1041 case 'MRG_MYISAM' :
1042 case 'MERGE' :
1043 case 'BerkeleyDB' :
1044 // Merge or BerkleyDB table: Only row count is accurate.
1045 if ($is_show_stats) {
1046 $formatted_size = ' - ';
1047 $unit = '';
1049 break;
1050 // for a view, the ENGINE is sometimes reported as null,
1051 // or on some servers it's reported as "SYSTEM VIEW"
1052 case null :
1053 case 'SYSTEM VIEW' :
1054 case 'FunctionEngine' :
1055 // if table is broken, Engine is reported as null, so one more test
1056 if ($current_table['TABLE_TYPE'] == 'VIEW') {
1057 // countRecords() takes care of $cfg['MaxExactCountViews']
1058 $current_table['TABLE_ROWS'] = PMA_Table::countRecords(
1059 $GLOBALS['db'], $current_table['TABLE_NAME'],
1060 true, true
1062 $table_is_view = true;
1064 break;
1065 default :
1066 // Unknown table type.
1067 if ($is_show_stats) {
1068 $formatted_size = __('unknown');
1069 $unit = '';
1071 } // end switch
1073 return array($current_table, $formatted_size, $unit, $formatted_overhead,
1074 $overhead_unit, $overhead_size, $table_is_view, $sum_size
1079 * Get values for ARIA/MARIA tables
1080 * $current_table, $formatted_size, $unit, $formatted_overhead,
1081 * $overhead_unit, $overhead_size
1083 * @param boolean $db_is_information_schema whether db is information schema or not
1084 * @param array $current_table current table
1085 * @param boolean $is_show_stats whether stats show or not
1086 * @param double $sum_size sum size
1087 * @param double $overhead_size overhead size
1089 * @return array
1091 function PMA_getValuesForAriaTable($db_is_information_schema, $current_table,
1092 $is_show_stats, $sum_size, $overhead_size, $formatted_size, $unit,
1093 $formatted_overhead, $overhead_unit
1095 if ($db_is_information_schema) {
1096 $current_table['Rows'] = PMA_Table::countRecords(
1097 $GLOBALS['db'], $current_table['Name']
1101 if ($is_show_stats) {
1102 $tblsize = doubleval($current_table['Data_length'])
1103 + doubleval($current_table['Index_length']);
1104 $sum_size += $tblsize;
1105 list($formatted_size, $unit) = PMA_Util::formatByteDown(
1106 $tblsize, 3, ($tblsize > 0) ? 1 : 0
1108 if (isset($current_table['Data_free']) && $current_table['Data_free'] > 0) {
1109 list($formatted_overhead, $overhead_unit)
1110 = PMA_Util::formatByteDown(
1111 $current_table['Data_free'], 3,
1112 (($current_table['Data_free'] > 0) ? 1 : 0)
1114 $overhead_size += $current_table['Data_free'];
1117 return array($current_table, $formatted_size, $unit, $formatted_overhead,
1118 $overhead_unit, $overhead_size, $sum_size
1123 * Get values for InnoDB table
1124 * $current_table, $formatted_size, $unit, $sum_size
1126 * @param array $current_table current table
1127 * @param boolean $is_show_stats whether stats show or not
1128 * @param double $sum_size sum size
1130 * @return array
1132 function PMA_getValuesForInnodbTable($current_table, $is_show_stats, $sum_size)
1134 $formatted_size = $unit = '';
1136 if (($current_table['ENGINE'] == 'InnoDB'
1137 && $current_table['TABLE_ROWS'] < $GLOBALS['cfg']['MaxExactCount'])
1138 || !isset($current_table['TABLE_ROWS'])
1140 $current_table['COUNTED'] = true;
1141 $current_table['TABLE_ROWS'] = PMA_Table::countRecords(
1142 $GLOBALS['db'], $current_table['TABLE_NAME'],
1143 true, false
1145 } else {
1146 $current_table['COUNTED'] = false;
1149 // Drizzle doesn't provide data and index length, check for null
1150 if ($is_show_stats && $current_table['Data_length'] !== null) {
1151 $tblsize = $current_table['Data_length'] + $current_table['Index_length'];
1152 $sum_size += $tblsize;
1153 list($formatted_size, $unit) = PMA_Util::formatByteDown(
1154 $tblsize, 3, (($tblsize > 0) ? 1 : 0)
1158 return array($current_table, $formatted_size, $unit, $sum_size);
1162 * table structure
1166 * Get the HTML snippet for structure table table header
1168 * @param type $db_is_information_schema whether db is information schema or not
1169 * @param type $tbl_is_view whether table is view or nt
1171 * @return string $html_output
1173 function PMA_getHtmlForTableStructureHeader(
1174 $db_is_information_schema,
1175 $tbl_is_view
1177 $html_output = '<thead>';
1178 $html_output .= '<tr>';
1179 $html_output .= '<th></th>'
1180 . '<th>#</th>'
1181 . '<th>' . __('Name') . '</th>'
1182 . '<th>' . __('Type'). '</th>'
1183 . '<th>' . __('Collation') . '</th>'
1184 . '<th>' . __('Attributes') . '</th>'
1185 . '<th>' . __('Null') . '</th>'
1186 . '<th>' . __('Default') . '</th>'
1187 . '<th>' . __('Extra') . '</th>';
1189 if ($db_is_information_schema || $tbl_is_view) {
1190 $html_output .= '<th>' . __('View') . '</th>';
1191 } else { /* see tbl_structure.js, function moreOptsMenuResize() */
1192 $colspan = 9;
1193 if (PMA_DRIZZLE) {
1194 $colspan -= 2;
1196 if (PMA_Util::showIcons('ActionLinksMode')) {
1197 $colspan--;
1199 $html_output .= '<th colspan="' . $colspan . '" '
1200 . 'class="action">' . __('Action') . '</th>';
1202 $html_output .= '</tr>'
1203 . '</thead>';
1205 return $html_output;
1209 * Get HTML for structure table's rows and return $odd_row parameter also
1210 * For "Action" Column, this function contains only HTML code for "Change"
1211 * and "Drop"
1213 * @param array $row current row
1214 * @param string $rownum row number
1215 * @param string $displayed_field_name displayed field name
1216 * @param string $type_nowrap type nowrap
1217 * @param array $extracted_columnspec associative array containing type,
1218 * spec_in_brackets and possibly
1219 * enum_set_values (another array)
1220 * @param string $type_mime mime type
1221 * @param string $field_charset field charset
1222 * @param string $attribute attribute (BINARY, UNSIGNED,
1223 * UNSIGNED ZEROFILL,
1224 * on update CURRENT_TIMESTAMP)
1225 * @param boolean $tbl_is_view whether tables is view or not
1226 * @param boolean $db_is_information_schema whether db is information schema or not
1227 * @param string $url_query url query
1228 * @param string $field_encoded field encoded
1229 * @param array $titles tittles array
1230 * @param string $table table
1232 * @return array ($html_output, $odd_row)
1234 function PMA_getHtmlTableStructureRow($row, $rownum,
1235 $displayed_field_name, $type_nowrap, $extracted_columnspec, $type_mime,
1236 $field_charset, $attribute, $tbl_is_view, $db_is_information_schema,
1237 $url_query, $field_encoded, $titles, $table
1239 $html_output = '<td class="center">'
1240 . '<input type="checkbox" class="checkall" name="selected_fld[]" '
1241 . 'value="' . htmlspecialchars($row['Field']) . '" '
1242 . 'id="checkbox_row_' . $rownum . '"/>'
1243 . '</td>';
1245 $html_output .= '<td class="right">'
1246 . $rownum
1247 . '</td>';
1249 $html_output .= '<th class="nowrap">'
1250 . '<label for="checkbox_row_' . $rownum . '">'
1251 . $displayed_field_name . '</label>'
1252 . '</th>';
1254 $html_output .= '<td' . $type_nowrap . '>'
1255 .'<bdo dir="ltr" lang="en">'
1256 . $extracted_columnspec['displayed_type'] . $type_mime
1257 . '</bdo></td>';
1259 $html_output .= '<td>' .
1260 (empty($field_charset)
1261 ? ''
1262 : '<dfn title="' . PMA_getCollationDescr($field_charset) . '">'
1263 . $field_charset . '</dfn>'
1265 . '</td>';
1267 $html_output .= '<td class="column_attribute nowrap">'
1268 . $attribute . '</td>';
1269 $html_output .= '<td>'
1270 . (($row['Null'] == 'YES') ? __('Yes') : __('No')) . ' </td>';
1272 $html_output .= '<td class="nowrap">';
1273 if (isset($row['Default'])) {
1274 if ($extracted_columnspec['type'] == 'bit') {
1275 // here, $row['Default'] contains something like b'010'
1276 $html_output .= PMA_Util::convertBitDefaultValue($row['Default']);
1277 } else {
1278 $html_output .= $row['Default'];
1280 } else {
1281 $html_output .= '<i>' . _pgettext('None for default', 'None') . '</i>';
1283 $html_output .= '</td>';
1285 $html_output .= '<td class="nowrap">' . strtoupper($row['Extra']) . '</td>';
1287 $html_output .= PMA_getHtmlForDropColumn(
1288 $tbl_is_view, $db_is_information_schema,
1289 $url_query, $field_encoded,
1290 $titles, $table, $row
1293 return $html_output;
1297 * Get HTML code for "Drop" Action link
1299 * @param boolean $tbl_is_view whether tables is view or not
1300 * @param boolean $db_is_information_schema whether db is information schema or not
1301 * @param string $url_query url query
1302 * @param string $field_encoded field encoded
1303 * @param array $titles tittles array
1304 * @param string $table table
1305 * @param array $row current row
1307 * @return string $html_output
1309 function PMA_getHtmlForDropColumn($tbl_is_view, $db_is_information_schema,
1310 $url_query, $field_encoded, $titles, $table, $row
1312 $html_output = '';
1314 if (! $tbl_is_view && ! $db_is_information_schema) {
1315 $html_output .= '<td class="edit center">'
1316 . '<a class="change_column_anchor ajax"'
1317 . ' href="tbl_structure.php?'
1318 . $url_query . '&amp;field=' . $field_encoded
1319 . '&amp;change_column=1">'
1320 . $titles['Change'] . '</a>' . '</td>';
1321 $html_output .= '<td class="drop center">'
1322 . '<a class="drop_column_anchor ajax"'
1323 . ' href="sql.php?' . $url_query . '&amp;sql_query='
1324 . urlencode(
1325 'ALTER TABLE ' . PMA_Util::backquote($table)
1326 . ' DROP ' . PMA_Util::backquote($row['Field']) . ';'
1328 . '&amp;dropped_column=' . urlencode($row['Field'])
1329 . '&amp;message_to_show=' . urlencode(
1330 sprintf(
1331 __('Column %s has been dropped'),
1332 htmlspecialchars($row['Field'])
1334 ) . '" >'
1335 . $titles['Drop'] . '</a>'
1336 . '</td>';
1339 return $html_output;
1343 * Get HTML for "check all" check box with "with selected" actions in table
1344 * structure
1346 * @param string $pmaThemeImage pma theme image url
1347 * @param string $text_dir test directory
1348 * @param boolean $tbl_is_view whether table is view or not
1349 * @param boolean $db_is_information_schema whether db is information schema or not
1350 * @param string $tbl_storage_engine table storage engine
1352 * @return string $html_output
1354 function PMA_getHtmlForCheckAllTableColumn($pmaThemeImage, $text_dir,
1355 $tbl_is_view, $db_is_information_schema, $tbl_storage_engine
1357 $html_output = '<img class="selectallarrow" '
1358 . 'src="' . $pmaThemeImage . 'arrow_' . $text_dir . '.png' . '"'
1359 . 'width="38" height="22" alt="' . __('With selected:') . '" />';
1361 $html_output .= '<input type="checkbox" id="fieldsForm_checkall" '
1362 . 'class="checkall_box" title="' . __('Check All') . '" />'
1363 . '<label for="fieldsForm_checkall">' . __('Check All') . '</label>';
1365 $html_output .= '<i style="margin-left: 2em">'
1366 . __('With selected:') . '</i>';
1368 $html_output .= PMA_Util::getButtonOrImage(
1369 'submit_mult', 'mult_submit', 'submit_mult_browse',
1370 __('Browse'), 'b_browse.png', 'browse'
1373 if (! $tbl_is_view && ! $db_is_information_schema) {
1374 $html_output .= PMA_Util::getButtonOrImage(
1375 'submit_mult', 'mult_submit change_columns_anchor ajax',
1376 'submit_mult_change', __('Change'), 'b_edit.png', 'change'
1378 $html_output .= PMA_Util::getButtonOrImage(
1379 'submit_mult', 'mult_submit', 'submit_mult_drop',
1380 __('Drop'), 'b_drop.png', 'drop'
1382 if ('ARCHIVE' != $tbl_storage_engine) {
1383 $html_output .= PMA_Util::getButtonOrImage(
1384 'submit_mult', 'mult_submit', 'submit_mult_primary',
1385 __('Primary'), 'b_primary.png', 'primary'
1387 $html_output .= PMA_Util::getButtonOrImage(
1388 'submit_mult', 'mult_submit', 'submit_mult_unique',
1389 __('Unique'), 'b_unique.png', 'unique'
1391 $html_output .= PMA_Util::getButtonOrImage(
1392 'submit_mult', 'mult_submit', 'submit_mult_index',
1393 __('Index'), 'b_index.png', 'index'
1397 if (! empty($tbl_storage_engine) && $tbl_storage_engine == 'MYISAM') {
1398 $html_output .= PMA_Util::getButtonOrImage(
1399 'submit_mult', 'mult_submit', 'submit_mult_spatial',
1400 __('Spatial'), 'b_spatial.png', 'spatial'
1403 if (! empty($tbl_storage_engine)
1404 && ($tbl_storage_engine == 'MYISAM'
1405 || $tbl_storage_engine == 'ARIA'
1406 || $tbl_storage_engine == 'MARIA')
1408 $html_output .= PMA_Util::getButtonOrImage(
1409 'submit_mult', 'mult_submit', 'submit_mult_fulltext',
1410 __('Fulltext'), 'b_ftext.png', 'ftext'
1414 return $html_output;
1418 * Get HTML for move columns dialog
1420 * @return string $html_output
1422 function PMA_getHtmlDivForMoveColumnsDialog()
1424 $html_output = '<div id="move_columns_dialog" '
1425 . 'title="' . __('Move columns') . '" style="display: none">';
1427 $html_output .= '<p>'
1428 . __('Move the columns by dragging them up and down.') . '</p>';
1430 $html_output .= '<form action="tbl_structure.php">'
1431 . '<div>'
1432 . PMA_URL_getHiddenInputs($GLOBALS['db'], $GLOBALS['table'])
1433 . '<ul></ul>'
1434 . '</div>'
1435 . '</form>'
1436 . '</div>';
1438 return $html_output;
1442 * Get HTML for edit views'
1444 * @param string $url_params URL parameters
1446 * @return string $html_output
1448 function PMA_getHtmlForEditView($url_params)
1450 $retval = array();
1451 $query = "SELECT `VIEW_DEFINITION`, `CHECK_OPTION`, `DEFINER`, `SECURITY_TYPE`"
1452 . " FROM `INFORMATION_SCHEMA`.`VIEWS`"
1453 . " WHERE TABLE_SCHEMA='" . PMA_Util::sqlAddSlashes($GLOBALS['db']) . "'"
1454 . " AND TABLE_NAME='" . PMA_Util::sqlAddSlashes($GLOBALS['table']) . "';";
1455 $item = $GLOBALS['dbi']->fetchSingleRow($query);
1457 $view = array(
1458 'operation' => 'alter',
1459 'definer' => $item['DEFINER'],
1460 'sql_security' => $item['SECURITY_TYPE'],
1461 'name' => $GLOBALS['table'],
1462 'as' => $item['VIEW_DEFINITION'],
1463 'with' => $item['CHECK_OPTION'],
1465 $url = 'view_create.php' . PMA_URL_getCommon($url_params) . '&amp;';
1466 $url .= implode(
1467 '&amp;',
1468 array_map(
1469 function ($key, $val) {
1470 return 'view[' . urlencode($key) . ']=' . urlencode($val);
1472 array_keys($view),
1473 $view
1476 $html_output = PMA_Util::linkOrButton(
1477 $url,
1478 PMA_Util::getIcon('b_edit.png', __('Edit view'), true)
1480 return $html_output;
1484 * Get HTML links for 'Print view', 'Relation view', 'Propose table structure',
1485 * 'Track table' and 'Move columns'
1487 * @param string $url_query url query
1488 * @param boolean $tbl_is_view whether table is view or not
1489 * @param boolean $db_is_information_schema whether db is information schema or not
1490 * @param string $tbl_storage_engine table storage engine
1491 * @param array $cfgRelation current relation parameters
1493 * @return string $html_output
1495 function PMA_getHtmlForOptionalActionLinks($url_query, $tbl_is_view,
1496 $db_is_information_schema, $tbl_storage_engine, $cfgRelation
1498 $html_output = '<a href="tbl_printview.php?' . $url_query . '" target="print_view">'
1499 . PMA_Util::getIcon('b_print.png', __('Print view'), true)
1500 . '</a>';
1502 if (! $tbl_is_view && ! $db_is_information_schema) {
1503 // if internal relations are available, or foreign keys are supported
1504 // ($tbl_storage_engine comes from libraries/tbl_info.inc.php
1506 if ($cfgRelation['relwork']
1507 || PMA_Util::isForeignKeySupported($tbl_storage_engine)
1509 $html_output .= '<a href="tbl_relation.php?' . $url_query . '">'
1510 . PMA_Util::getIcon(
1511 'b_relations.png', __('Relation view'), true
1513 . '</a>';
1515 if (!PMA_DRIZZLE) {
1516 $html_output .= '<a href="sql.php?' . $url_query
1517 . '&amp;session_max_rows=all&amp;sql_query=' . urlencode(
1518 'SELECT * FROM ' . PMA_Util::backquote($GLOBALS['table'])
1519 . ' PROCEDURE ANALYSE()'
1520 ) . '">'
1521 . PMA_Util::getIcon(
1522 'b_tblanalyse.png',
1523 __('Propose table structure'),
1524 true
1526 . '</a>';
1527 $html_output .= PMA_Util::showMySQLDocu('procedure_analyse') . "\n";
1529 if (PMA_Tracker::isActive()) {
1530 $html_output .= '<a href="tbl_tracking.php?' . $url_query . '">'
1531 . PMA_Util::getIcon('eye.png', __('Track table'), true)
1532 . '</a>';
1534 $html_output .= '<a href="#" id="move_columns_anchor">'
1535 . PMA_Util::getIcon('b_move.png', __('Move columns'), true)
1536 . '</a>';
1539 return $html_output;
1543 * Get HTML snippet for "Add column" feature in structure table
1545 * @param array $columns_list column list array
1547 * @return string $html_output
1549 function PMA_getHtmlForAddColumn($columns_list)
1551 $html_output = '<form method="post" action="tbl_addfield.php" '
1552 . 'id="addColumns" name="addColumns" '
1553 . 'onsubmit="return checkFormElementInRange('
1554 . 'this, \'num_fields\', \'' . str_replace(
1555 '\'',
1556 '\\\'',
1557 __('You have to add at least one column.')
1558 ) . '\', 1)'
1559 . '">';
1561 $html_output .= PMA_URL_getHiddenInputs(
1562 $GLOBALS['db'],
1563 $GLOBALS['table']
1565 if (PMA_Util::showIcons('ActionLinksMode')) {
1566 $html_output .=PMA_Util::getImage(
1567 'b_insrow.png',
1568 __('Add column')
1571 $num_fields = '<input type="number" name="num_fields" size="2" '
1572 . 'maxlength="2" value="1" onfocus="this.select()" '
1573 . 'min="1" required />';
1574 $html_output .= sprintf(__('Add %s column(s)'), $num_fields);
1576 // I tried displaying the drop-down inside the label but with Firefox
1577 // the drop-down was blinking
1578 $column_selector = '<select name="after_field" '
1579 . 'onclick="this.form.field_where[2].checked=true" '
1580 . 'onchange="this.form.field_where[2].checked=true">';
1582 foreach ($columns_list as $one_column_name) {
1583 $column_selector .= '<option '
1584 . 'value="' . htmlspecialchars($one_column_name) . '">'
1585 . htmlspecialchars($one_column_name)
1586 . '</option>';
1588 $column_selector .= '</select>';
1590 $choices = array(
1591 'last' => __('At End of Table'),
1592 'first' => __('At Beginning of Table'),
1593 'after' => sprintf(__('After %s'), '')
1595 $html_output .= PMA_Util::getRadioFields(
1596 'field_where', $choices, 'last', false
1598 $html_output .= $column_selector;
1599 $html_output .= '<input type="submit" value="' . __('Go') . '" />'
1600 . '</form>';
1602 return $html_output;
1606 * Get HTML snippet for table rows in the Information ->Space usage table
1608 * @param boolean $odd_row whether current row is odd or even
1609 * @param string $name type of usage
1610 * @param string $value value of usage
1611 * @param string $unit unit
1613 * @return string $html_output
1615 function PMA_getHtmlForSpaceUsageTableRow($odd_row, $name, $value, $unit)
1617 $html_output = '<tr class="' . (($odd_row = !$odd_row) ? 'odd' : 'even') . '">';
1618 $html_output .= '<th class="name">' . $name . '</th>';
1619 $html_output .= '<td class="value">' . $value . '</td>';
1620 $html_output .= '<td class="unit">' . $unit . '</td>';
1621 $html_output .= '</tr>';
1623 return $html_output;
1627 * Get HTML for Optimize link if overhead in Information fieldset
1629 * @param type $url_query URL query
1631 * @return string $html_output
1633 function PMA_getHtmlForOptimizeLink($url_query)
1635 $html_output = '<tr class="tblFooters">';
1636 $html_output .= '<td colspan="3" class="center">';
1637 $html_output .= '<a href="sql.php?' . $url_query
1638 . '&pos=0&amp;sql_query=' . urlencode(
1639 'OPTIMIZE TABLE ' . PMA_Util::backquote($GLOBALS['table'])
1641 . '">'
1642 . PMA_Util::getIcon('b_tbloptimize.png', __('Optimize table'))
1643 . '</a>';
1644 $html_output .= '</td>';
1645 $html_output .= '</tr>';
1647 return $html_output;
1651 * Get HTML for 'Row statistics' table row
1653 * @param type $odd_row whether current row is odd or even
1654 * @param type $name statement name
1655 * @param type $value value
1657 * @return string $html_output
1659 function PMA_getHtmlForRowStatsTableRow($odd_row, $name, $value)
1661 $html_output = '<tr class="' . (($odd_row = !$odd_row) ? 'odd' : 'even') . '">';
1662 $html_output .= '<th class="name">' . $name . '</th>';
1663 $html_output .= '<td class="value">' . $value . '</td>';
1664 $html_output .= '</tr>';
1666 return $html_output;
1670 * Get HTML snippet for display Row statistics table
1672 * @param array $showtable show table array
1673 * @param string $tbl_collation table collation
1674 * @param boolean $is_innodb whether table is innob or not
1675 * @param boolean $mergetable Checks if current table is a merge table
1676 * @param integer $avg_size average size
1677 * @param string $avg_unit average unit
1679 * @return string $html_output
1681 function getHtmlForRowStatsTable($showtable, $tbl_collation,
1682 $is_innodb, $mergetable, $avg_size, $avg_unit
1684 $odd_row = false;
1685 $html_output = '<table id="tablerowstats" class="data">';
1686 $html_output .= '<caption class="tblHeaders">'
1687 . __('Row statistics') . '</caption>';
1688 $html_output .= '<tbody>';
1690 if (isset($showtable['Row_format'])) {
1691 if ($showtable['Row_format'] == 'Fixed') {
1692 $value = __('static');
1693 } elseif ($showtable['Row_format'] == 'Dynamic') {
1694 $value = __('dynamic');
1695 } else {
1696 $value = $showtable['Row_format'];
1698 $html_output .= PMA_getHtmlForRowStatsTableRow(
1699 $odd_row, __('Format'), $value
1701 $odd_row = !$odd_row;
1703 if (! empty($showtable['Create_options'])) {
1704 if ($showtable['Create_options'] == 'partitioned') {
1705 $value = __('partitioned');
1706 } else {
1707 $value = $showtable['Create_options'];
1709 $html_output .= PMA_getHtmlForRowStatsTableRow(
1710 $odd_row, __('Options'), $value
1712 $odd_row = !$odd_row;
1714 if (!empty($tbl_collation)) {
1715 $value = '<dfn title="' . PMA_getCollationDescr($tbl_collation) . '">'
1716 . $tbl_collation . '</dfn>';
1717 $html_output .= PMA_getHtmlForRowStatsTableRow(
1718 $odd_row, __('Collation'), $value
1720 $odd_row = !$odd_row;
1722 if (!$is_innodb && isset($showtable['Rows'])) {
1723 $html_output .= PMA_getHtmlForRowStatsTableRow(
1724 $odd_row,
1725 __('Rows'),
1726 PMA_Util::formatNumber($showtable['Rows'], 0)
1728 $odd_row = !$odd_row;
1730 if (!$is_innodb
1731 && isset($showtable['Avg_row_length'])
1732 && $showtable['Avg_row_length'] > 0
1734 list($avg_row_length_value, $avg_row_length_unit)
1735 = PMA_Util::formatByteDown(
1736 $showtable['Avg_row_length'],
1740 $html_output .= PMA_getHtmlForRowStatsTableRow(
1741 $odd_row,
1742 __('Row length'),
1743 ($avg_row_length_value . ' ' . $avg_row_length_unit)
1745 unset($avg_row_length_value, $avg_row_length_unit);
1746 $odd_row = !$odd_row;
1748 if (!$is_innodb
1749 && isset($showtable['Data_length'])
1750 && $showtable['Rows'] > 0
1751 && $mergetable == false
1753 $html_output .= PMA_getHtmlForRowStatsTableRow(
1754 $odd_row,
1755 __('Row size'),
1756 ($avg_size . ' ' . $avg_unit)
1758 $odd_row = !$odd_row;
1760 if (isset($showtable['Auto_increment'])) {
1761 $html_output .= PMA_getHtmlForRowStatsTableRow(
1762 $odd_row,
1763 __('Next autoindex'),
1764 PMA_Util::formatNumber($showtable['Auto_increment'], 0)
1766 $odd_row = !$odd_row;
1768 if (isset($showtable['Create_time'])) {
1769 $html_output .= PMA_getHtmlForRowStatsTableRow(
1770 $odd_row,
1771 __('Creation'),
1772 PMA_Util::localisedDate(strtotime($showtable['Create_time']))
1774 $odd_row = !$odd_row;
1776 if (isset($showtable['Update_time'])) {
1777 $html_output .= PMA_getHtmlForRowStatsTableRow(
1778 $odd_row,
1779 __('Last update'),
1780 PMA_Util::localisedDate(strtotime($showtable['Update_time']))
1782 $odd_row = !$odd_row;
1784 if (isset($showtable['Check_time'])) {
1785 $html_output .= PMA_getHtmlForRowStatsTableRow(
1786 $odd_row,
1787 __('Last check'),
1788 PMA_Util::localisedDate(strtotime($showtable['Check_time']))
1791 $html_output .= '</tbody>'
1792 . '</table>'
1793 . '</fieldset>'
1794 . '</div>';
1796 return $html_output;
1800 * Get HTML snippet for action row in structure table,
1801 * This function returns common HTML <td> for Primary, Unique, Index,
1802 * Spatial actions
1804 * @param array $type column type
1805 * @param array $tbl_storage_engine table storage engine
1806 * @param string $class class attribute for <td>
1807 * @param boolean $hasField has field
1808 * @param boolean $hasLinkClass has <a> the class attribute
1809 * @param string $url_query url query
1810 * @param boolean $primary primary if set, false otherwise
1811 * @param string $syntax Sql syntax
1812 * @param string $message message to show
1813 * @param string $action action
1814 * @param array $titles titles array
1815 * @param array $row current row
1816 * @param boolean $isPrimary is primary action
1818 * @return array $html_output, $action_enabled
1820 function PMA_getHtmlForActionRowInStructureTable($type, $tbl_storage_engine,
1821 $class, $hasField, $hasLinkClass, $url_query, $primary, $syntax,
1822 $message, $action, $titles, $row, $isPrimary
1824 $html_output = '<li class="'. $class .'">';
1826 if ($type == 'text'
1827 || $type == 'blob'
1828 || 'ARCHIVE' == $tbl_storage_engine
1829 || $hasField
1831 $html_output .= $titles['No' . $action];
1832 $action_enabled = false;
1833 } else {
1834 $html_output .= '<a rel="samepage" '
1835 . ($hasLinkClass ? 'class="ajax add_primary_key_anchor" ' : '')
1836 . 'href="sql.php?' . $url_query . '&amp;sql_query='
1837 . urlencode(
1838 'ALTER TABLE ' . PMA_Util::backquote($GLOBALS['table'])
1839 . ($isPrimary ? ($primary ? ' DROP PRIMARY KEY,' : '') : '')
1840 . ' ' . $syntax . '('
1841 . PMA_Util::backquote($row['Field']) . ');'
1843 . '&amp;message_to_show=' . urlencode(
1844 sprintf(
1845 $message,
1846 htmlspecialchars($row['Field'])
1848 ) . '" >'
1849 . $titles[$action] . '</a>';
1850 $action_enabled = true;
1852 $html_output .= '</li>';
1854 return array($html_output, $action_enabled);
1858 * Get HTML for fulltext action,
1859 * and this function returns $fulltext_enabled boolean value also
1861 * @param string $tbl_storage_engine table storage engine
1862 * @param string $type column type
1863 * @param string $url_query url query
1864 * @param array $row current row
1865 * @param array $titles titles array
1867 * @return type array $html_output, $fulltext_enabled
1869 function PMA_getHtmlForFullTextAction($tbl_storage_engine, $type, $url_query,
1870 $row, $titles
1872 $html_output = '<li class="fulltext nowrap">';
1873 if (! empty($tbl_storage_engine)
1874 && ($tbl_storage_engine == 'MYISAM'
1875 || $tbl_storage_engine == 'ARIA'
1876 || $tbl_storage_engine == 'MARIA'
1877 || ($tbl_storage_engine == 'INNODB' && PMA_MYSQL_INT_VERSION >= 50604))
1878 && (strpos(' ' . $type, 'text') || strpos(' ' . $type, 'char'))
1880 $html_output .= '<a rel="samepage" href="sql.php?' . $url_query . '&amp;sql_query='
1881 . urlencode(
1882 'ALTER TABLE ' . PMA_Util::backquote($GLOBALS['table'])
1883 . ' ADD FULLTEXT(' . PMA_Util::backquote($row['Field'])
1884 . ');'
1886 . '&amp;message_to_show='
1887 . urlencode(
1888 sprintf(
1889 __('An index has been added on %s'),
1890 htmlspecialchars($row['Field'])
1893 . '">';
1894 $html_output .= $titles['IdxFulltext'] . '</a>';
1895 $fulltext_enabled = true;
1896 } else {
1897 $html_output .= $titles['NoIdxFulltext'];
1898 $fulltext_enabled = false;
1900 $html_output .= '</li>';
1901 return array($html_output, $fulltext_enabled);
1905 * Get HTML snippet for "Distinc Value" action
1907 * @param string $url_query url query
1908 * @param array $row current row
1909 * @param array $titles titles array
1911 * @return string $html_output
1913 function PMA_getHtmlForDistinctValueAction($url_query, $row, $titles)
1915 $html_output = '<li class="browse nowrap">';
1916 $html_output .= '<a href="sql.php?' . $url_query . '&amp;sql_query='
1917 . urlencode(
1918 'SELECT COUNT(*) AS ' . PMA_Util::backquote(__('Rows'))
1919 . ', ' . PMA_Util::backquote($row['Field'])
1920 . ' FROM ' . PMA_Util::backquote($GLOBALS['table'])
1921 . ' GROUP BY ' . PMA_Util::backquote($row['Field'])
1922 . ' ORDER BY ' . PMA_Util::backquote($row['Field'])
1924 . '">'
1925 . $titles['DistinctValues']
1926 . '</a>';
1927 $html_output .= '</li>';
1929 return $html_output;
1933 * Get HTML snippet for Actions in table structure
1935 * @param string $type column type
1936 * @param string $tbl_storage_engine table storage engine
1937 * @param boolean $primary primary if set, false otherwise
1938 * @param string $field_name column name
1939 * @param string $url_query url query
1940 * @param array $titles titles array
1941 * @param array $row current row
1942 * @param string $rownum row number
1943 * @param array $hidden_titles hidden titles
1944 * @param array $columns_with_unique_index columns with unique index
1946 * @return string $html_output;
1948 function PMA_getHtmlForActionsInTableStructure($type, $tbl_storage_engine,
1949 $primary, $field_name, $url_query, $titles, $row, $rownum, $hidden_titles,
1950 $columns_with_unique_index
1952 $html_output = '<td><ul class="table-structure-actions resizable-menu">';
1953 list($primary, $primary_enabled)
1954 = PMA_getHtmlForActionRowInStructureTable(
1955 $type, $tbl_storage_engine,
1956 'primary nowrap',
1957 ($primary && $primary->hasColumn($field_name)),
1958 true, $url_query, $primary,
1959 'ADD PRIMARY KEY',
1960 __('A primary key has been added on %s'),
1961 'Primary', $titles, $row, true
1963 $html_output .= $primary;
1964 list($unique, $unique_enabled)
1965 = PMA_getHtmlForActionRowInStructureTable(
1966 $type, $tbl_storage_engine,
1967 'unique nowrap',
1968 isset($columns_with_unique_index[$field_name]),
1969 false, $url_query, $primary, 'ADD UNIQUE',
1970 __('An index has been added on %s'),
1971 'Unique', $titles, $row, false
1973 $html_output .= $unique;
1974 list($index, $index_enabled)
1975 = PMA_getHtmlForActionRowInStructureTable(
1976 $type, $tbl_storage_engine,
1977 'index nowrap', false, false, $url_query,
1978 $primary, 'ADD INDEX', __('An index has been added on %s'),
1979 'Index', $titles, $row, false
1981 $html_output .= $index;
1982 if (!PMA_DRIZZLE) {
1983 $spatial_types = array(
1984 'geometry', 'point', 'linestring', 'polygon', 'multipoint',
1985 'multilinestring', 'multipolygon', 'geomtrycollection'
1987 list($spatial, $spatial_enabled)
1988 = PMA_getHtmlForActionRowInStructureTable(
1989 $type, $tbl_storage_engine,
1990 'spatial nowrap',
1991 (! in_array($type, $spatial_types)
1992 || 'MYISAM' != $tbl_storage_engine
1994 false, $url_query, $primary, 'ADD SPATIAL',
1995 __('An index has been added on %s'), 'Spatial',
1996 $titles, $row, false
1998 $html_output .= $spatial;
2000 // FULLTEXT is possible on TEXT, CHAR and VARCHAR
2001 list ($fulltext, $fulltext_enabled) = PMA_getHtmlForFullTextAction(
2002 $tbl_storage_engine, $type, $url_query, $row, $titles
2004 $html_output .= $fulltext;
2006 $html_output .= PMA_getHtmlForDistinctValueAction($url_query, $row, $titles);
2007 $html_output .= '</ul></td>';
2008 return $html_output;
2012 * Get hidden action titles (image and string)
2014 * @return array $hidden_titles
2016 function PMA_getHiddenTitlesArray()
2018 $hidden_titles = array();
2019 $hidden_titles['DistinctValues'] = PMA_Util::getIcon(
2020 'b_browse.png', __('Distinct values'), true
2022 $hidden_titles['Primary'] = PMA_Util::getIcon(
2023 'b_primary.png', __('Add primary key'), true
2025 $hidden_titles['NoPrimary'] = PMA_Util::getIcon(
2026 'bd_primary.png', __('Add primary key'), true
2028 $hidden_titles['Index'] = PMA_Util::getIcon(
2029 'b_index.png', __('Add index'), true
2031 $hidden_titles['NoIndex'] = PMA_Util::getIcon(
2032 'bd_index.png', __('Add index'), true
2034 $hidden_titles['Unique'] = PMA_Util::getIcon(
2035 'b_unique.png', __('Add unique index'), true
2037 $hidden_titles['NoUnique'] = PMA_Util::getIcon(
2038 'bd_unique.png', __('Add unique index'), true
2040 $hidden_titles['Spatial'] = PMA_Util::getIcon(
2041 'b_spatial.png', __('Add SPATIAL index'), true
2043 $hidden_titles['NoSpatial'] = PMA_Util::getIcon(
2044 'bd_spatial.png', __('Add SPATIAL index'), true
2046 $hidden_titles['IdxFulltext'] = PMA_Util::getIcon(
2047 'b_ftext.png', __('Add FULLTEXT index'), true
2049 $hidden_titles['NoIdxFulltext'] = PMA_Util::getIcon(
2050 'bd_ftext.png', __('Add FULLTEXT index'), true
2053 return $hidden_titles;
2057 * Get action titles (image or string array
2059 * @return array $titles
2061 function PMA_getActionTitlesArray()
2063 $titles = array();
2064 $titles['Change']
2065 = PMA_Util::getIcon('b_edit.png', __('Change'));
2066 $titles['Drop']
2067 = PMA_Util::getIcon('b_drop.png', __('Drop'));
2068 $titles['NoDrop']
2069 = PMA_Util::getIcon('b_drop.png', __('Drop'));
2070 $titles['Primary']
2071 = PMA_Util::getIcon('b_primary.png', __('Primary'));
2072 $titles['Index']
2073 = PMA_Util::getIcon('b_index.png', __('Index'));
2074 $titles['Unique']
2075 = PMA_Util::getIcon('b_unique.png', __('Unique'));
2076 $titles['Spatial']
2077 = PMA_Util::getIcon('b_spatial.png', __('Spatial'));
2078 $titles['IdxFulltext']
2079 = PMA_Util::getIcon('b_ftext.png', __('Fulltext'));
2080 $titles['NoPrimary']
2081 = PMA_Util::getIcon('bd_primary.png', __('Primary'));
2082 $titles['NoIndex']
2083 = PMA_Util::getIcon('bd_index.png', __('Index'));
2084 $titles['NoUnique']
2085 = PMA_Util::getIcon('bd_unique.png', __('Unique'));
2086 $titles['NoSpatial']
2087 = PMA_Util::getIcon('bd_spatial.png', __('Spatial'));
2088 $titles['NoIdxFulltext']
2089 = PMA_Util::getIcon('bd_ftext.png', __('Fulltext'));
2090 $titles['DistinctValues']
2091 = PMA_Util::getIcon('b_browse.png', __('Distinct values'));
2093 return $titles;
2097 * Get HTML snippet for display table statistics
2099 * @param array $showtable full table status info
2100 * @param integer $table_info_num_rows table info number of rows
2101 * @param boolean $tbl_is_view whether table is view or not
2102 * @param boolean $db_is_information_schema whether db is information schema or not
2103 * @param string $tbl_storage_engine table storage engine
2104 * @param string $url_query url query
2105 * @param string $tbl_collation table collation
2107 * @return string $html_output
2109 function PMA_getHtmlForDisplayTableStats($showtable, $table_info_num_rows,
2110 $tbl_is_view, $db_is_information_schema, $tbl_storage_engine, $url_query,
2111 $tbl_collation
2113 $html_output = '<div id="tablestatistics">';
2114 if (empty($showtable)) {
2115 $showtable = PMA_Table::sGetStatusInfo(
2116 $GLOBALS['db'], $GLOBALS['table'], null, true
2120 $nonisam = false;
2121 $is_innodb = (isset($showtable['Type']) && $showtable['Type'] == 'InnoDB');
2122 if (isset($showtable['Type'])
2123 && ! preg_match('@ISAM|HEAP@i', $showtable['Type'])
2125 $nonisam = true;
2128 // Gets some sizes
2130 $mergetable = PMA_Table::isMerge($GLOBALS['db'], $GLOBALS['table']);
2132 // this is to display for example 261.2 MiB instead of 268k KiB
2133 $max_digits = 3;
2134 $decimals = 1;
2135 list($data_size, $data_unit) = PMA_Util::formatByteDown(
2136 $showtable['Data_length'], $max_digits, $decimals
2138 if ($mergetable == false) {
2139 list($index_size, $index_unit) = PMA_Util::formatByteDown(
2140 $showtable['Index_length'], $max_digits, $decimals
2143 // InnoDB returns a huge value in Data_free, do not use it
2144 if (! $is_innodb
2145 && isset($showtable['Data_free'])
2146 && $showtable['Data_free'] > 0
2148 list($free_size, $free_unit) = PMA_Util::formatByteDown(
2149 $showtable['Data_free'], $max_digits, $decimals
2151 list($effect_size, $effect_unit) = PMA_Util::formatByteDown(
2152 $showtable['Data_length'] + $showtable['Index_length'] - $showtable['Data_free'],
2153 $max_digits, $decimals
2155 } else {
2156 list($effect_size, $effect_unit) = PMA_Util::formatByteDown(
2157 $showtable['Data_length'] + $showtable['Index_length'],
2158 $max_digits, $decimals
2161 list($tot_size, $tot_unit) = PMA_Util::formatByteDown(
2162 $showtable['Data_length'] + $showtable['Index_length'],
2163 $max_digits, $decimals
2165 if ($table_info_num_rows > 0) {
2166 list($avg_size, $avg_unit) = PMA_Util::formatByteDown(
2167 ($showtable['Data_length'] + $showtable['Index_length']) / $showtable['Rows'],
2168 6, 1
2172 // Displays them
2173 $odd_row = false;
2175 $html_output .= '<fieldset>'
2176 . '<legend>' . __('Information') . '</legend>'
2177 . '<a id="showusage"></a>';
2179 if (! $tbl_is_view && ! $db_is_information_schema) {
2180 $html_output .= '<table id="tablespaceusage" class="data">'
2181 . '<caption class="tblHeaders">' . __('Space usage') . '</caption>'
2182 . '<tbody>';
2184 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2185 $odd_row, __('Data'), $data_size, $data_unit
2187 $odd_row = !$odd_row;
2189 if (isset($index_size)) {
2190 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2191 $odd_row, __('Index'), $index_size, $index_unit
2193 $odd_row = !$odd_row;
2196 if (isset($free_size)) {
2197 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2198 $odd_row, __('Overhead'), $free_size, $free_unit
2200 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2201 $odd_row, __('Effective'), $effect_size, $effect_unit
2203 $odd_row = !$odd_row;
2205 if (isset($tot_size) && $mergetable == false) {
2206 $html_output .= PMA_getHtmlForSpaceUsageTableRow(
2207 $odd_row, __('Total'), $tot_size, $tot_unit
2209 $odd_row = !$odd_row;
2211 // Optimize link if overhead
2212 if (isset($free_size) && !PMA_DRIZZLE
2213 && ($tbl_storage_engine == 'MYISAM'
2214 || $tbl_storage_engine == 'ARIA'
2215 || $tbl_storage_engine == 'MARIA'
2216 || $tbl_storage_engine == 'BDB')
2218 $html_output .= PMA_getHtmlForOptimizeLink($url_query);
2220 $html_output .= '</tbody>'
2221 . '</table>';
2224 $html_output .= getHtmlForRowStatsTable(
2225 $showtable, $tbl_collation,
2226 $is_innodb, $mergetable,
2227 (isset ($avg_size) ? $avg_size : ''),
2228 (isset ($avg_unit) ? $avg_unit : '')
2231 return $html_output;
2235 * Displays HTML for changing one or more columns
2237 * @param string $db database name
2238 * @param string $table table name
2239 * @param array $selected the selected columns
2240 * @param string $action target script to call
2242 * @return boolean $regenerate true if error occurred
2245 function PMA_displayHtmlForColumnChange($db, $table, $selected, $action)
2247 // $selected comes from multi_submits.inc.php
2248 if (empty($selected)) {
2249 $selected[] = $_REQUEST['field'];
2250 $selected_cnt = 1;
2251 } else { // from a multiple submit
2252 $selected_cnt = count($selected);
2256 * @todo optimize in case of multiple fields to modify
2258 for ($i = 0; $i < $selected_cnt; $i++) {
2259 $fields_meta[] = $GLOBALS['dbi']->getColumns($db, $table, $selected[$i], true);
2261 $num_fields = count($fields_meta);
2262 // set these globals because tbl_columns_definition_form.inc.php
2263 // verifies them
2264 // @todo: refactor tbl_columns_definition_form.inc.php so that it uses
2265 // function params
2266 $GLOBALS['action'] = 'tbl_structure.php';
2267 $GLOBALS['num_fields'] = $num_fields;
2269 // Get more complete field information.
2270 // For now, this is done to obtain MySQL 4.1.2+ new TIMESTAMP options
2271 // and to know when there is an empty DEFAULT value.
2272 // Later, if the analyser returns more information, it
2273 // could be executed to replace the info given by SHOW FULL COLUMNS FROM.
2275 * @todo put this code into a require()
2276 * or maybe make it part of $GLOBALS['dbi']->getColumns();
2279 // We also need this to correctly learn if a TIMESTAMP is NOT NULL, since
2280 // SHOW FULL COLUMNS says NULL and SHOW CREATE TABLE says NOT NULL (tested
2281 // in MySQL 4.0.25).
2283 $show_create_table = $GLOBALS['dbi']->fetchValue(
2284 'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table),
2285 0, 1
2287 $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
2288 unset($show_create_table);
2290 * Form for changing properties.
2292 include 'libraries/tbl_columns_definition_form.inc.php';
2297 * Update the table's structure based on $_REQUEST
2299 * @param string $db database name
2300 * @param string $table table name
2302 * @return boolean $regenerate true if error occurred
2305 function PMA_updateColumns($db, $table)
2307 $err_url = 'tbl_structure.php?' . PMA_URL_getCommon($db, $table);
2308 $regenerate = false;
2309 $field_cnt = count($_REQUEST['field_name']);
2310 $key_fields = array();
2311 $changes = array();
2313 for ($i = 0; $i < $field_cnt; $i++) {
2314 $changes[] = 'CHANGE ' . PMA_Table::generateAlter(
2315 isset($_REQUEST['field_orig'][$i])
2316 ? $_REQUEST['field_orig'][$i]
2317 : '',
2318 $_REQUEST['field_name'][$i],
2319 $_REQUEST['field_type'][$i],
2320 $_REQUEST['field_length'][$i],
2321 $_REQUEST['field_attribute'][$i],
2322 isset($_REQUEST['field_collation'][$i])
2323 ? $_REQUEST['field_collation'][$i]
2324 : '',
2325 isset($_REQUEST['field_null'][$i])
2326 ? $_REQUEST['field_null'][$i]
2327 : 'NOT NULL',
2328 $_REQUEST['field_default_type'][$i],
2329 $_REQUEST['field_default_value'][$i],
2330 isset($_REQUEST['field_extra'][$i])
2331 ? $_REQUEST['field_extra'][$i]
2332 : false,
2333 isset($_REQUEST['field_comments'][$i])
2334 ? $_REQUEST['field_comments'][$i]
2335 : '',
2336 $key_fields,
2338 isset($_REQUEST['field_move_to'][$i])
2339 ? $_REQUEST['field_move_to'][$i]
2340 : ''
2342 } // end for
2344 // Builds the primary keys statements and updates the table
2345 $key_query = '';
2347 * this is a little bit more complex
2349 * @todo if someone selects A_I when altering a column we need to check:
2350 * - no other column with A_I
2351 * - the column has an index, if not create one
2353 if (count($key_fields)) {
2354 $fields = array();
2355 foreach ($key_fields as $each_field) {
2356 if (isset($_REQUEST['field_name'][$each_field]) && strlen($_REQUEST['field_name'][$each_field])) {
2357 $fields[] = PMA_Util::backquote($_REQUEST['field_name'][$each_field]);
2359 } // end for
2360 $key_query = ', ADD KEY (' . implode(', ', $fields) . ') ';
2364 // To allow replication, we first select the db to use and then run queries
2365 // on this db.
2366 if (! $GLOBALS['dbi']->selectDb($db)) {
2367 PMA_Util::mysqlDie(
2368 $GLOBALS['dbi']->getError(),
2369 'USE ' . PMA_Util::backquote($db) . ';',
2371 $err_url
2374 $sql_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ';
2375 $sql_query .= implode(', ', $changes) . $key_query;
2376 $sql_query .= ';';
2377 $result = $GLOBALS['dbi']->tryQuery($sql_query);
2379 $response = PMA_Response::getInstance();
2380 if ($result !== false) {
2381 $message = PMA_Message::success(
2382 __('Table %1$s has been altered successfully')
2384 $message->addParam($table);
2387 * If comments were sent, enable relation stuff
2389 include_once 'libraries/transformations.lib.php';
2391 // update field names in relation
2392 if (isset($_REQUEST['field_orig']) && is_array($_REQUEST['field_orig'])) {
2393 foreach ($_REQUEST['field_orig'] as $fieldindex => $fieldcontent) {
2394 if ($_REQUEST['field_name'][$fieldindex] != $fieldcontent) {
2395 PMA_REL_renameField(
2396 $db, $table, $fieldcontent,
2397 $_REQUEST['field_name'][$fieldindex]
2403 // update mime types
2404 if (isset($_REQUEST['field_mimetype'])
2405 && is_array($_REQUEST['field_mimetype'])
2406 && $GLOBALS['cfg']['BrowseMIME']
2408 foreach ($_REQUEST['field_mimetype'] as $fieldindex => $mimetype) {
2409 if (isset($_REQUEST['field_name'][$fieldindex])
2410 && strlen($_REQUEST['field_name'][$fieldindex])
2412 PMA_setMIME(
2413 $db, $table, $_REQUEST['field_name'][$fieldindex],
2414 $mimetype,
2415 $_REQUEST['field_transformation'][$fieldindex],
2416 $_REQUEST['field_transformation_options'][$fieldindex]
2422 $response->addHTML(
2423 PMA_Util::getMessage($message, $sql_query, 'success')
2425 } else {
2426 // An error happened while inserting/updating a table definition
2427 $response->isSuccess(false);
2428 $response->addJSON(
2429 'message',
2430 PMA_Message::rawError(__('Query error') . ':<br />'.$GLOBALS['dbi']->getError())
2432 $regenerate = true;
2434 return $regenerate;
2438 * Moves columns in the table's structure based on $_REQUEST
2440 * @param string $db database name
2441 * @param string $table table name
2443 * @return void
2445 function PMA_moveColumns($db, $table)
2447 $GLOBALS['dbi']->selectDb($db);
2450 * load the definitions for all columns
2452 $columns = $GLOBALS['dbi']->getColumnsFull($db, $table);
2453 $column_names = array_keys($columns);
2454 $changes = array();
2455 $we_dont_change_keys = array();
2457 // move columns from first to last
2458 for ($i = 0, $l = count($_REQUEST['move_columns']); $i < $l; $i++) {
2459 $column = $_REQUEST['move_columns'][$i];
2460 // is this column already correctly placed?
2461 if ($column_names[$i] == $column) {
2462 continue;
2465 // it is not, let's move it to index $i
2466 $data = $columns[$column];
2467 $extracted_columnspec = PMA_Util::extractColumnSpec($data['Type']);
2468 if (isset($data['Extra']) && $data['Extra'] == 'on update CURRENT_TIMESTAMP') {
2469 $extracted_columnspec['attribute'] = $data['Extra'];
2470 unset($data['Extra']);
2472 $current_timestamp = false;
2473 if (($data['Type'] == 'timestamp' || $data['Type'] == 'datetime')
2474 && $data['Default'] == 'CURRENT_TIMESTAMP'
2476 $current_timestamp = true;
2478 $default_type
2479 = $data['Null'] === 'YES' && $data['Default'] === null
2480 ? 'NULL'
2481 : ($current_timestamp
2482 ? 'CURRENT_TIMESTAMP'
2483 : ($data['Default'] === null
2484 ? 'NONE'
2485 : 'USER_DEFINED'));
2487 $changes[] = 'CHANGE ' . PMA_Table::generateAlter(
2488 $column,
2489 $column,
2490 strtoupper($extracted_columnspec['type']),
2491 $extracted_columnspec['spec_in_brackets'],
2492 $extracted_columnspec['attribute'],
2493 isset($data['Collation']) ? $data['Collation'] : '',
2494 $data['Null'] === 'YES' ? 'NULL' : 'NOT NULL',
2495 $default_type,
2496 $current_timestamp ? '' : $data['Default'],
2497 isset($data['Extra']) && $data['Extra'] !== '' ? $data['Extra'] : false,
2498 isset($data['Comments']) && $data['Comments'] !== ''
2499 ? $data['Comments'] : false,
2500 $we_dont_change_keys,
2502 $i === 0 ? '-first' : $column_names[$i - 1]
2504 // update current column_names array, first delete old position
2505 for ($j = 0, $ll = count($column_names); $j < $ll; $j++) {
2506 if ($column_names[$j] == $column) {
2507 unset($column_names[$j]);
2510 // insert moved column
2511 array_splice($column_names, $i, 0, $column);
2513 $response = PMA_Response::getInstance();
2514 if (empty($changes)) { // should never happen
2515 $response->isSuccess(false);
2516 exit;
2518 $move_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ';
2519 $move_query .= implode(', ', $changes);
2520 // move columns
2521 $GLOBALS['dbi']->tryQuery($move_query);
2522 $tmp_error = $GLOBALS['dbi']->getError();
2523 if ($tmp_error) {
2524 $response->isSuccess(false);
2525 $response->addJSON('message', PMA_Message::error($tmp_error));
2526 } else {
2527 $message = PMA_Message::success(
2528 __('The columns have been moved successfully.')
2530 $response->addJSON('message', $message);
2531 $response->addJSON('columns', $column_names);
2533 exit;
2537 * Get columns with unique index
2539 * @param string $db database name
2540 * @param string $table tablename
2542 * @return array $columns_with_unique_index An array of columns with unique index,
2543 * with $column name as the array key
2545 function PMA_getColumnsWithUniqueIndex($db ,$table)
2547 $columns_with_unique_index = array();
2548 foreach (PMA_Index::getFromTable($table, $db) as $index) {
2549 if ($index->isUnique() && $index->getChoice() == 'UNIQUE') {
2550 $columns = $index->getColumns();
2551 foreach ($columns as $column_name => $dummy) {
2552 $columns_with_unique_index[$column_name] = 1;
2556 return $columns_with_unique_index;
2560 * Check column names for MySQL reserved words
2562 * @param string $db database name
2563 * @param string $table tablename
2565 * @return array $messages array of PMA_Messages
2567 function PMA_getReservedWordColumnNameMessages($db ,$table)
2569 $messages = array();
2570 if ($GLOBALS['cfg']['ReservedWordDisableWarning'] === false) {
2571 $pma_table = new PMA_Table($table, $db);
2572 $columns = $pma_table->getReservedColumnNames();
2573 if (!empty($columns)) {
2574 foreach ($columns as $column) {
2575 $msg = PMA_message::notice(
2576 __('The column name \'%s\' is a MySQL reserved keyword.')
2578 $msg->addParam($column);
2579 $messages[] = $msg;
2583 return $messages;
2587 * Function to get the type of command for multiple field handling
2589 * @return string
2591 function PMA_getMultipleFieldCommandType()
2593 $submit_mult = null;
2595 if (isset($_REQUEST['submit_mult_change_x'])) {
2596 $submit_mult = 'change';
2597 } elseif (isset($_REQUEST['submit_mult_drop_x'])) {
2598 $submit_mult = 'drop';
2599 } elseif (isset($_REQUEST['submit_mult_primary_x'])) {
2600 $submit_mult = 'primary';
2601 } elseif (isset($_REQUEST['submit_mult_index_x'])) {
2602 $submit_mult = 'index';
2603 } elseif (isset($_REQUEST['submit_mult_unique_x'])) {
2604 $submit_mult = 'unique';
2605 } elseif (isset($_REQUEST['submit_mult_spatial_x'])) {
2606 $submit_mult = 'spatial';
2607 } elseif (isset($_REQUEST['submit_mult_fulltext_x'])) {
2608 $submit_mult = 'ftext';
2609 } elseif (isset($_REQUEST['submit_mult_browse_x'])) {
2610 $submit_mult = 'browse';
2611 } elseif (isset($_REQUEST['submit_mult'])) {
2612 $submit_mult = $_REQUEST['submit_mult'];
2613 } elseif (isset($_REQUEST['mult_btn']) && $_REQUEST['mult_btn'] == __('Yes')) {
2614 $submit_mult = 'row_delete';
2615 if (isset($_REQUEST['selected'])) {
2616 $_REQUEST['selected_fld'] = $_REQUEST['selected'];
2620 return $submit_mult;
2624 * Function to display table browse for selected columns
2626 * @param string $db current database
2627 * @param string $table current table
2628 * @param string $goto goto page url
2629 * @param string $pmaThemeImage URI of the pma theme image
2631 * @return void
2633 function PMA_displayTableBrowseForSelectedColumns($db, $table, $goto,
2634 $pmaThemeImage
2636 $GLOBALS['active_page'] = 'sql.php';
2637 $sql_query = '';
2638 foreach ($_REQUEST['selected_fld'] as $idx => $sval) {
2639 if ($sql_query == '') {
2640 $sql_query .= 'SELECT ' . PMA_Util::backquote($sval);
2641 } else {
2642 $sql_query .= ', ' . PMA_Util::backquote($sval);
2645 $sql_query .= ' FROM ' . PMA_Util::backquote($db)
2646 . '.' . PMA_Util::backquote($table);
2648 // Parse and analyze the query
2649 include_once 'libraries/parse_analyze.inc.php';
2651 include_once 'libraries/sql.lib.php';
2653 PMA_executeQueryAndSendQueryResponse(
2654 $analyzed_sql_results, false, $db, $table, null, null, null, false,
2655 null, null, null, null, $goto, $pmaThemeImage, null, null,
2656 null, $sql_query, null, null