diff --git a/libraries/tbl_tracking.lib.php b/libraries/tbl_tracking.lib.php new file mode 100644 index 0000000000..fa3e550cb2 --- /dev/null +++ b/libraries/tbl_tracking.lib.php @@ -0,0 +1,1206 @@ += $filter_ts_from + && $timestamp <= $filter_ts_to + && (in_array('*', $filter_users) || $filtered_user) + ) { + $tmp_entries[] = array( + 'id' => $id, + 'timestamp' => $timestamp, + 'username' => $entry['username'], + 'statement' => $entry['statement'] + ); + } + $id++; + } + return($tmp_entries); +} + +/** + * Function to get html for data definition and data manipulation statements + * + * @param string $url_query url query + * @param int $last_version last version + * + * @return string + */ +function PMA_getHtmlForDataDefinitionAndManipulationStatements($url_query, + $last_version +) { + $html = '
'; + $html .= '
'; + $html .= PMA_URL_getHiddenInputs($GLOBALS['db'], $GLOBALS['table']); + $html .= '
'; + $html .= ''; + $html .= sprintf( + __('Create version %1$s of %2$s'), + ($last_version + 1), + htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']) + ); + $html .= ''; + $html .= ''; + $html .= '

' . __('Track these data definition statements:') + . '

'; + $html .= ' ALTER TABLE
'; + $html .= ' RENAME TABLE
'; + $html .= ' CREATE TABLE
'; + $html .= ' DROP TABLE
'; + $html .= '
'; + $html .= ' CREATE INDEX
'; + $html .= ' DROP INDEX
'; + $html .= '

' . __('Track these data manipulation statements:') . '

'; + $html .= ' INSERT
'; + $html .= ' UPDATE
'; + $html .= ' DELETE
'; + $html .= ' TRUNCATE
'; + $html .= '
'; + + $html .= '
'; + $html .= ''; + $html .= ''; + $html .= '
'; + + $html .= '
'; + $html .= '
'; + + return $html; +} + +/** + * Function to get html for activate tracking + * + * @param string $url_query url query + * @param int $last_version last version + * + * @return string + */ +function PMA_getHtmlForActivateTracking($url_query, $last_version) +{ + $html = '
'; + $html .= '
'; + $html .= '
'; + $html .= ''; + $html .= sprintf( + __('Activate tracking for %s'), + htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']) + ); + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= '
'; + $html .= '
'; + $html .= '
'; + + return $html; +} + +/** + * Function to get html for deactivating tracking + * + * @param string $url_query url query + * @param int $last_version last version + * + * @return string + */ +function PMA_getHtmlForDeactivateTracking($url_query, $last_version) +{ + $html = '
'; + $html .= '
'; + $html .= '
'; + $html .= ''; + $html .= sprintf( + __('Deactivate tracking for %s'), + htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']) + ); + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= '
'; + $html .= '
'; + $html .= '
'; + + return $html; +} + +/** + * Function to get the list versions of the table + * + * @return array + */ +function PMA_getListOfVersionsOfTable() +{ + $sql_query = " SELECT * FROM " . + PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "." . + PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) . + " WHERE db_name = '" . PMA_Util::sqlAddSlashes($_REQUEST['db']) . "' ". + " AND table_name = '" . PMA_Util::sqlAddSlashes($_REQUEST['table']) ."' ". + " ORDER BY version DESC "; + + return PMA_queryAsControlUser($sql_query); +} + +/** + * Function to get html for displaying last version number + * + * @param array $sql_result sql result + * @param int $last_version last version + * @param array $url_params url parameters + * @param string $url_query url query + * + * @return string + */ +function PMA_getHtmlForTableVersionDetails($sql_result, $last_version, $url_params, + $url_query +) { + $html = ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + + $style = 'odd'; + $GLOBALS['dbi']->dataSeek($sql_result, 0); + while ($version = $GLOBALS['dbi']->fetchArray($sql_result)) { + if ($version['tracking_active'] == 1) { + $version_status = __('active'); + } else { + $version_status = __('not active'); + } + if ($version['version'] == $last_version) { + if ($version['tracking_active'] == 1) { + $tracking_active = true; + } else { + $tracking_active = false; + } + } + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + + if ($style == 'even') { + $style = 'odd'; + } else { + $style = 'even'; + } + } + + $html .= ''; + $html .= '
' . __('Database') . '' . __('Table') . '' . __('Version') . '' . __('Created') . '' . __('Updated') . '' . __('Status') . '' . __('Show') . '
' . htmlspecialchars($version['db_name']) . '' . htmlspecialchars($version['table_name']) . '' . htmlspecialchars($version['version']) . '' . htmlspecialchars($version['date_created']) . '' . htmlspecialchars($version['date_updated']) . '' . $version_status . '' . __('Tracking report') . ''; + $html .= '| ' . __('Structure snapshot') . ''; + $html .= '
'; + + if ($tracking_active) { + $html .= PMA_getHtmlForDeactivateTracking($url_query, $last_version); + } else { + $html .= PMA_getHtmlForActivateTracking($url_query, $last_version); + } + + return $html; +} + +/** + * Function to get the last version number of a table + * + * @param array $sql_result sql result + * + * @return int + */ +function PMA_getTableLastVersionNumber($sql_result) +{ + $maxversion = $GLOBALS['dbi']->fetchArray($sql_result); + $last_version = $maxversion['version']; + + return $last_version; +} + +/** + * Function to get sql results for selectable tables + * + * @return array + */ +function PMA_getSQLResultForSelectableTables() +{ + include_once 'libraries/relation.lib.php'; + + $sql_query = " SELECT DISTINCT db_name, table_name FROM " . + PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "." . + PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) . + " WHERE db_name = '" . PMA_Util::sqlAddSlashes($GLOBALS['db']) . "' " . + " ORDER BY db_name, table_name"; + + return PMA_queryAsControlUser($sql_query); +} + +/** + * Function to get html for selectable table rows + * + * @param array $selectable_tables_sql_result sql results for selectable rows + * @param string $url_query url query + * + * @return string + */ +function PMA_getHtmlForSelectableTables($selectable_tables_sql_result, $url_query) +{ + $html = '
'; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= '
'; + + return $html; +} + +/** + * Function to get html for tracking report and tracking report export + * + * @param string $url_query url query + * @param array $data data + * @param array $url_params url params + * @param array $selection_schema selection schema + * @param array $selection_data selection data + * @param bool $selection_both selection both + * @param int $filter_ts_to filter time stamp from + * @param int $filter_ts_from filter time stamp tp + * @param array $filter_users filter users + * + * @return string + */ +function PMA_getHtmlForTrackingReport($url_query, $data, $url_params, + $selection_schema, $selection_data, $selection_both, $filter_ts_to, + $filter_ts_from, $filter_users +) { + $html = '

