1. Check existence of mb_string, mysql and xml extensions before installation.
[openemr.git] / phpmyadmin / libraries / tracking.lib.php
blobdc839b04136662edbcbf4cae4150a20556ba60d9
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Functions used for database and table tracking
6 * @package PhpMyAdmin
7 */
9 /**
10 * Filters tracking entries
12 * @param array $data the entries to filter
13 * @param string $filter_ts_from "from" date
14 * @param string $filter_ts_to "to" date
15 * @param array $filter_users users
17 * @return array filtered entries
19 function PMA_filterTracking(
20 $data, $filter_ts_from, $filter_ts_to, $filter_users
21 ) {
22 $tmp_entries = array();
23 $id = 0;
24 foreach ($data as $entry) {
25 $timestamp = strtotime($entry['date']);
26 $filtered_user = in_array($entry['username'], $filter_users);
27 if ($timestamp >= $filter_ts_from
28 && $timestamp <= $filter_ts_to
29 && (in_array('*', $filter_users) || $filtered_user)
30 ) {
31 $tmp_entries[] = array(
32 'id' => $id,
33 'timestamp' => $timestamp,
34 'username' => $entry['username'],
35 'statement' => $entry['statement']
38 $id++;
40 return($tmp_entries);
43 /**
44 * Function to get html for data definition and data manipulation statements
46 * @param string $url_query url query
47 * @param int $last_version last version
48 * @param string $db database
49 * @param array $selected selected tables
50 * @param string $type type of the table; table, view or both
52 * @return string
54 function PMA_getHtmlForDataDefinitionAndManipulationStatements($url_query,
55 $last_version, $db, $selected, $type = 'both'
56 ) {
57 $html = '<div id="div_create_version">';
58 $html .= '<form method="post" action="' . $url_query . '">';
59 $html .= PMA_URL_getHiddenInputs($db);
60 foreach ($selected as $selected_table) {
61 $html .= '<input type="hidden" name="selected[]"'
62 . ' value="' . htmlspecialchars($selected_table) . '" />';
65 $html .= '<fieldset>';
66 $html .= '<legend>';
67 if (count($selected) == 1) {
68 $html .= sprintf(
69 __('Create version %1$s of %2$s'),
70 ($last_version + 1),
71 htmlspecialchars($db . '.' . $selected[0])
73 } else {
74 $html .= sprintf(__('Create version %1$s'), ($last_version + 1));
76 $html .= '</legend>';
77 $html .= '<input type="hidden" name="version" value="' . ($last_version + 1)
78 . '" />';
79 $html .= '<p>' . __('Track these data definition statements:')
80 . '</p>';
82 if ($type == 'both' || $type == 'table') {
83 $html .= '<input type="checkbox" name="alter_table" value="true"'
84 . (/*overload*/mb_stripos(
85 $GLOBALS['cfg']['Server']['tracking_default_statements'],
86 'ALTER TABLE'
87 ) !== false ? ' checked="checked"' : '')
88 . ' /> ALTER TABLE<br/>';
89 $html .= '<input type="checkbox" name="rename_table" value="true"'
90 . (/*overload*/mb_stripos(
91 $GLOBALS['cfg']['Server']['tracking_default_statements'],
92 'RENAME TABLE'
93 ) !== false ? ' checked="checked"' : '')
94 . ' /> RENAME TABLE<br/>';
95 $html .= '<input type="checkbox" name="create_table" value="true"'
96 . (/*overload*/mb_stripos(
97 $GLOBALS['cfg']['Server']['tracking_default_statements'],
98 'CREATE TABLE'
99 ) !== false ? ' checked="checked"' : '')
100 . ' /> CREATE TABLE<br/>';
101 $html .= '<input type="checkbox" name="drop_table" value="true"'
102 . (/*overload*/mb_stripos(
103 $GLOBALS['cfg']['Server']['tracking_default_statements'],
104 'DROP TABLE'
105 ) !== false ? ' checked="checked"' : '')
106 . ' /> DROP TABLE<br/>';
108 if ($type == 'both') {
109 $html .= '<br/>';
111 if ($type == 'both' || $type == 'view') {
112 $html .= '<input type="checkbox" name="alter_view" value="true"'
113 . (/*overload*/mb_stripos(
114 $GLOBALS['cfg']['Server']['tracking_default_statements'],
115 'ALTER VIEW'
116 ) !== false ? ' checked="checked"' : '')
117 . ' /> ALTER VIEW<br/>';
118 $html .= '<input type="checkbox" name="create_view" value="true"'
119 . (/*overload*/mb_stripos(
120 $GLOBALS['cfg']['Server']['tracking_default_statements'],
121 'CREATE VIEW'
122 ) !== false ? ' checked="checked"' : '')
123 . ' /> CREATE VIEW<br/>';
124 $html .= '<input type="checkbox" name="drop_view" value="true"'
125 . (/*overload*/mb_stripos(
126 $GLOBALS['cfg']['Server']['tracking_default_statements'],
127 'DROP VIEW'
128 ) !== false ? ' checked="checked"' : '')
129 . ' /> DROP VIEW<br/>';
131 $html .= '<br/>';
133 $html .= '<input type="checkbox" name="create_index" value="true"'
134 . (/*overload*/mb_stripos(
135 $GLOBALS['cfg']['Server']['tracking_default_statements'],
136 'CREATE INDEX'
137 ) !== false ? ' checked="checked"' : '')
138 . ' /> CREATE INDEX<br/>';
139 $html .= '<input type="checkbox" name="drop_index" value="true"'
140 . (/*overload*/mb_stripos(
141 $GLOBALS['cfg']['Server']['tracking_default_statements'],
142 'DROP INDEX'
143 ) !== false ? ' checked="checked"' : '')
144 . ' /> DROP INDEX<br/>';
145 $html .= '<p>' . __('Track these data manipulation statements:') . '</p>';
146 $html .= '<input type="checkbox" name="insert" value="true"'
147 . (/*overload*/mb_stripos(
148 $GLOBALS['cfg']['Server']['tracking_default_statements'],
149 'INSERT'
150 ) !== false ? ' checked="checked"' : '')
151 . ' /> INSERT<br/>';
152 $html .= '<input type="checkbox" name="update" value="true"'
153 . (/*overload*/mb_stripos(
154 $GLOBALS['cfg']['Server']['tracking_default_statements'],
155 'UPDATE'
156 ) !== false ? ' checked="checked"' : '')
157 . ' /> UPDATE<br/>';
158 $html .= '<input type="checkbox" name="delete" value="true"'
159 . (/*overload*/mb_stripos(
160 $GLOBALS['cfg']['Server']['tracking_default_statements'],
161 'DELETE'
162 ) !== false ? ' checked="checked"' : '')
163 . ' /> DELETE<br/>';
164 $html .= '<input type="checkbox" name="truncate" value="true"'
165 . (/*overload*/mb_stripos(
166 $GLOBALS['cfg']['Server']['tracking_default_statements'],
167 'TRUNCATE'
168 ) !== false ? ' checked="checked"' : '')
169 . ' /> TRUNCATE<br/>';
170 $html .= '</fieldset>';
172 $html .= '<fieldset class="tblFooters">';
173 $html .= '<input type="hidden" name="submit_create_version" value="1" />';
174 $html .= '<input type="submit" value="' . __('Create version') . '" />';
175 $html .= '</fieldset>';
177 $html .= '</form>';
178 $html .= '</div>';
180 return $html;
184 * Function to get html for activate/deactivate tracking
186 * @param string $action activate|deactivate
187 * @param string $url_query url query
188 * @param int $last_version last version
190 * @return string
192 function PMA_getHtmlForActivateDeactivateTracking(
193 $action, $url_query, $last_version
195 $html = '<div>';
196 $html .= '<form method="post" action="tbl_tracking.php' . $url_query . '">';
197 $html .= '<fieldset>';
198 $html .= '<legend>';
200 switch($action) {
201 case 'activate':
202 $legend = __('Activate tracking for %s');
203 $value = "activate_now";
204 $button = __('Activate now');
205 break;
206 case 'deactivate':
207 $legend = __('Deactivate tracking for %s');
208 $value = "deactivate_now";
209 $button = __('Deactivate now');
210 break;
211 default:
212 $legend = '';
213 $value = '';
214 $button = '';
217 $html .= sprintf(
218 $legend,
219 htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table'])
221 $html .= '</legend>';
222 $html .= '<input type="hidden" name="version" value="' . $last_version . '" />';
223 $html .= '<input type="hidden" name="toggle_activation" value="' . $value
224 . '" />';
225 $html .= '<input type="submit" value="' . $button . '" />';
226 $html .= '</fieldset>';
227 $html .= '</form>';
228 $html .= '</div>';
230 return $html;
234 * Function to get the list versions of the table
236 * @return array
238 function PMA_getListOfVersionsOfTable()
240 $cfgRelation = PMA_getRelationsParam();
241 $sql_query = " SELECT * FROM " .
242 PMA_Util::backquote($cfgRelation['db']) . "." .
243 PMA_Util::backquote($cfgRelation['tracking']) .
244 " WHERE db_name = '" . PMA_Util::sqlAddSlashes($_REQUEST['db']) . "' " .
245 " AND table_name = '" . PMA_Util::sqlAddSlashes($_REQUEST['table']) . "' " .
246 " ORDER BY version DESC ";
248 return PMA_queryAsControlUser($sql_query);
252 * Function to get html for displaying last version number
254 * @param array $sql_result sql result
255 * @param int $last_version last version
256 * @param array $url_params url parameters
257 * @param string $url_query url query
258 * @param string $pmaThemeImage path to theme's image folder
259 * @param string $text_dir text direction
261 * @return string
263 function PMA_getHtmlForTableVersionDetails(
264 $sql_result, $last_version, $url_params,
265 $url_query, $pmaThemeImage, $text_dir
267 $tracking_active = false;
269 $html = '<form method="post" action="tbl_tracking.php" name="versionsForm"'
270 . ' id="versionsForm" class="ajax">';
271 $html .= PMA_URL_getHiddenInputs($GLOBALS['db'], $GLOBALS['table']);
272 $html .= '<table id="versions" class="data">';
273 $html .= '<thead>';
274 $html .= '<tr>';
275 $html .= '<th></th>';
276 $html .= '<th>' . __('Version') . '</th>';
277 $html .= '<th>' . __('Created') . '</th>';
278 $html .= '<th>' . __('Updated') . '</th>';
279 $html .= '<th>' . __('Status') . '</th>';
280 $html .= '<th>' . __('Action') . '</th>';
281 $html .= '<th>' . __('Show') . '</th>';
282 $html .= '</tr>';
283 $html .= '</thead>';
284 $html .= '<tbody>';
286 $style = 'odd';
287 $GLOBALS['dbi']->dataSeek($sql_result, 0);
288 $delete = PMA_Util::getIcon('b_drop.png', __('Delete version'));
289 $report = PMA_Util::getIcon('b_report.png', __('Tracking report'));
290 $structure = PMA_Util::getIcon('b_props.png', __('Structure snapshot'));
292 while ($version = $GLOBALS['dbi']->fetchArray($sql_result)) {
293 if ($version['version'] == $last_version) {
294 if ($version['tracking_active'] == 1) {
295 $tracking_active = true;
296 } else {
297 $tracking_active = false;
300 $delete_link = 'tbl_tracking.php' . $url_query . '&amp;version='
301 . htmlspecialchars($version['version'])
302 . '&amp;submit_delete_version=true';
303 $checkbox_id = 'selected_versions_' . htmlspecialchars($version['version']);
305 $html .= '<tr class="' . $style . '">';
306 $html .= '<td class="center">';
307 $html .= '<input type="checkbox" name="selected_versions[]"'
308 . ' class="checkall" id="' . $checkbox_id . '"'
309 . ' value="' . htmlspecialchars($version['version']) . '"/>';
310 $html .= '</td>';
311 $html .= '<th class="floatright">';
312 $html .= '<label for="' . $checkbox_id . '">'
313 . htmlspecialchars($version['version']) . '</label>';
314 $html .= '</th>';
315 $html .= '<td>' . htmlspecialchars($version['date_created']) . '</td>';
316 $html .= '<td>' . htmlspecialchars($version['date_updated']) . '</td>';
317 $html .= '<td>' . PMA_getVersionStatus($version) . '</td>';
318 $html .= '<td><a class="delete_version_anchor ajax"'
319 . ' href="' . $delete_link . '" >' . $delete . '</a></td>';
320 $html .= '<td><a href="tbl_tracking.php';
321 $html .= PMA_URL_getCommon(
322 $url_params + array(
323 'report' => 'true', 'version' => $version['version']
326 $html .= '">' . $report . '</a>';
327 $html .= '&nbsp;&nbsp;';
328 $html .= '<a href="tbl_tracking.php';
329 $html .= PMA_URL_getCommon(
330 $url_params + array(
331 'snapshot' => 'true', 'version' => $version['version']
334 $html .= '">' . $structure . '</a>';
335 $html .= '</td>';
336 $html .= '</tr>';
338 if ($style == 'even') {
339 $style = 'odd';
340 } else {
341 $style = 'even';
345 $html .= '</tbody>';
346 $html .= '</table>';
348 $html .= PMA_Util::getWithSelected($pmaThemeImage, $text_dir, "versionsForm");
349 $html .= PMA_Util::getButtonOrImage(
350 'submit_mult', 'mult_submit', 'submit_mult_delete_version',
351 __('Delete version'), 'b_drop.png', 'delete_version'
354 $html .= '</form>';
356 if ($tracking_active) {
357 $html .= PMA_getHtmlForActivateDeactivateTracking(
358 'deactivate', $url_query, $last_version
360 } else {
361 $html .= PMA_getHtmlForActivateDeactivateTracking(
362 'activate', $url_query, $last_version
366 return $html;
370 * Function to get the last version number of a table
372 * @param array $sql_result sql result
374 * @return int
376 function PMA_getTableLastVersionNumber($sql_result)
378 $maxversion = $GLOBALS['dbi']->fetchArray($sql_result);
379 $last_version = $maxversion['version'];
381 return $last_version;
385 * Function to get sql results for selectable tables
387 * @return array
389 function PMA_getSQLResultForSelectableTables()
391 include_once 'libraries/relation.lib.php';
392 $cfgRelation = PMA_getRelationsParam();
394 $sql_query = " SELECT DISTINCT db_name, table_name FROM " .
395 PMA_Util::backquote($cfgRelation['db']) . "." .
396 PMA_Util::backquote($cfgRelation['tracking']) .
397 " WHERE db_name = '" . PMA_Util::sqlAddSlashes($GLOBALS['db']) . "' " .
398 " ORDER BY db_name, table_name";
400 return PMA_queryAsControlUser($sql_query);
404 * Function to get html for selectable table rows
406 * @param array $selectable_tables_sql_result sql results for selectable rows
407 * @param string $url_query url query
409 * @return string
411 function PMA_getHtmlForSelectableTables($selectable_tables_sql_result, $url_query)
413 $html = '<form method="post" action="tbl_tracking.php' . $url_query . '">';
414 $html .= '<select name="table" class="autosubmit">';
415 while ($entries = $GLOBALS['dbi']->fetchArray($selectable_tables_sql_result)) {
416 if (PMA_Tracker::isTracked($entries['db_name'], $entries['table_name'])) {
417 $status = ' (' . __('active') . ')';
418 } else {
419 $status = ' (' . __('not active') . ')';
421 if ($entries['table_name'] == $_REQUEST['table']) {
422 $s = ' selected="selected"';
423 } else {
424 $s = '';
426 $html .= '<option value="' . htmlspecialchars($entries['table_name'])
427 . '"' . $s . '>' . htmlspecialchars($entries['db_name']) . ' . '
428 . htmlspecialchars($entries['table_name']) . $status . '</option>'
429 . "\n";
431 $html .= '</select>';
432 $html .= '<input type="hidden" name="show_versions_submit" value="1" />';
433 $html .= '</form>';
435 return $html;
439 * Function to get html for tracking report and tracking report export
441 * @param string $url_query url query
442 * @param array $data data
443 * @param array $url_params url params
444 * @param boolean $selection_schema selection schema
445 * @param boolean $selection_data selection data
446 * @param boolean $selection_both selection both
447 * @param int $filter_ts_to filter time stamp from
448 * @param int $filter_ts_from filter time stamp tp
449 * @param array $filter_users filter users
451 * @return string
453 function PMA_getHtmlForTrackingReport($url_query, $data, $url_params,
454 $selection_schema, $selection_data, $selection_both, $filter_ts_to,
455 $filter_ts_from, $filter_users
457 $html = '<h3>' . __('Tracking report')
458 . ' [<a href="tbl_tracking.php' . $url_query . '">' . __('Close')
459 . '</a>]</h3>';
461 $html .= '<small>' . __('Tracking statements') . ' '
462 . htmlspecialchars($data['tracking']) . '</small><br/>';
463 $html .= '<br/>';
465 list($str1, $str2, $str3, $str4, $str5) = PMA_getHtmlForElementsOfTrackingReport(
466 $selection_schema, $selection_data, $selection_both
469 // Prepare delete link content here
470 $drop_image_or_text = '';
471 if (PMA_Util::showIcons('ActionLinksMode')) {
472 $drop_image_or_text .= PMA_Util::getImage(
473 'b_drop.png', __('Delete tracking data row from report')
476 if (PMA_Util::showText('ActionLinksMode')) {
477 $drop_image_or_text .= __('Delete');
481 * First, list tracked data definition statements
483 if (count($data['ddlog']) == 0 && count($data['dmlog']) == 0) {
484 $msg = PMA_Message::notice(__('No data'));
485 $msg->display();
488 $html .= PMA_getHtmlForTrackingReportExportForm1(
489 $data, $url_params, $selection_schema, $selection_data, $selection_both,
490 $filter_ts_to, $filter_ts_from, $filter_users, $str1, $str2, $str3,
491 $str4, $str5, $drop_image_or_text
494 $html .= PMA_getHtmlForTrackingReportExportForm2(
495 $url_params, $str1, $str2, $str3, $str4, $str5
498 $html .= "<br/><br/><hr/><br/>\n";
500 return $html;
504 * Generate HTML element for report form
506 * @param boolean $selection_schema selection schema
507 * @param boolean $selection_data selection data
508 * @param boolean $selection_both selection both
510 * @return array
512 function PMA_getHtmlForElementsOfTrackingReport(
513 $selection_schema, $selection_data, $selection_both
515 $str1 = '<select name="logtype">'
516 . '<option value="schema"'
517 . ($selection_schema ? ' selected="selected"' : '') . '>'
518 . __('Structure only') . '</option>'
519 . '<option value="data"'
520 . ($selection_data ? ' selected="selected"' : '') . '>'
521 . __('Data only') . '</option>'
522 . '<option value="schema_and_data"'
523 . ($selection_both ? ' selected="selected"' : '') . '>'
524 . __('Structure and data') . '</option>'
525 . '</select>';
526 $str2 = '<input type="text" name="date_from" value="'
527 . htmlspecialchars($_REQUEST['date_from']) . '" size="19" />';
528 $str3 = '<input type="text" name="date_to" value="'
529 . htmlspecialchars($_REQUEST['date_to']) . '" size="19" />';
530 $str4 = '<input type="text" name="users" value="'
531 . htmlspecialchars($_REQUEST['users']) . '" />';
532 $str5 = '<input type="hidden" name="list_report" value="1" />'
533 . '<input type="submit" value="' . __('Go') . '" />';
534 return array($str1, $str2, $str3, $str4, $str5);
538 * Generate HTML for export form
540 * @param array $data data
541 * @param array $url_params url params
542 * @param boolean $selection_schema selection schema
543 * @param boolean $selection_data selection data
544 * @param boolean $selection_both selection both
545 * @param int $filter_ts_to filter time stamp from
546 * @param int $filter_ts_from filter time stamp tp
547 * @param array $filter_users filter users
548 * @param string $str1 HTML for logtype select
549 * @param string $str2 HTML for "from date"
550 * @param string $str3 HTML for "to date"
551 * @param string $str4 HTML for user
552 * @param string $str5 HTML for "list report"
553 * @param string $drop_image_or_text HTML for image or text
555 * @return string HTML for form
557 function PMA_getHtmlForTrackingReportExportForm1(
558 $data, $url_params, $selection_schema, $selection_data, $selection_both,
559 $filter_ts_to, $filter_ts_from, $filter_users, $str1, $str2, $str3,
560 $str4, $str5, $drop_image_or_text
562 $ddlog_count = 0;
564 $html = '<form method="post" action="tbl_tracking.php'
565 . PMA_URL_getCommon(
566 $url_params + array(
567 'report' => 'true', 'version' => $_REQUEST['version']
570 . '">';
572 $html .= sprintf(
573 __('Show %1$s with dates from %2$s to %3$s by user %4$s %5$s'),
574 $str1, $str2, $str3, $str4, $str5
577 if ($selection_schema || $selection_both && count($data['ddlog']) > 0) {
578 list($temp, $ddlog_count) = PMA_getHtmlForDataDefinitionStatements(
579 $data, $filter_users, $filter_ts_from, $filter_ts_to, $url_params,
580 $drop_image_or_text
582 $html .= $temp;
583 unset($temp);
584 } //endif
587 * Secondly, list tracked data manipulation statements
589 if (($selection_data || $selection_both) && count($data['dmlog']) > 0) {
590 $html .= PMA_getHtmlForDataManipulationStatements(
591 $data, $filter_users, $filter_ts_from, $filter_ts_to, $url_params,
592 $ddlog_count, $drop_image_or_text
595 $html .= '</form>';
596 return $html;
600 * Generate HTML for export form
602 * @param array $url_params Parameters
603 * @param string $str1 HTML for logtype select
604 * @param string $str2 HTML for "from date"
605 * @param string $str3 HTML for "to date"
606 * @param string $str4 HTML for user
607 * @param string $str5 HTML for "list report"
609 * @return string HTML for form
611 function PMA_getHtmlForTrackingReportExportForm2(
612 $url_params, $str1, $str2, $str3, $str4, $str5
614 $html = '<form method="post" action="tbl_tracking.php'
615 . PMA_URL_getCommon(
616 $url_params + array(
617 'report' => 'true', 'version' => $_REQUEST['version']
620 . '">';
621 $html .= sprintf(
622 __('Show %1$s with dates from %2$s to %3$s by user %4$s %5$s'),
623 $str1, $str2, $str3, $str4, $str5
625 $html .= '</form>';
627 $html .= '<form class="disableAjax" method="post" action="tbl_tracking.php'
628 . PMA_URL_getCommon(
629 $url_params
630 + array('report' => 'true', 'version' => $_REQUEST['version'])
632 . '">';
633 $html .= '<input type="hidden" name="logtype" value="'
634 . htmlspecialchars($_REQUEST['logtype']) . '" />';
635 $html .= '<input type="hidden" name="date_from" value="'
636 . htmlspecialchars($_REQUEST['date_from']) . '" />';
637 $html .= '<input type="hidden" name="date_to" value="'
638 . htmlspecialchars($_REQUEST['date_to']) . '" />';
639 $html .= '<input type="hidden" name="users" value="'
640 . htmlspecialchars($_REQUEST['users']) . '" />';
642 $str_export1 = '<select name="export_type">'
643 . '<option value="sqldumpfile">' . __('SQL dump (file download)')
644 . '</option>'
645 . '<option value="sqldump">' . __('SQL dump') . '</option>'
646 . '<option value="execution" onclick="alert(\''
647 . PMA_escapeJsString(
648 __('This option will replace your table and contained data.')
650 . '\')">' . __('SQL execution') . '</option>' . '</select>';
652 $str_export2 = '<input type="hidden" name="report_export" value="1" />'
653 . '<input type="submit" value="' . __('Go') . '" />';
655 $html .= "<br/>" . sprintf(__('Export as %s'), $str_export1)
656 . $str_export2 . "<br/>";
657 $html .= '</form>';
658 return $html;
662 * Function to get html for data manipulation statements
664 * @param array $data data
665 * @param array $filter_users filter users
666 * @param int $filter_ts_from filter time staml from
667 * @param int $filter_ts_to filter time stamp to
668 * @param array $url_params url parameters
669 * @param int $ddlog_count data definition log count
670 * @param string $drop_image_or_text drop image or text
672 * @return string
674 function PMA_getHtmlForDataManipulationStatements($data, $filter_users,
675 $filter_ts_from, $filter_ts_to, $url_params, $ddlog_count,
676 $drop_image_or_text
678 // no need for the secondth returned parameter
679 list($html,) = PMA_getHtmlForDataStatements(
680 $data, $filter_users, $filter_ts_from, $filter_ts_to, $url_params,
681 $drop_image_or_text, 'dmlog', __('Data manipulation statement'),
682 $ddlog_count, 'dml_versions'
685 return $html;
689 * Function to get html for one data manipulation statement
691 * @param array $entry entry
692 * @param array $filter_users filter users
693 * @param int $filter_ts_from filter time stamp from
694 * @param int $filter_ts_to filter time stamp to
695 * @param string $style style
696 * @param int $line_number line number
697 * @param array $url_params url parameters
698 * @param int $offset line number offset
699 * @param string $drop_image_or_text drop image or text
700 * @param string $delete_param parameter for delete
702 * @return string
704 function PMA_getHtmlForOneStatement($entry, $filter_users,
705 $filter_ts_from, $filter_ts_to, $style, $line_number, $url_params, $offset,
706 $drop_image_or_text, $delete_param
708 $statement = PMA_Util::formatSql($entry['statement'], true);
709 $timestamp = strtotime($entry['date']);
710 $filtered_user = in_array($entry['username'], $filter_users);
711 $html = null;
713 if ($timestamp >= $filter_ts_from
714 && $timestamp <= $filter_ts_to
715 && (in_array('*', $filter_users) || $filtered_user)
717 $html = '<tr class="noclick ' . $style . '">';
718 $html .= '<td class="right"><small>' . $line_number . '</small></td>';
719 $html .= '<td><small>'
720 . htmlspecialchars($entry['date']) . '</small></td>';
721 $html .= '<td><small>'
722 . htmlspecialchars($entry['username']) . '</small></td>';
723 $html .= '<td>' . $statement . '</td>';
724 $html .= '<td class="nowrap"><a class="delete_entry_anchor ajax"'
725 . ' href="tbl_tracking.php'
726 . PMA_URL_getCommon(
727 $url_params + array(
728 'report' => 'true',
729 'version' => $_REQUEST['version'],
730 $delete_param => ($line_number - $offset),
733 . '">'
734 . $drop_image_or_text
735 . '</a></td>';
736 $html .= '</tr>';
739 return $html;
742 * Function to get html for data definition statements in schema snapshot
744 * @param array $data data
745 * @param array $filter_users filter users
746 * @param int $filter_ts_from filter time stamp from
747 * @param int $filter_ts_to filter time stamp to
748 * @param array $url_params url parameters
749 * @param string $drop_image_or_text drop image or text
751 * @return array
753 function PMA_getHtmlForDataDefinitionStatements($data, $filter_users,
754 $filter_ts_from, $filter_ts_to, $url_params, $drop_image_or_text
756 list($html, $line_number) = PMA_getHtmlForDataStatements(
757 $data, $filter_users, $filter_ts_from, $filter_ts_to, $url_params,
758 $drop_image_or_text, 'ddlog', __('Data definition statement'),
759 1, 'ddl_versions'
762 return array($html, $line_number);
766 * Function to get html for data statements in schema snapshot
768 * @param array $data data
769 * @param array $filter_users filter users
770 * @param int $filter_ts_from filter time stamp from
771 * @param int $filter_ts_to filter time stamp to
772 * @param array $url_params url parameters
773 * @param string $drop_image_or_text drop image or text
774 * @param string $which_log dmlog|ddlog
775 * @param string $header_message message for this section
776 * @param int $line_number line number
777 * @param string $table_id id for the table element
779 * @return array
781 function PMA_getHtmlForDataStatements($data, $filter_users,
782 $filter_ts_from, $filter_ts_to, $url_params, $drop_image_or_text,
783 $which_log, $header_message, $line_number, $table_id
785 $offset = $line_number;
786 $html = '<table id="' . $table_id . '" class="data" width="100%">';
787 $html .= '<thead>';
788 $html .= '<tr>';
789 $html .= '<th width="18">#</th>';
790 $html .= '<th width="100">' . __('Date') . '</th>';
791 $html .= '<th width="60">' . __('Username') . '</th>';
792 $html .= '<th>' . $header_message . '</th>';
793 $html .= '<th>' . __('Action') . '</th>';
794 $html .= '</tr>';
795 $html .= '</thead>';
796 $html .= '<tbody>';
798 $style = 'odd';
799 foreach ($data[$which_log] as $entry) {
800 $html .= PMA_getHtmlForOneStatement(
801 $entry, $filter_users, $filter_ts_from, $filter_ts_to, $style,
802 $line_number, $url_params, $offset, $drop_image_or_text,
803 'delete_' . $which_log
805 if ($style == 'even') {
806 $style = 'odd';
807 } else {
808 $style = 'even';
810 $line_number++;
812 $html .= '</tbody>';
813 $html .= '</table>';
815 return array($html, $line_number);
819 * Function to get html for schema snapshot
821 * @param string $url_query url query
823 * @return string
825 function PMA_getHtmlForSchemaSnapshot($url_query)
827 $html = '<h3>' . __('Structure snapshot')
828 . ' [<a href="tbl_tracking.php' . $url_query . '">' . __('Close')
829 . '</a>]</h3>';
830 $data = PMA_Tracker::getTrackedData(
831 $_REQUEST['db'], $_REQUEST['table'], $_REQUEST['version']
834 // Get first DROP TABLE/VIEW and CREATE TABLE/VIEW statements
835 $drop_create_statements = $data['ddlog'][0]['statement'];
837 if (/*overload*/mb_strstr($data['ddlog'][0]['statement'], 'DROP TABLE')
838 || /*overload*/mb_strstr($data['ddlog'][0]['statement'], 'DROP VIEW')
840 $drop_create_statements .= $data['ddlog'][1]['statement'];
842 // Print SQL code
843 $html .= PMA_Util::getMessage(
844 sprintf(
845 __('Version %s snapshot (SQL code)'),
846 htmlspecialchars($_REQUEST['version'])
848 $drop_create_statements
851 // Unserialize snapshot
852 $temp = unserialize($data['schema_snapshot']);
853 $columns = $temp['COLUMNS'];
854 $indexes = $temp['INDEXES'];
855 $html .= PMA_getHtmlForColumns($columns);
857 if (count($indexes) > 0) {
858 $html .= PMA_getHtmlForIndexes($indexes);
859 } // endif
860 $html .= '<br /><hr /><br />';
862 return $html;
866 * Function to get html for displaying columns in the schema snapshot
868 * @param array $columns columns
870 * @return string
872 function PMA_getHtmlForColumns($columns)
874 $html = '<h3>' . __('Structure') . '</h3>';
875 $html .= '<table id="tablestructure" class="data">';
876 $html .= '<thead>';
877 $html .= '<tr>';
878 $html .= '<th>' . __('#') . '</th>';
879 $html .= '<th>' . __('Column') . '</th>';
880 $html .= '<th>' . __('Type') . '</th>';
881 $html .= '<th>' . __('Collation') . '</th>';
882 $html .= '<th>' . __('Null') . '</th>';
883 $html .= '<th>' . __('Default') . '</th>';
884 $html .= '<th>' . __('Extra') . '</th>';
885 $html .= '<th>' . __('Comment') . '</th>';
886 $html .= '</tr>';
887 $html .= '</thead>';
888 $html .= '<tbody>';
889 $style = 'odd';
890 $index = 1;
891 foreach ($columns as $field) {
892 $html .= PMA_getHtmlForField($index++, $field, $style);
893 if ($style == 'even') {
894 $style = 'odd';
895 } else {
896 $style = 'even';
900 $html .= '</tbody>';
901 $html .= '</table>';
903 return $html;
907 * Function to get html for field
909 * @param int $index index
910 * @param array $field field
911 * @param string $style style
913 * @return string
915 function PMA_getHtmlForField($index, $field, $style)
917 $html = '<tr class="noclick ' . $style . '">';
918 $html .= '<td>' . $index . '</td>';
919 $html .= '<td><b>' . htmlspecialchars($field['Field']);
920 if ($field['Key'] == 'PRI') {
921 $html .= ' ' . PMA_Util::getImage(
922 'b_primary.png', __('Primary')
924 } elseif (! empty($field['Key'])) {
925 $html .= ' ' . PMA_Util::getImage(
926 'bd_primary.png', __('Index')
929 $html .= '</b></td>';
930 $html .= "\n";
931 $html .= '<td>' . htmlspecialchars($field['Type']) . '</td>';
932 $html .= '<td>' . htmlspecialchars($field['Collation']) . '</td>';
933 $html .= '<td>' . (($field['Null'] == 'YES') ? __('Yes') : __('No')) . '</td>';
934 $html .= '<td>';
935 if (isset($field['Default'])) {
936 $extracted_columnspec = PMA_Util::extractColumnSpec($field['Type']);
937 if ($extracted_columnspec['type'] == 'bit') {
938 // here, $field['Default'] contains something like b'010'
939 $html .= PMA_Util::convertBitDefaultValue($field['Default']);
940 } else {
941 $html .= htmlspecialchars($field['Default']);
943 } else {
944 if ($field['Null'] == 'YES') {
945 $html .= '<i>NULL</i>';
946 } else {
947 $html .= '<i>' . _pgettext('None for default', 'None') . '</i>';
950 $html .= '</td>';
951 $html .= '<td>' . htmlspecialchars($field['Extra']) . '</td>';
952 $html .= '<td>' . htmlspecialchars($field['Comment']) . '</td>';
953 $html .= '</tr>';
955 return $html;
959 * Function to get html for the indexes in schema snapshot
961 * @param array $indexes indexes
963 * @return string
965 function PMA_getHtmlForIndexes($indexes)
967 $html = '<h3>' . __('Indexes') . '</h3>';
968 $html .= '<table id="tablestructure_indexes" class="data">';
969 $html .= '<thead>';
970 $html .= '<tr>';
971 $html .= '<th>' . __('Keyname') . '</th>';
972 $html .= '<th>' . __('Type') . '</th>';
973 $html .= '<th>' . __('Unique') . '</th>';
974 $html .= '<th>' . __('Packed') . '</th>';
975 $html .= '<th>' . __('Column') . '</th>';
976 $html .= '<th>' . __('Cardinality') . '</th>';
977 $html .= '<th>' . __('Collation') . '</th>';
978 $html .= '<th>' . __('Null') . '</th>';
979 $html .= '<th>' . __('Comment') . '</th>';
980 $html .= '</tr>';
981 $html .= '<tbody>';
983 $style = 'odd';
984 foreach ($indexes as $index) {
985 $html .= PMA_getHtmlForIndex($index, $style);
986 if ($style == 'even') {
987 $style = 'odd';
988 } else {
989 $style = 'even';
992 $html .= '</tbody>';
993 $html .= '</table>';
994 return $html;
998 * Function to get html for an index in schema snapshot
1000 * @param array $index index
1001 * @param string $style style
1003 * @return string
1005 function PMA_getHtmlForIndex($index, $style)
1007 if ($index['Non_unique'] == 0) {
1008 $str_unique = __('Yes');
1009 } else {
1010 $str_unique = __('No');
1012 if ($index['Packed'] != '') {
1013 $str_packed = __('Yes');
1014 } else {
1015 $str_packed = __('No');
1018 $html = '<tr class="noclick ' . $style . '">';
1019 $html .= '<td><b>' . htmlspecialchars($index['Key_name']) . '</b></td>';
1020 $html .= '<td>' . htmlspecialchars($index['Index_type']) . '</td>';
1021 $html .= '<td>' . $str_unique . '</td>';
1022 $html .= '<td>' . $str_packed . '</td>';
1023 $html .= '<td>' . htmlspecialchars($index['Column_name']) . '</td>';
1024 $html .= '<td>' . htmlspecialchars($index['Cardinality']) . '</td>';
1025 $html .= '<td>' . htmlspecialchars($index['Collation']) . '</td>';
1026 $html .= '<td>' . htmlspecialchars($index['Null']) . '</td>';
1027 $html .= '<td>' . htmlspecialchars($index['Comment']) . '</td>';
1028 $html .= '</tr>';
1030 return $html;
1034 * Function to handle the tracking report
1036 * @param array &$data tracked data
1038 * @return string HTML for the message
1040 function PMA_deleteTrackingReportRows(&$data)
1042 $html = '';
1043 if (isset($_REQUEST['delete_ddlog'])) {
1044 // Delete ddlog row data
1045 $html .= PMA_deleteFromTrackingReportLog(
1046 $data,
1047 'ddlog',
1048 'DDL',
1049 __('Tracking data definition successfully deleted')
1053 if (isset($_REQUEST['delete_dmlog'])) {
1054 // Delete dmlog row data
1055 $html .= PMA_deleteFromTrackingReportLog(
1056 $data,
1057 'dmlog',
1058 'DML',
1059 __('Tracking data manipulation successfully deleted')
1062 return $html;
1066 * Function to delete from a tracking report log
1068 * @param array &$data tracked data
1069 * @param string $which_log ddlog|dmlog
1070 * @param string $type DDL|DML
1071 * @param string $message success message
1073 * @return string HTML for the message
1075 function PMA_deleteFromTrackingReportLog(&$data, $which_log, $type, $message)
1077 $html = '';
1078 $delete_id = $_REQUEST['delete_' . $which_log];
1080 // Only in case of valid id
1081 if ($delete_id == (int)$delete_id) {
1082 unset($data[$which_log][$delete_id]);
1084 $successfullyDeleted = PMA_Tracker::changeTrackingData(
1085 $_REQUEST['db'],
1086 $_REQUEST['table'],
1087 $_REQUEST['version'],
1088 $type,
1089 $data[$which_log]
1091 if ($successfullyDeleted) {
1092 $msg = PMA_Message::success($message);
1093 } else {
1094 $msg = PMA_Message::rawError(__('Query error'));
1096 $html .= $msg->getDisplay();
1098 return $html;
1102 * Function to export as sql dump
1104 * @param array $entries entries
1106 * @return string HTML SQL query form
1108 function PMA_exportAsSQLDump($entries)
1110 $html = '';
1111 $new_query = "# "
1112 . __(
1113 'You can execute the dump by creating and using a temporary database. '
1114 . 'Please ensure that you have the privileges to do so.'
1116 . "\n"
1117 . "# " . __('Comment out these two lines if you do not need them.') . "\n"
1118 . "\n"
1119 . "CREATE database IF NOT EXISTS pma_temp_db; \n"
1120 . "USE pma_temp_db; \n"
1121 . "\n";
1123 foreach ($entries as $entry) {
1124 $new_query .= $entry['statement'];
1126 $msg = PMA_Message::success(
1127 __('SQL statements exported. Please copy the dump or execute it.')
1129 $html .= $msg->getDisplay();
1131 $db_temp = $GLOBALS['db'];
1132 $table_temp = $GLOBALS['table'];
1134 $GLOBALS['db'] = $GLOBALS['table'] = '';
1135 include_once './libraries/sql_query_form.lib.php';
1137 $html .= PMA_getHtmlForSqlQueryForm($new_query, 'sql');
1139 $GLOBALS['db'] = $db_temp;
1140 $GLOBALS['table'] = $table_temp;
1142 return $html;
1146 * Function to export as sql execution
1148 * @param array $entries entries
1150 * @return array
1152 function PMA_exportAsSQLExecution($entries)
1154 $sql_result = array();
1155 foreach ($entries as $entry) {
1156 $sql_result = $GLOBALS['dbi']->query("/*NOTRACK*/\n" . $entry['statement']);
1159 return $sql_result;
1163 * Function to export as entries
1165 * @param array $entries entries
1167 * @return void
1169 function PMA_exportAsFileDownload($entries)
1171 @ini_set('url_rewriter.tags', '');
1173 $dump = "# " . sprintf(
1174 __('Tracking report for table `%s`'), htmlspecialchars($_REQUEST['table'])
1176 . "\n" . "# " . date('Y-m-d H:i:s') . "\n";
1177 foreach ($entries as $entry) {
1178 $dump .= $entry['statement'];
1180 $filename = 'log_' . htmlspecialchars($_REQUEST['table']) . '.sql';
1181 PMA_Response::getInstance()->disable();
1182 PMA_downloadHeader(
1183 $filename,
1184 'text/x-sql',
1185 /*overload*/mb_strlen($dump)
1187 echo $dump;
1189 exit();
1193 * Function to activate tracking
1195 * @return string HTML for the success message
1197 function PMA_activateTracking()
1199 $html = '';
1200 $activated = PMA_Tracker::activateTracking(
1201 $GLOBALS['db'], $GLOBALS['table'], $_REQUEST['version']
1203 if ($activated) {
1204 $msg = PMA_Message::success(
1205 sprintf(
1206 __('Tracking for %1$s was activated at version %2$s.'),
1207 htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']),
1208 htmlspecialchars($_REQUEST['version'])
1211 $html .= $msg->getDisplay();
1214 return $html;
1218 * Function to deactivate tracking
1220 * @return string HTML of the success message
1222 function PMA_deactivateTracking()
1224 $html = '';
1225 $deactivated = PMA_Tracker::deactivateTracking(
1226 $GLOBALS['db'], $GLOBALS['table'], $_REQUEST['version']
1228 if ($deactivated) {
1229 $msg = PMA_Message::success(
1230 sprintf(
1231 __('Tracking for %1$s was deactivated at version %2$s.'),
1232 htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']),
1233 htmlspecialchars($_REQUEST['version'])
1236 $html .= $msg->getDisplay();
1239 return $html;
1243 * Function to get tracking set
1245 * @return string
1247 function PMA_getTrackingSet()
1249 $tracking_set = '';
1251 // a key is absent from the request if it has been removed from
1252 // tracking_default_statements in the config
1253 if (isset($_REQUEST['alter_table']) && $_REQUEST['alter_table'] == true) {
1254 $tracking_set .= 'ALTER TABLE,';
1256 if (isset($_REQUEST['rename_table']) && $_REQUEST['rename_table'] == true) {
1257 $tracking_set .= 'RENAME TABLE,';
1259 if (isset($_REQUEST['create_table']) && $_REQUEST['create_table'] == true) {
1260 $tracking_set .= 'CREATE TABLE,';
1262 if (isset($_REQUEST['drop_table']) && $_REQUEST['drop_table'] == true) {
1263 $tracking_set .= 'DROP TABLE,';
1265 if (isset($_REQUEST['alter_view']) && $_REQUEST['alter_view'] == true) {
1266 $tracking_set .= 'ALTER VIEW,';
1268 if (isset($_REQUEST['create_view']) && $_REQUEST['create_view'] == true) {
1269 $tracking_set .= 'CREATE VIEW,';
1271 if (isset($_REQUEST['drop_view']) && $_REQUEST['drop_view'] == true) {
1272 $tracking_set .= 'DROP VIEW,';
1274 if (isset($_REQUEST['create_index']) && $_REQUEST['create_index'] == true) {
1275 $tracking_set .= 'CREATE INDEX,';
1277 if (isset($_REQUEST['drop_index']) && $_REQUEST['drop_index'] == true) {
1278 $tracking_set .= 'DROP INDEX,';
1280 if (isset($_REQUEST['insert']) && $_REQUEST['insert'] == true) {
1281 $tracking_set .= 'INSERT,';
1283 if (isset($_REQUEST['update']) && $_REQUEST['update'] == true) {
1284 $tracking_set .= 'UPDATE,';
1286 if (isset($_REQUEST['delete']) && $_REQUEST['delete'] == true) {
1287 $tracking_set .= 'DELETE,';
1289 if (isset($_REQUEST['truncate']) && $_REQUEST['truncate'] == true) {
1290 $tracking_set .= 'TRUNCATE,';
1292 $tracking_set = rtrim($tracking_set, ',');
1294 return $tracking_set;
1298 * Deletes a tracking version
1300 * @param string $version tracking version
1302 * @return string HTML of the success message
1304 function PMA_deleteTrackingVersion($version)
1306 $html = '';
1307 $versionDeleted = PMA_Tracker::deleteTracking(
1308 $GLOBALS['db'],
1309 $GLOBALS['table'],
1310 $version
1312 if ($versionDeleted) {
1313 $msg = PMA_Message::success(
1314 sprintf(
1315 __('Version %1$s of %2$s was deleted.'),
1316 htmlspecialchars($version),
1317 htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table'])
1320 $html .= $msg->getDisplay();
1323 return $html;
1327 * Function to create the tracking version
1329 * @return string HTML of the success message
1331 function PMA_createTrackingVersion()
1333 $html = '';
1334 $tracking_set = PMA_getTrackingSet();
1336 $versionCreated = PMA_Tracker::createVersion(
1337 $GLOBALS['db'],
1338 $GLOBALS['table'],
1339 $_REQUEST['version'],
1340 $tracking_set,
1341 $GLOBALS['dbi']->getTable($GLOBALS['db'], $GLOBALS['table'])->isView()
1343 if ($versionCreated) {
1344 $msg = PMA_Message::success(
1345 sprintf(
1346 __('Version %1$s was created, tracking for %2$s is active.'),
1347 htmlspecialchars($_REQUEST['version']),
1348 htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table'])
1351 $html .= $msg->getDisplay();
1354 return $html;
1358 * Create tracking version for multiple tables
1360 * @param array $selected list of selected tables
1362 * @return void
1364 function PMA_createTrackingForMultipleTables($selected)
1366 $tracking_set = PMA_getTrackingSet();
1368 foreach ($selected as $selected_table) {
1369 PMA_Tracker::createVersion(
1370 $GLOBALS['db'],
1371 $selected_table,
1372 $_REQUEST['version'],
1373 $tracking_set,
1374 $GLOBALS['dbi']->getTable($GLOBALS['db'], $selected_table)->isView()
1380 * Function to get the entries
1382 * @param array $data data
1383 * @param int $filter_ts_from filter time stamp from
1384 * @param int $filter_ts_to filter time stamp to
1385 * @param array $filter_users filter users
1387 * @return array
1389 function PMA_getEntries($data, $filter_ts_from, $filter_ts_to, $filter_users)
1391 $entries = array();
1392 // Filtering data definition statements
1393 if ($_REQUEST['logtype'] == 'schema'
1394 || $_REQUEST['logtype'] == 'schema_and_data'
1396 $entries = array_merge(
1397 $entries,
1398 PMA_filterTracking(
1399 $data['ddlog'], $filter_ts_from, $filter_ts_to, $filter_users
1404 // Filtering data manipulation statements
1405 if ($_REQUEST['logtype'] == 'data'
1406 || $_REQUEST['logtype'] == 'schema_and_data'
1408 $entries = array_merge(
1409 $entries,
1410 PMA_filterTracking(
1411 $data['dmlog'], $filter_ts_from, $filter_ts_to, $filter_users
1416 // Sort it
1417 $ids = $timestamps = $usernames = $statements = array();
1418 foreach ($entries as $key => $row) {
1419 $ids[$key] = $row['id'];
1420 $timestamps[$key] = $row['timestamp'];
1421 $usernames[$key] = $row['username'];
1422 $statements[$key] = $row['statement'];
1425 array_multisort(
1426 $timestamps, SORT_ASC, $ids, SORT_ASC, $usernames,
1427 SORT_ASC, $statements, SORT_ASC, $entries
1430 return $entries;
1434 * Function to get version status
1436 * @param array $version version info
1438 * @return string $version_status The status message
1440 function PMA_getVersionStatus($version)
1442 if ($version['tracking_active'] == 1) {
1443 return __('active');
1444 } else {
1445 return __('not active');
1450 * Display untracked tables
1452 * @param string $db current database
1453 * @param array $untracked_tables untracked tables
1454 * @param string $url_query url query string
1455 * @param string $pmaThemeImage path to theme's image folder
1456 * @param string $text_dir text direction
1458 * @return void
1460 function PMA_displayUntrackedTables(
1461 $db, $untracked_tables, $url_query, $pmaThemeImage, $text_dir
1464 <h3><?php echo __('Untracked tables');?></h3>
1465 <form method="post" action="db_tracking.php" name="untrackedForm"
1466 id="untrackedForm" class="ajax">
1467 <?php
1468 echo PMA_URL_getHiddenInputs($db)
1470 <table id="noversions" class="data">
1471 <thead>
1472 <tr>
1473 <th></th>
1474 <th style="width: 300px"><?php echo __('Table');?></th>
1475 <th><?php echo __('Action');?></th>
1476 </tr>
1477 </thead>
1478 <tbody>
1479 <?php
1481 // Print out list of untracked tables
1482 $style = 'odd';
1483 foreach ($untracked_tables as $key => $tablename) {
1484 $style = PMA_displayOneUntrackedTable($db, $tablename, $url_query, $style);
1487 </tbody>
1488 </table>
1489 <?php
1490 echo PMA_Util::getWithSelected($pmaThemeImage, $text_dir, "untrackedForm");
1491 echo PMA_Util::getButtonOrImage(
1492 'submit_mult', 'mult_submit', 'submit_mult_track',
1493 __('Track table'), 'eye.png', 'track'
1496 </form>
1497 <?php
1501 * Display one untracked table
1503 * @param string $db current database
1504 * @param string $tablename the table name for which to display a line
1505 * @param string $url_query url query string
1506 * @param string $style odd|even
1508 * @return string $style changed style (even|odd)
1510 function PMA_displayOneUntrackedTable($db, $tablename, $url_query, $style)
1512 $checkbox_id = "selected_tbl_"
1513 . htmlspecialchars($tablename);
1514 if (PMA_Tracker::getVersion($db, $tablename) == -1) {
1515 $my_link = '<a href="tbl_tracking.php' . $url_query
1516 . '&amp;table=' . htmlspecialchars($tablename) . '">';
1517 $my_link .= PMA_Util::getIcon('eye.png', __('Track table'));
1518 $my_link .= '</a>';
1520 <tr class="<?php echo $style;?>">
1521 <td class="center">
1522 <input type="checkbox" name="selected_tbl[]"
1523 class="checkall" id="<?php echo $checkbox_id;?>"
1524 value="<?php echo htmlspecialchars($tablename);?>"/>
1525 </td>
1526 <th>
1527 <label for="<?php echo $checkbox_id;?>">
1528 <?php echo htmlspecialchars($tablename);?>
1529 </label>
1530 </th>
1531 <td><?php echo $my_link;?></td>
1532 </tr>
1533 <?php
1534 if ($style == 'even') {
1535 $style = 'odd';
1536 } else {
1537 $style = 'even';
1540 return $style;
1544 * Get untracked tables
1546 * @param string $db current database
1548 * @return array $untracked_tables
1550 function PMA_getUntrackedTables($db)
1552 $untracked_tables = array();
1553 $sep = $GLOBALS['cfg']['NavigationTreeTableSeparator'];
1555 // Get list of tables
1556 $table_list = PMA_Util::getTableList($db);
1558 // For each table try to get the tracking version
1559 foreach ($table_list as $key => $value) {
1560 // If $value is a table group.
1561 if (array_key_exists(('is' . $sep . 'group'), $value)
1562 && $value['is' . $sep . 'group']
1564 foreach ($value as $temp_table) {
1565 // If $temp_table is a table with the value for 'Name' is set,
1566 // rather than a property of the table group.
1567 if (is_array($temp_table)
1568 && array_key_exists('Name', $temp_table)
1570 $tracking_version = PMA_Tracker::getVersion(
1571 $db,
1572 $temp_table['Name']
1574 if ($tracking_version == -1) {
1575 $untracked_tables[] = $temp_table['Name'];
1579 } else { // If $value is a table.
1580 if (PMA_Tracker::getVersion($db, $value['Name']) == -1) {
1581 $untracked_tables[] = $value['Name'];
1585 return $untracked_tables;
1589 * Display tracked tables
1591 * @param string $db current database
1592 * @param object $all_tables_result result set of tracked tables
1593 * @param string $url_query url query string
1594 * @param string $pmaThemeImage path to theme's image folder
1595 * @param string $text_dir text direction
1596 * @param array $cfgRelation configuration storage info
1598 * @return void
1600 function PMA_displayTrackedTables(
1601 $db, $all_tables_result, $url_query, $pmaThemeImage, $text_dir, $cfgRelation
1604 <div id="tracked_tables">
1605 <h3><?php echo __('Tracked tables');?></h3>
1607 <form method="post" action="db_tracking.php" name="trackedForm"
1608 id="trackedForm" class="ajax">
1609 <?php
1610 echo PMA_URL_getHiddenInputs($db)
1612 <table id="versions" class="data">
1613 <thead>
1614 <tr>
1615 <th></th>
1616 <th><?php echo __('Table');?></th>
1617 <th><?php echo __('Last version');?></th>
1618 <th><?php echo __('Created');?></th>
1619 <th><?php echo __('Updated');?></th>
1620 <th><?php echo __('Status');?></th>
1621 <th><?php echo __('Action');?></th>
1622 <th><?php echo __('Show');?></th>
1623 </tr>
1624 </thead>
1625 <tbody>
1626 <?php
1628 // Print out information about versions
1630 $delete = PMA_Util::getIcon('b_drop.png', __('Delete tracking'));
1631 $versions = PMA_Util::getIcon('b_versions.png', __('Versions'));
1632 $report = PMA_Util::getIcon('b_report.png', __('Tracking report'));
1633 $structure = PMA_Util::getIcon('b_props.png', __('Structure snapshot'));
1635 $style = 'odd';
1636 while ($one_result = $GLOBALS['dbi']->fetchArray($all_tables_result)) {
1637 list($table_name, $version_number) = $one_result;
1638 $table_query = ' SELECT * FROM ' .
1639 PMA_Util::backquote($cfgRelation['db']) . '.' .
1640 PMA_Util::backquote($cfgRelation['tracking']) .
1641 ' WHERE `db_name` = \'' . PMA_Util::sqlAddSlashes($_REQUEST['db'])
1642 . '\' AND `table_name` = \'' . PMA_Util::sqlAddSlashes($table_name)
1643 . '\' AND `version` = \'' . $version_number . '\'';
1645 $table_result = PMA_queryAsControlUser($table_query);
1646 $version_data = $GLOBALS['dbi']->fetchArray($table_result);
1648 $tbl_link = 'tbl_tracking.php' . $url_query . '&amp;table='
1649 . htmlspecialchars($version_data['table_name']);
1650 $delete_link = 'db_tracking.php' . $url_query . '&amp;table='
1651 . htmlspecialchars($version_data['table_name'])
1652 . '&amp;delete_tracking=true&amp';
1653 $checkbox_id = "selected_tbl_"
1654 . htmlspecialchars($version_data['table_name']);
1656 <tr class="<?php echo $style;?>">
1657 <td class="center">
1658 <input type="checkbox" name="selected_tbl[]"
1659 class="checkall" id="<?php echo $checkbox_id;?>"
1660 value="<?php echo htmlspecialchars($version_data['table_name']);?>"/>
1661 </td>
1662 <th>
1663 <label for="<?php echo $checkbox_id;?>">
1664 <?php echo htmlspecialchars($version_data['table_name']);?>
1665 </label>
1666 </th>
1667 <td class="right"><?php echo $version_data['version'];?></td>
1668 <td><?php echo $version_data['date_created'];?></td>
1669 <td><?php echo $version_data['date_updated'];?></td>
1670 <td>
1671 <?php
1672 PMA_displayStatusButton($version_data, $tbl_link);
1674 </td>
1675 <td>
1676 <a class="delete_tracking_anchor ajax"
1677 href="<?php echo $delete_link;?>" >
1678 <?php echo $delete; ?></a>
1679 <?php
1680 echo '</td>'
1681 . '<td>'
1682 . '<a href="' . $tbl_link . '">' . $versions . '</a>'
1683 . '&nbsp;&nbsp;'
1684 . '<a href="' . $tbl_link . '&amp;report=true&amp;version='
1685 . $version_data['version'] . '">' . $report . '</a>'
1686 . '&nbsp;&nbsp;'
1687 . '<a href="' . $tbl_link . '&amp;snapshot=true&amp;version='
1688 . $version_data['version'] . '">' . $structure . '</a>'
1689 . '</td>'
1690 . '</tr>';
1691 if ($style == 'even') {
1692 $style = 'odd';
1693 } else {
1694 $style = 'even';
1698 </tbody>
1699 </table>
1700 <?php
1701 echo PMA_Util::getWithSelected($pmaThemeImage, $text_dir, "trackedForm");
1702 echo PMA_Util::getButtonOrImage(
1703 'submit_mult', 'mult_submit', 'submit_mult_delete_tracking',
1704 __('Delete tracking'), 'b_drop.png', 'delete_tracking'
1707 </form>
1708 </div>
1709 <?php
1713 * Display tracking status button
1715 * @param array $version_data data about tracking versions
1716 * @param string $tbl_link link for tbl_tracking.php
1718 * @return void
1720 function PMA_displayStatusButton($version_data, $tbl_link)
1722 $state = PMA_getVersionStatus($version_data);
1723 $options = array(
1724 0 => array(
1725 'label' => __('not active'),
1726 'value' => 'deactivate_now',
1727 'selected' => ($state != 'active')
1729 1 => array(
1730 'label' => __('active'),
1731 'value' => 'activate_now',
1732 'selected' => ($state == 'active')
1735 echo PMA_Util::toggleButton(
1736 $tbl_link . '&amp;version=' . $version_data['version'],
1737 'toggle_activation',
1738 $options,
1739 null