' . __('Tracking report') + . ' [' . __('Close') + . ']

'; + + $html .= '' . __('Tracking statements') . ' ' + . htmlspecialchars($data['tracking']) . '
'; + $html .= '
'; + + $html .= '
'; + + $str1 = ''; + $str2 = ''; + $str3 = ''; + $str4 = ''; + $str5 = '' + . ''; + + $html .= sprintf( + __('Show %1$s with dates from %2$s to %3$s by user %4$s %5$s'), + $str1, $str2, $str3, $str4, $str5 + ); + + // Prepare delete link content here + $drop_image_or_text = ''; + if (PMA_Util::showIcons('ActionsLinksMode')) { + $drop_image_or_text .= PMA_Util::getImage( + 'b_drop.png', __('Delete tracking data row from report') + ); + } + if (PMA_Util::showText('ActionLinksMode')) { + $drop_image_or_text .= __('Delete'); + } + + /* + * First, list tracked data definition statements + */ + if (count($data['ddlog']) == 0 && count($data['dmlog']) == 0) { + $msg = PMA_Message::notice(__('No data')); + $msg->display(); + } + + if ($selection_schema || $selection_both && count($data['ddlog']) > 0) { + list($temp, $ddlog_count) = PMA_getHtmlForDataDefinitionStatements( + $data, $filter_users, $filter_ts_from, $filter_ts_to, $url_params, + $drop_image_or_text + ); + $html .= $temp; + unset($temp); + } //endif + + /* + * Secondly, list tracked data manipulation statements + */ + if (($selection_data || $selection_both) && count($data['dmlog']) > 0) { + $html .= PMA_getHtmlForDataManipulationStatements( + $data, $filter_users, $filter_ts_from, $filter_ts_to, $url_params, + $ddlog_count, $drop_image_or_text + ); + } + $html .= '
'; + $html .= '
'; + $html .= sprintf( + __('Show %1$s with dates from %2$s to %3$s by user %4$s %5$s'), + $str1, $str2, $str3, $str4, $str5 + ); + + $str_export1 = ''; + + $str_export2 = '' + . ''; + $html .= '
'; + $html .= '
'; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= "
" . sprintf(__('Export as %s'), $str_export1) + . $str_export2 . "
"; + $html .= '
'; + $html .= "



\n"; + + return $html; +} +/** + * Function to get html for data manipulation statements + * + * @param array $data data + * @param array $filter_users filter users + * @param int $filter_ts_from filter time staml from + * @param int $filter_ts_to filter time stamp to + * @param array $url_params url parameters + * @param int $ddlog_count data definition log count + * @param string $drop_image_or_text drop image or text + * + * @return string + */ +function PMA_getHtmlForDataManipulationStatements($data, $filter_users, + $filter_ts_from, $filter_ts_to, $url_params, $ddlog_count, + $drop_image_or_text +) { + $i = $ddlog_count; + $html = ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + + $style = 'odd'; + foreach ($data['dmlog'] as $entry) { + $html .= PMA_getHtmlForDataManipulationStatement( + $entry, $filter_users, $filter_ts_from, $filter_ts_to, $style, $i, + $url_params, $ddlog_count, $drop_image_or_text + ); + if ($style == 'even') { + $style = 'odd'; + } else { + $style = 'even'; + } + $i++; + } + $html .= ''; + $html .= '
#' . __('Date') . '' . __('Username') . '' . __('Data manipulation statement') . '' . __('Delete') . '
'; + + return $html; +} + +/** + * Function to get html for data manipulation statements + * + * @param array $entry entry + * @param array $filter_users filter users + * @param int $filter_ts_from filter time stamp from + * @param int $filter_ts_to filter time stamp to + * @param string $style style + * @param int $i field number + * @param array $url_params url parameters + * @param int $ddlog_count data definition log count + * @param string $drop_image_or_text drop image or text + * + * @return string + */ +function PMA_getHtmlForDataManipulationStatement($entry, $filter_users, + $filter_ts_from, $filter_ts_to, $style, $i, $url_params, $ddlog_count, + $drop_image_or_text +) { + $statement = PMA_Util::formatSql($entry['statement'], true); + $timestamp = strtotime($entry['date']); + $filtered_user = in_array($entry['username'], $filter_users); + if ($timestamp >= $filter_ts_from + && $timestamp <= $filter_ts_to + && (in_array('*', $filter_users) || $filtered_user) + ) { + $html = ''; + $html .= '' . $i . ''; + $html .= '' + . htmlspecialchars($entry['date']) . ''; + $html .= '' + . htmlspecialchars($entry['username']) . ''; + $html .= '' . $statement . ''; + $html .= '' + . $drop_image_or_text + . ''; + $html .= ''; + } + + return $html; +} +/** + * Function to get html for data definition statements in schema snapshot + * + * @param array $data data + * @param array $filter_users filter users + * @param int $filter_ts_from filter time stamp from + * @param int $filter_ts_to filter time stamp to + * @param array $url_params url parameters + * @param string $drop_image_or_text drop image or text + * + * @return string + */ +function PMA_getHtmlForDataDefinitionStatements($data, $filter_users, + $filter_ts_from, $filter_ts_to, $url_params, $drop_image_or_text +) { + $i = 1; + $html = ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + + $style = 'odd'; + foreach ($data['ddlog'] as $entry) { + $html .= PMA_getHtmlForDataDefinitionStatement( + $entry, $filter_users, $filter_ts_from, $filter_ts_to, $style, $i, + $url_params, $drop_image_or_text + ); + if ($style == 'even') { + $style = 'odd'; + } else { + $style = 'even'; + } + $i++; + } + $html .= ''; + $html .= '
#' . __('Date') . '' . __('Username') . '' . __('Data definition statement') . '' . __('Delete') . '
'; + + return array($html, $i); +} +/** + * Function to get html for a data definition statement in schema snapshot + * + * @param array $entry entry + * @param array $filter_users filter users + * @param int $filter_ts_from filter time stamp from + * @param int $filter_ts_to filter time stamp to + * @param string $style style + * @param int $i column number + * @param array $url_params url parameters + * @param string $drop_image_or_text drop image or text + * + * @return string + */ +function PMA_getHtmlForDataDefinitionStatement($entry, $filter_users, + $filter_ts_from, $filter_ts_to, $style, $i, $url_params, $drop_image_or_text +) { + $statement = PMA_Util::formatSql($entry['statement'], true); + $timestamp = strtotime($entry['date']); + $filtered_user = in_array($entry['username'], $filter_users); + if ($timestamp >= $filter_ts_from + && $timestamp <= $filter_ts_to + && (in_array('*', $filter_users) || $filtered_user) + ) { + $html = ''; + $html .= '' . $i . ''; + $html .= '' + . htmlspecialchars($entry['date']) . ''; + $html .= '' + . htmlspecialchars($entry['username']) . ''; + $html .= '' . $statement . ''; + $html .= '' . $drop_image_or_text + . ''; + $html .= ''; + } + + return $html; +} +/** + * Function to get html for schema snapshot + * + * @param string $url_query url query + * + * @return string + */ +function PMA_getHtmlForSchemaSnapshot($url_query) +{ + $html = '

' . __('Structure snapshot') + . ' [' . __('Close') + . ']

'; + $data = PMA_Tracker::getTrackedData( + $_REQUEST['db'], $_REQUEST['table'], $_REQUEST['version'] + ); + + // Get first DROP TABLE/VIEW and CREATE TABLE/VIEW statements + $drop_create_statements = $data['ddlog'][0]['statement']; + + if (strstr($data['ddlog'][0]['statement'], 'DROP TABLE') + || strstr($data['ddlog'][0]['statement'], 'DROP VIEW') + ) { + $drop_create_statements .= $data['ddlog'][1]['statement']; + } + // Print SQL code + $html .= PMA_Util::getMessage( + sprintf( + __('Version %s snapshot (SQL code)'), + htmlspecialchars($_REQUEST['version']) + ), + $drop_create_statements + ); + + // Unserialize snapshot + $temp = unserialize($data['schema_snapshot']); + $columns = $temp['COLUMNS']; + $indexes = $temp['INDEXES']; + $html .= PMA_getHtmlForColumns($columns); + + if (count($indexes) > 0) { + $html .= PMA_getHtmlForIndexes($indexes); + } // endif + $html .= '


'; + + return $html; +} + +/** + * Function to get html for displaying columns in the schema snapshot + * + * @param array $columns columns + * + * @return string + */ +function PMA_getHtmlForColumns($columns) +{ + $html = '

' . __('Structure') . '

'; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $style = 'odd'; + foreach ($columns as $field) { + $html .= PMA_getHtmlForColumn($field, $style); + if ($style == 'even') { + $style = 'odd'; + } else { + $style = 'even'; + } + } + + $html .= ''; + $html .= '
' . __('Column') . '' . __('Type') . '' . __('Collation') . '' . __('Null') . '' . __('Default') . '' . __('Extra') . '' . __('Comment') . '
'; + + return $html; +} + +/** + * Function to get html for column + * + * @param array $field field + * @param string $style style + * + * @return string + */ +function PMA_getHtmlForColumn($field, $style) +{ + $html = ''; + if ($field['Key'] == 'PRI') { + $html .= '' . htmlspecialchars($field['Field']) . ''; + } else { + $html .= '' . htmlspecialchars($field['Field']) . ''; + } + $html .= "\n"; + $html .= '' . htmlspecialchars($field['Type']) . ''; + $html .= '' . htmlspecialchars($field['Collation']) . ''; + $html .= '' . (($field['Null'] == 'YES') ? __('Yes') : __('No')) . ''; + $html .= ''; + if (isset($field['Default'])) { + $extracted_columnspec = PMA_Util::extractColumnSpec($field['Type']); + if ($extracted_columnspec['type'] == 'bit') { + // here, $field['Default'] contains something like b'010' + $html .= PMA_Util::convertBitDefaultValue($field['Default']); + } else { + $html .= htmlspecialchars($field['Default']); + } + } else { + if ($field['Null'] == 'YES') { + $html .= 'NULL'; + } else { + $html .= '' . _pgettext('None for default', 'None') . ''; + } + } + $html .= ''; + $html .= '' . htmlspecialchars($field['Extra']) . ''; + $html .= '' . htmlspecialchars($field['Comment']) . ''; + $html .= ''; + + return $html; +} + +/** + * Fuunction to get html for the indexes in schema snapshot + * + * @param array $indexes indexes + * + * @return string + */ +function PMA_getHtmlForIndexes($indexes) +{ + $html = '

' . __('Indexes') . '

'; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + + $style = 'odd'; + foreach ($indexes as $index) { + $html .= PMA_getHtmlForIndex($index, $style); + if ($style == 'even') { + $style = 'odd'; + } else { + $style = 'even'; + } + } + $html .= ''; + $html .= '
' . __('Keyname') . '' . __('Type') . '' . __('Unique') . '' . __('Packed') . '' . __('Column') . '' . __('Cardinality') . '' . __('Collation') . '' . __('Null') . '' . __('Comment') . '
'; + return $html; +} + +/** + * Funtion to get html for an index in schema snapshot + * + * @param array $index index + * @param string $style style + * + * @return string + */ +function PMA_getHtmlForIndex($index, $style) +{ + if ($index['Non_unique'] == 0) { + $str_unique = __('Yes'); + } else { + $str_unique = __('No'); + } + if ($index['Packed'] != '') { + $str_packed = __('Yes'); + } else { + $str_packed = __('No'); + } + + $html .= ''; + $html .= '' . htmlspecialchars($index['Key_name']) . ''; + $html .= '' . htmlspecialchars($index['Index_type']) . ''; + $html .= '' . $str_unique . ''; + $html .= '' . $str_packed . ''; + $html .= '' . htmlspecialchars($index['Column_name']) . ''; + $html .= '' . htmlspecialchars($index['Cardinality']) . ''; + $html .= '' . htmlspecialchars($index['Collation']) . ''; + $html .= '' . htmlspecialchars($index['Null']) . ''; + $html .= '' . htmlspecialchars($index['Comment']) . ''; + $html .= ''; + + return $html; +} + +/** + * Function to handle the tracking report + * + * @param array &$data tracked data + * + * @return void + */ +function PMA_deleteTrackingReportRows(&$data) +{ + if (isset($_REQUEST['delete_ddlog'])) { + // Delete ddlog row data + PMA_handleDeleteDataDefinitionsLog($data); + } + + if (isset($_REQUEST['delete_dmlog'])) { + // Delete dmlog row data + PMA_handleDeleteDataManipulationLog($data); + } +} + +/** + * Function to handle the delete ddlog row data + * + * @param array &$data tracked data + * + * @return void + */ +function PMA_handleDeleteDataDefinitionsLog(&$data) +{ + $delete_id = $_REQUEST['delete_ddlog']; + + // Only in case of valable id + if ($delete_id == (int)$delete_id) { + unset($data['ddlog'][$delete_id]); + + $successfullyDeleted = PMA_Tracker::changeTrackingData( + $_REQUEST['db'], $_REQUEST['table'], + $_REQUEST['version'], 'DDL', $data['ddlog'] + ); + if ($successfullyDeleted) { + $msg = PMA_Message::success( + __('Tracking data definition successfully deleted') + ); + } else { + $msg = PMA_Message::rawError(__('Query error')); + } + $msg->display(); + } +} + +/** + * Function to handle the delete of fmlog rows + * + * @param array &$data tracked data + * + * @return void + */ +function PMA_handleDeleteDataManipulationLog(&$data) +{ + $delete_id = $_REQUEST['delete_dmlog']; + + // Only in case of valable id + if ($delete_id == (int)$delete_id) { + unset($data['dmlog'][$delete_id]); + + $successfullyDeleted = PMA_Tracker::changeTrackingData( + $_REQUEST['db'], $_REQUEST['table'], + $_REQUEST['version'], 'DML', $data['dmlog'] + ); + if ($successfullyDeleted) { + $msg = PMA_Message::success( + __('Tracking data manipulation successfully deleted') + ); + } else { + $msg = PMA_Message::rawError(__('Query error')); + } + $msg->display(); + } +} + +/** + * Function to export as sql dump + * + * @param array $entries entries + * + * @return void + */ +function PMA_exportAsSQLDump($entries) +{ + $new_query = "# " + . __( + 'You can execute the dump by creating and using a temporary database. ' + . 'Please ensure that you have the privileges to do so.' + ) + . "\n" + . "# " . __('Comment out these two lines if you do not need them.') . "\n" + . "\n" + . "CREATE database IF NOT EXISTS pma_temp_db; \n" + . "USE pma_temp_db; \n" + . "\n"; + + foreach ($entries as $entry) { + $new_query .= $entry['statement']; + } + $msg = PMA_Message::success( + __('SQL statements exported. Please copy the dump or execute it.') + ); + $msg->display(); + + $db_temp = $GLOBALS['db']; + $table_temp = $GLOBALS['table']; + + $GLOBALS['db'] = $GLOBALS['table'] = ''; + include_once './libraries/sql_query_form.lib.php'; + + PMA_getHtmlForSqlQueryForm($new_query, 'sql'); + + $GLOBALS['db'] = $db_temp; + $GLOBALS['table'] = $table_temp; +} + +/** + * Function to export as sql execution + * + * @param array $entries entries + * + * @return array + */ +function PMA_exportAsSQLExecution($entries) +{ + foreach ($entries as $entry) { + $sql_result = $GLOBALS['dbi']->query("/*NOTRACK*/\n" . $entry['statement']); + } + $msg = PMA_Message::success(__('SQL statements executed.')); + $msg->display(); + + return $sql_result; +} + +/** + * Function to export as entries + * + * @param array $entries entries + * + * @return void + */ +function PMA_exportAsFileDownload($entries) +{ + @ini_set('url_rewriter.tags', ''); + + $dump = "# " . sprintf( + __('Tracking report for table `%s`'), htmlspecialchars($_REQUEST['table']) + ) + . "\n" . "# " . date('Y-m-d H:i:s') . "\n"; + foreach ($entries as $entry) { + $dump .= $entry['statement']; + } + $filename = 'log_' . htmlspecialchars($_REQUEST['table']) . '.sql'; + PMA_downloadHeader($filename, 'text/x-sql', strlen($dump)); + + $response = PMA_Response::getInstance(); + $response->addHTML($dump); + + exit(); +} + +/** + * Function to activate tracking + * + * @return void + */ +function PMA_activateTracking() +{ + $activated = PMA_Tracker::activateTracking( + $GLOBALS['db'], $GLOBALS['table'], $_REQUEST['version'] + ); + if ($activated) { + $msg = PMA_Message::success( + sprintf( + __('Tracking for %1$s was activated at version %2$s.'), + htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']), + htmlspecialchars($_REQUEST['version']) + ) + ); + $msg->display(); + } +} + +/** + * Function to deactivate tracking + * + * @return void + */ +function PMA_deactivateTracking() +{ + $deactivated = PMA_Tracker::deactivateTracking( + $GLOBALS['db'], $GLOBALS['table'], $_REQUEST['version'] + ); + if ($deactivated) { + $msg = PMA_Message::success( + sprintf( + __('Tracking for %1$s was deactivated at version %2$s.'), + htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']), + htmlspecialchars($_REQUEST['version']) + ) + ); + $msg->display(); + } +} + +/** + * Function to get tracking set + * + * @return string + */ +function PMA_getTrackingSet() +{ + $tracking_set = ''; + + if ($_REQUEST['alter_table'] == true) { + $tracking_set .= 'ALTER TABLE,'; + } + if ($_REQUEST['rename_table'] == true) { + $tracking_set .= 'RENAME TABLE,'; + } + if ($_REQUEST['create_table'] == true) { + $tracking_set .= 'CREATE TABLE,'; + } + if ($_REQUEST['drop_table'] == true) { + $tracking_set .= 'DROP TABLE,'; + } + if ($_REQUEST['create_index'] == true) { + $tracking_set .= 'CREATE INDEX,'; + } + if ($_REQUEST['drop_index'] == true) { + $tracking_set .= 'DROP INDEX,'; + } + if ($_REQUEST['insert'] == true) { + $tracking_set .= 'INSERT,'; + } + if ($_REQUEST['update'] == true) { + $tracking_set .= 'UPDATE,'; + } + if ($_REQUEST['delete'] == true) { + $tracking_set .= 'DELETE,'; + } + if ($_REQUEST['truncate'] == true) { + $tracking_set .= 'TRUNCATE,'; + } + $tracking_set = rtrim($tracking_set, ','); + + return $tracking_set; +} + +/** + * Function to create the tracking version + * + * @return void + */ +function PMA_createTrackingVersion() +{ + $tracking_set = PMA_getTrackingSet(); + + $versionCreated = PMA_Tracker::createVersion( + $GLOBALS['db'], + $GLOBALS['table'], + $_REQUEST['version'], + $tracking_set, + PMA_Table::isView($GLOBALS['db'], $GLOBALS['table']) + ); + if ($versionCreated) { + $msg = PMA_Message::success( + sprintf( + __('Version %1$s was created, tracking for %2$s is active.'), + htmlspecialchars($_REQUEST['version']), + htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']) + ) + ); + $msg->display(); + } +} + +/** + * Function to get the entries + * + * @param array $data data + * @param int $filter_ts_from filter time stamp from + * @param int $filter_ts_to filter time stamp to + * @param array $filter_users filter users + * + * @return array + */ +function PMA_getEntries($data, $filter_ts_from, $filter_ts_to, $filter_users) +{ + $entries = array(); + // Filtering data definition statements + if ($_REQUEST['logtype'] == 'schema' + || $_REQUEST['logtype'] == 'schema_and_data' + ) { + $entries = array_merge( + $entries, + PMA_filterTracking( + $data['ddlog'], $filter_ts_from, $filter_ts_to, $filter_users + ) + ); + } + + // Filtering data manipulation statements + if ($_REQUEST['logtype'] == 'data' + || $_REQUEST['logtype'] == 'schema_and_data' + ) { + $entries = array_merge( + $entries, + PMA_filterTracking( + $data['dmlog'], $filter_ts_from, $filter_ts_to, $filter_users + ) + ); + } + + // Sort it + foreach ($entries as $key => $row) { + $ids[$key] = $row['id']; + $timestamps[$key] = $row['timestamp']; + $usernames[$key] = $row['username']; + $statements[$key] = $row['statement']; + } + + array_multisort( + $timestamps, SORT_ASC, $ids, SORT_ASC, $usernames, + SORT_ASC, $statements, SORT_ASC, $entries + ); + + return $entries; +} +?> diff --git a/tbl_tracking.php b/tbl_tracking.php index 039fcf9694..c4cbd7a65b 100644 --- a/tbl_tracking.php +++ b/tbl_tracking.php @@ -9,6 +9,8 @@ // Run common work require_once './libraries/common.inc.php'; +require_once './libraries/tbl_tracking.lib.php'; + define('TABLE_MAY_BE_ABSENT', true); require './libraries/tbl_common.inc.php'; $url_query .= '&goto=tbl_tracking.php&back=tbl_tracking.php'; @@ -51,100 +53,14 @@ if (isset($_REQUEST['report']) || isset($_REQUEST['report_export'])) { // Prepare export if (isset($_REQUEST['report_export'])) { - - /** - * Filters tracking entries - * - * @param array $data the entries to filter - * @param string $filter_ts_from "from" date - * @param string $filter_ts_to "to" date - * @param string $filter_users users - * - * @return array filtered entries - */ - function PMA_filterTracking( - $data, $filter_ts_from, $filter_ts_to, $filter_users - ) { - $tmp_entries = array(); - $id = 0; - foreach ($data as $entry) { - $timestamp = strtotime($entry['date']); - - if ($timestamp >= $filter_ts_from - && $timestamp <= $filter_ts_to - && (in_array('*', $filter_users) - || in_array($entry['username'], $filter_users)) - ) { - $tmp_entries[] = array( - 'id' => $id, - 'timestamp' => $timestamp, - 'username' => $entry['username'], - 'statement' => $entry['statement'] - ); - } - $id++; - } - return($tmp_entries); - } - - $entries = array(); - // Filtering data definition statements - if ($_REQUEST['logtype'] == 'schema' - || $_REQUEST['logtype'] == 'schema_and_data' - ) { - $entries = array_merge( - $entries, - PMA_filterTracking( - $data['ddlog'], $filter_ts_from, $filter_ts_to, $filter_users - ) - ); - } - - // Filtering data manipulation statements - if ($_REQUEST['logtype'] == 'data' - || $_REQUEST['logtype'] == 'schema_and_data' - ) { - $entries = array_merge( - $entries, - PMA_filterTracking( - $data['dmlog'], $filter_ts_from, $filter_ts_to, $filter_users - ) - ); - } - - // Sort it - foreach ($entries as $key => $row) { - $ids[$key] = $row['id']; - $timestamps[$key] = $row['timestamp']; - $usernames[$key] = $row['username']; - $statements[$key] = $row['statement']; - } - - array_multisort( - $timestamps, SORT_ASC, $ids, SORT_ASC, $usernames, - SORT_ASC, $statements, SORT_ASC, $entries - ); - + $entries = PMA_getEntries($data, $filter_ts_from, $filter_ts_to, $filter_users); } // Export as file download if (isset($_REQUEST['report_export']) && $_REQUEST['export_type'] == 'sqldumpfile' ) { - @ini_set('url_rewriter.tags', ''); - - $dump = "# " . sprintf( - __('Tracking report for table `%s`'), htmlspecialchars($_REQUEST['table']) - ) - . "\n" . "# " . date('Y-m-d H:i:s') . "\n"; - foreach ($entries as $entry) { - $dump .= $entry['statement']; - } - $filename = 'log_' . htmlspecialchars($_REQUEST['table']) . '.sql'; - PMA_downloadHeader($filename, 'text/x-sql', strlen($dump)); - - echo $dump; - exit(); + PMA_exportAsFileDownload($entries); } @@ -152,7 +68,7 @@ if (isset($_REQUEST['report_export']) * Gets tables informations */ -echo '
'; +$html = '
'; /** * Actions @@ -160,277 +76,34 @@ echo '
'; // Create tracking version if (isset($_REQUEST['submit_create_version'])) { - $tracking_set = ''; - - if ($_REQUEST['alter_table'] == true) { - $tracking_set .= 'ALTER TABLE,'; - } - if ($_REQUEST['rename_table'] == true) { - $tracking_set .= 'RENAME TABLE,'; - } - if ($_REQUEST['create_table'] == true) { - $tracking_set .= 'CREATE TABLE,'; - } - if ($_REQUEST['drop_table'] == true) { - $tracking_set .= 'DROP TABLE,'; - } - if ($_REQUEST['create_index'] == true) { - $tracking_set .= 'CREATE INDEX,'; - } - if ($_REQUEST['drop_index'] == true) { - $tracking_set .= 'DROP INDEX,'; - } - if ($_REQUEST['insert'] == true) { - $tracking_set .= 'INSERT,'; - } - if ($_REQUEST['update'] == true) { - $tracking_set .= 'UPDATE,'; - } - if ($_REQUEST['delete'] == true) { - $tracking_set .= 'DELETE,'; - } - if ($_REQUEST['truncate'] == true) { - $tracking_set .= 'TRUNCATE,'; - } - $tracking_set = rtrim($tracking_set, ','); - - $versionCreated = PMA_Tracker::createVersion( - $GLOBALS['db'], - $GLOBALS['table'], - $_REQUEST['version'], - $tracking_set, - PMA_Table::isView($GLOBALS['db'], $GLOBALS['table']) - ); - if ($versionCreated) { - $msg = PMA_Message::success( - sprintf( - __('Version %1$s was created, tracking for %2$s is active.'), - htmlspecialchars($_REQUEST['version']), - htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']) - ) - ); - $msg->display(); - } + PMA_createTrackingVersion(); } // Deactivate tracking if (isset($_REQUEST['submit_deactivate_now'])) { - $deactivated = PMA_Tracker::deactivateTracking( - $GLOBALS['db'], $GLOBALS['table'], $_REQUEST['version'] - ); - if ($deactivated) { - $msg = PMA_Message::success( - sprintf( - __('Tracking for %1$s was deactivated at version %2$s.'), - htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']), - htmlspecialchars($_REQUEST['version']) - ) - ); - $msg->display(); - } + PMA_deactivateTracking(); } // Activate tracking if (isset($_REQUEST['submit_activate_now'])) { - $activated = PMA_Tracker::activateTracking( - $GLOBALS['db'], $GLOBALS['table'], $_REQUEST['version'] - ); - if ($activated) { - $msg = PMA_Message::success( - sprintf( - __('Tracking for %1$s was activated at version %2$s.'), - htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']), - htmlspecialchars($_REQUEST['version']) - ) - ); - $msg->display(); - } + PMA_activateTracking(); } // Export as SQL execution if (isset($_REQUEST['report_export']) && $_REQUEST['export_type'] == 'execution') { - foreach ($entries as $entry) { - $sql_result = $GLOBALS['dbi']->query("/*NOTRACK*/\n" . $entry['statement']); - } - $msg = PMA_Message::success(__('SQL statements executed.')); - $msg->display(); + $sql_result = PMA_exportAsSQLExecution($entries); } // Export as SQL dump if (isset($_REQUEST['report_export']) && $_REQUEST['export_type'] == 'sqldump') { - $new_query = "# " - . __( - 'You can execute the dump by creating and using a temporary database. ' - . 'Please ensure that you have the privileges to do so.' - ) - . "\n" - . "# " . __('Comment out these two lines if you do not need them.') . "\n" - . "\n" - . "CREATE database IF NOT EXISTS pma_temp_db; \n" - . "USE pma_temp_db; \n" - . "\n"; - - foreach ($entries as $entry) { - $new_query .= $entry['statement']; - } - $msg = PMA_Message::success( - __('SQL statements exported. Please copy the dump or execute it.') - ); - $msg->display(); - - $db_temp = $db; - $table_temp = $table; - - $db = $table = ''; - include_once './libraries/sql_query_form.lib.php'; - - echo PMA_getHtmlForSqlQueryForm($new_query, 'sql'); - - $db = $db_temp; - $table = $table_temp; + PMA_exportAsSQLDump($entries); } /* * Schema snapshot */ if (isset($_REQUEST['snapshot'])) { - echo '

' . __('Structure snapshot') - . ' [' . __('Close') - . ']

'; - $data = PMA_Tracker::getTrackedData( - $_REQUEST['db'], $_REQUEST['table'], $_REQUEST['version'] - ); - - // Get first DROP TABLE/VIEW and CREATE TABLE/VIEW statements - $drop_create_statements = $data['ddlog'][0]['statement']; - - if (strstr($data['ddlog'][0]['statement'], 'DROP TABLE') - || strstr($data['ddlog'][0]['statement'], 'DROP VIEW') - ) { - $drop_create_statements .= $data['ddlog'][1]['statement']; - } - // Print SQL code - echo PMA_Util::getMessage( - sprintf( - __('Version %s snapshot (SQL code)'), - htmlspecialchars($_REQUEST['version']) - ), - $drop_create_statements - ); - - // Unserialize snapshot - $temp = unserialize($data['schema_snapshot']); - $columns = $temp['COLUMNS']; - $indexes = $temp['INDEXES']; - echo '

' . __('Structure') . '

'; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - $style = 'odd'; - foreach ($columns as $field_index => $field) { - echo ''; - if ($field['Key'] == 'PRI') { - echo ''; - } else { - echo ''; - } - echo "\n"; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - if ($style == 'even') { - $style = 'odd'; - } else { - $style = 'even'; - } - } - - echo ''; - echo '
' . __('Column') . '' . __('Type') . '' . __('Collation') . '' . __('Null') . '' . __('Default') . '' . __('Extra') . '' . __('Comment') . '
' . htmlspecialchars($field['Field']) . '' . htmlspecialchars($field['Field']) . '' . htmlspecialchars($field['Type']) . '' . htmlspecialchars($field['Collation']) . '' . (($field['Null'] == 'YES') ? __('Yes') : __('No')) . ''; - if (isset($field['Default'])) { - $extracted_columnspec = PMA_Util::extractColumnSpec($field['Type']); - if ($extracted_columnspec['type'] == 'bit') { - // here, $field['Default'] contains something like b'010' - echo PMA_Util::convertBitDefaultValue($field['Default']); - } else { - echo htmlspecialchars($field['Default']); - } - } else { - if ($field['Null'] == 'YES') { - echo 'NULL'; - } else { - echo '' . _pgettext('None for default', 'None') . ''; - } - } - echo '' . htmlspecialchars($field['Extra']) . '' . htmlspecialchars($field['Comment']) . '
'; - - if (count($indexes) > 0) { - echo '

' . __('Indexes') . '

'; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - $style = 'odd'; - foreach ($indexes as $indexes_index => $index) { - if ($index['Non_unique'] == 0) { - $str_unique = __('Yes'); - } else { - $str_unique = __('No'); - } - if ($index['Packed'] != '') { - $str_packed = __('Yes'); - } else { - $str_packed = __('No'); - } - - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - if ($style == 'even') { - $style = 'odd'; - } else { - $style = 'even'; - } - } - echo ''; - echo '
' . __('Keyname') . '' . __('Type') . '' . __('Unique') . '' . __('Packed') . '' . __('Column') . '' . __('Cardinality') . '' . __('Collation') . '' . __('Null') . '' . __('Comment') . '
' . htmlspecialchars($index['Key_name']) . '' . htmlspecialchars($index['Index_type']) . '' . $str_unique . '' . $str_packed . '' . htmlspecialchars($index['Column_name']) . '' . htmlspecialchars($index['Cardinality']) . '' . htmlspecialchars($index['Collation']) . '' . htmlspecialchars($index['Null']) . '' . htmlspecialchars($index['Comment']) . '
'; - } // endif - echo '


'; + $html .= PMA_getHtmlForSchemaSnapshot($url_query); } // end of snapshot report @@ -440,483 +113,46 @@ if (isset($_REQUEST['snapshot'])) { if (isset($_REQUEST['report']) && (isset($_REQUEST['delete_ddlog']) || isset($_REQUEST['delete_dmlog'])) ) { - - if (isset($_REQUEST['delete_ddlog'])) { - - // Delete ddlog row data - $delete_id = $_REQUEST['delete_ddlog']; - - // Only in case of valable id - if ($delete_id == (int)$delete_id) { - unset($data['ddlog'][$delete_id]); - - $successfullyDeleted = PMA_Tracker::changeTrackingData( - $_REQUEST['db'], $_REQUEST['table'], - $_REQUEST['version'], 'DDL', $data['ddlog'] - ); - if ($successfullyDeleted) { - $msg = PMA_Message::success( - __('Tracking data definition successfully deleted') - ); - } else { - $msg = PMA_Message::rawError(__('Query error')); - } - $msg->display(); - } - } - - if (isset($_REQUEST['delete_dmlog'])) { - - // Delete dmlog row data - $delete_id = $_REQUEST['delete_dmlog']; - - // Only in case of valable id - if ($delete_id == (int)$delete_id) { - unset($data['dmlog'][$delete_id]); - - $successfullyDeleted = PMA_Tracker::changeTrackingData( - $_REQUEST['db'], $_REQUEST['table'], - $_REQUEST['version'], 'DML', $data['dmlog'] - ); - if ($successfullyDeleted) { - $msg = PMA_Message::success( - __('Tracking data manipulation successfully deleted') - ); - } else { - $msg = PMA_Message::rawError(__('Query error')); - } - $msg->display(); - } - } + PMA_deleteTrackingReportRows($data); } if (isset($_REQUEST['report']) || isset($_REQUEST['report_export'])) { - echo '

' . __('Tracking report') - . ' [' . __('Close') - . ']

'; - - echo '' . __('Tracking statements') . ' ' - . htmlspecialchars($data['tracking']) . '
'; - echo '
'; - - echo '
'; - - $str1 = ''; - $str2 = ''; - $str3 = ''; - $str4 = ''; - $str5 = '' - . ''; - - printf( - __('Show %1$s with dates from %2$s to %3$s by user %4$s %5$s'), - $str1, $str2, $str3, $str4, $str5 - ); - - // Prepare delete link content here - $drop_image_or_text = ''; - if (PMA_Util::showIcons('ActionsLinksMode')) { - $drop_image_or_text .= PMA_Util::getImage( - 'b_drop.png', __('Delete tracking data row from report') - ); - } - if (PMA_Util::showText('ActionLinksMode')) { - $drop_image_or_text .= __('Delete'); - } - - /* - * First, list tracked data definition statements - */ - $i = 1; - if (count($data['ddlog']) == 0 && count($data['dmlog']) == 0) { - $msg = PMA_Message::notice(__('No data')); - $msg->display(); - } - - if ($selection_schema || $selection_both && count($data['ddlog']) > 0) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - $style = 'odd'; - foreach ($data['ddlog'] as $entry) { - $statement = PMA_Util::formatSql($entry['statement'], true); - $timestamp = strtotime($entry['date']); - - if ($timestamp >= $filter_ts_from - && $timestamp <= $filter_ts_to - && (in_array('*', $filter_users) - || in_array($entry['username'], $filter_users)) - ) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - if ($style == 'even') { - $style = 'odd'; - } else { - $style = 'even'; - } - $i++; - } - } - echo ''; - echo '
#' . __('Date') . '' . __('Username') . '' . __('Data definition statement') . '' . __('Delete') . '
' . $i . '' . htmlspecialchars($entry['date']) - . '' . htmlspecialchars($entry['username']) - . '' . $statement . '' . $drop_image_or_text - . '
'; - - } //endif - - // Memorize data definition amount - $ddlog_count = $i; - - /* - * Secondly, list tracked data manipulation statements - */ - - if (($selection_data || $selection_both) && count($data['dmlog']) > 0) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - $style = 'odd'; - foreach ($data['dmlog'] as $entry) { - $statement = PMA_Util::formatSql($entry['statement'], true); - $timestamp = strtotime($entry['date']); - - if ($timestamp >= $filter_ts_from - && $timestamp <= $filter_ts_to - && (in_array('*', $filter_users) - || in_array($entry['username'], $filter_users)) - ) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - if ($style == 'even') { - $style = 'odd'; - } else { - $style = 'even'; - } - $i++; - } - } - echo ''; - echo '
#' . __('Date') . '' . __('Username') . '' . __('Data manipulation statement') . '' . __('Delete') . '
' . $i . '' . htmlspecialchars($entry['date']) - . '' . htmlspecialchars($entry['username']) - . '' . $statement . '' - . $drop_image_or_text - . '
'; - } - echo '
'; - echo '
'; - printf( - __('Show %1$s with dates from %2$s to %3$s by user %4$s %5$s'), - $str1, $str2, $str3, $str4, $str5 - ); - - $str_export1 = ''; - - $str_export2 = '' - . ''; - echo '
'; - echo '
'; - echo ''; - echo ''; - echo ''; - echo ''; - echo "
" . sprintf(__('Export as %s'), $str_export1) - . $str_export2 . "
"; - echo '
'; - echo "



\n"; + $html .= PMA_getHtmlForTrackingReport( + $url_query, $data, $url_params, $selection_schema, $selection_data, + $selection_both, $filter_ts_to, $filter_ts_from, $filter_users + ); } // end of report /* * List selectable tables */ - -$sql_query = " SELECT DISTINCT db_name, table_name FROM " . - PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "." . - PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) . - " WHERE db_name = '" . PMA_Util::sqlAddSlashes($GLOBALS['db']) . "' " . - " ORDER BY db_name, table_name"; - -$sql_result = PMA_queryAsControlUser($sql_query); - -if ($GLOBALS['dbi']->numRows($sql_result) > 0) { - echo '
'; - echo ''; - echo ''; - echo ''; - echo '
'; +$selectable_tables_sql_result = PMA_getSQLResultForSelectableTables(); +if ($GLOBALS['dbi']->numRows($selectable_tables_sql_result) > 0) { + $html .= PMA_getHtmlForSelectableTables( + $selectable_tables_sql_result, $url_query + ); } -echo '
'; +$html .= '
'; /* * List versions of current table */ - -$sql_query = " SELECT * FROM " . - PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "." . - PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) . - " WHERE db_name = '" . PMA_Util::sqlAddSlashes($_REQUEST['db']) . "' ". - " AND table_name = '" . PMA_Util::sqlAddSlashes($_REQUEST['table']) ."' ". - " ORDER BY version DESC "; - -$sql_result = PMA_queryAsControlUser($sql_query); - -$last_version = 0; -$maxversion = $GLOBALS['dbi']->fetchArray($sql_result); -$last_version = $maxversion['version']; - +$sql_result = PMA_getListOfVersionsOfTable(); +$last_version = PMA_getTableLastVersionNumber($sql_result); if ($last_version > 0) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - $style = 'odd'; - $GLOBALS['dbi']->dataSeek($sql_result, 0); - while ($version = $GLOBALS['dbi']->fetchArray($sql_result)) { - if ($version['tracking_active'] == 1) { - $version_status = __('active'); - } else { - $version_status = __('not active'); - } - if ($version['version'] == $last_version) { - if ($version['tracking_active'] == 1) { - $tracking_active = true; - } else { - $tracking_active = false; - } - } - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - if ($style == 'even') { - $style = 'odd'; - } else { - $style = 'even'; - } - } - - echo ''; - echo '
' . __('Database') . '' . __('Table') . '' . __('Version') . '' . __('Created') . '' . __('Updated') . '' . __('Status') . '' . __('Show') . '
' . htmlspecialchars($version['db_name']) . '' . htmlspecialchars($version['table_name']) . '' . htmlspecialchars($version['version']) . '' . htmlspecialchars($version['date_created']) . '' . htmlspecialchars($version['date_updated']) . '' . $version_status . '' . __('Tracking report') . ''; - echo '| ' . __('Structure snapshot') . ''; - echo '
'; - - if ($tracking_active) { - echo '
'; - echo '
'; - echo '
'; - echo ''; - printf( - __('Deactivate tracking for %s'), - htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']) - ); - echo ''; - echo ''; - echo ''; - echo ''; - echo '
'; - echo '
'; - echo '
'; - } else { - echo '
'; - echo '
'; - echo '
'; - echo ''; - printf( - __('Activate tracking for %s'), - htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']) - ); - echo ''; - echo ''; - echo ''; - echo ''; - echo '
'; - echo '
'; - echo '
'; - } + $html .= PMA_getHtmlForTableVersionDetails( + $sql_result, $last_version, $url_params, $url_query + ); } -echo '
'; -echo '
'; -echo PMA_URL_getHiddenInputs($GLOBALS['db'], $GLOBALS['table']); -echo '
'; -echo ''; -printf( - __('Create version %1$s of %2$s'), - ($last_version + 1), - htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']) +$html .= PMA_getHtmlForDataDefinitionAndManipulationStatements( + $url_query, $last_version ); -echo ''; -echo ''; +$html .= '
'; -echo '

' . __('Track these data definition statements:') . '

'; -echo '' - . ' ALTER TABLE
'; -echo '' - . ' RENAME TABLE
'; -echo '' - . ' CREATE TABLE
'; -echo '' - . ' DROP TABLE
'; -echo '
'; -echo '' - . ' CREATE INDEX
'; -echo '' - . ' DROP INDEX
'; -echo '

' . __('Track these data manipulation statements:') . '

'; -echo '' - . ' INSERT
'; -echo '' - . ' UPDATE
'; -echo '' - . ' DELETE
'; -echo '' - . ' TRUNCATE
'; +$response = PMA_Response::getInstance(); +$response->addHTML($html); -echo '
'; -echo '
'; - -echo ''; -echo ''; -echo '
'; -echo '
'; -echo '
'; - -echo '
'; +?> \ No newline at end of file