tbl_tracking.lib.php 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Functions used to generate table tracking
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. /**
  9. * Filters tracking entries
  10. *
  11. * @param array $data the entries to filter
  12. * @param string $filter_ts_from "from" date
  13. * @param string $filter_ts_to "to" date
  14. * @param string $filter_users users
  15. *
  16. * @return array filtered entries
  17. */
  18. function PMA_filterTracking(
  19. $data, $filter_ts_from, $filter_ts_to, $filter_users
  20. ) {
  21. $tmp_entries = array();
  22. $id = 0;
  23. foreach ($data as $entry) {
  24. $timestamp = strtotime($entry['date']);
  25. $filtered_user = in_array($entry['username'], $filter_users);
  26. if ($timestamp >= $filter_ts_from
  27. && $timestamp <= $filter_ts_to
  28. && (in_array('*', $filter_users) || $filtered_user)
  29. ) {
  30. $tmp_entries[] = array(
  31. 'id' => $id,
  32. 'timestamp' => $timestamp,
  33. 'username' => $entry['username'],
  34. 'statement' => $entry['statement']
  35. );
  36. }
  37. $id++;
  38. }
  39. return($tmp_entries);
  40. }
  41. /**
  42. * Function to get html for data definition and data manipulation statements
  43. *
  44. * @param string $url_query url query
  45. * @param int $last_version last version
  46. *
  47. * @return string
  48. */
  49. function PMA_getHtmlForDataDefinitionAndManipulationStatements($url_query,
  50. $last_version
  51. ) {
  52. $html = '<div id="div_create_version">';
  53. $html .= '<form method="post" action="tbl_tracking.php?' . $url_query . '">';
  54. $html .= PMA_URL_getHiddenInputs($GLOBALS['db'], $GLOBALS['table']);
  55. $html .= '<fieldset>';
  56. $html .= '<legend>';
  57. $html .= sprintf(
  58. __('Create version %1$s of %2$s'),
  59. ($last_version + 1),
  60. htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table'])
  61. );
  62. $html .= '</legend>';
  63. $html .= '<input type="hidden" name="version" value="' . ($last_version + 1)
  64. . '" />';
  65. $html .= '<p>' . __('Track these data definition statements:')
  66. . '</p>';
  67. $html .= '<input type="checkbox" name="alter_table" value="true"'
  68. . ' checked="checked" /> ALTER TABLE<br/>';
  69. $html .= '<input type="checkbox" name="rename_table" value="true"'
  70. . ' checked="checked" /> RENAME TABLE<br/>';
  71. $html .= '<input type="checkbox" name="create_table" value="true"'
  72. . ' checked="checked" /> CREATE TABLE<br/>';
  73. $html .= '<input type="checkbox" name="drop_table" value="true"'
  74. . ' checked="checked" /> DROP TABLE<br/>';
  75. $html .= '<br/>';
  76. $html .= '<input type="checkbox" name="create_index" value="true"'
  77. . ' checked="checked" /> CREATE INDEX<br/>';
  78. $html .= '<input type="checkbox" name="drop_index" value="true"'
  79. . ' checked="checked" /> DROP INDEX<br/>';
  80. $html .= '<p>' . __('Track these data manipulation statements:') . '</p>';
  81. $html .= '<input type="checkbox" name="insert" value="true"'
  82. . ' checked="checked" /> INSERT<br/>';
  83. $html .= '<input type="checkbox" name="update" value="true"'
  84. . ' checked="checked" /> UPDATE<br/>';
  85. $html .= '<input type="checkbox" name="delete" value="true"'
  86. . ' checked="checked" /> DELETE<br/>';
  87. $html .= '<input type="checkbox" name="truncate" value="true"'
  88. . ' checked="checked" /> TRUNCATE<br/>';
  89. $html .= '</fieldset>';
  90. $html .= '<fieldset class="tblFooters">';
  91. $html .= '<input type="hidden" name="submit_create_version" value="1" />';
  92. $html .= '<input type="submit" value="' . __('Create version') . '" />';
  93. $html .= '</fieldset>';
  94. $html .= '</form>';
  95. $html .= '</div>';
  96. return $html;
  97. }
  98. /**
  99. * Function to get html for activate tracking
  100. *
  101. * @param string $url_query url query
  102. * @param int $last_version last version
  103. *
  104. * @return string
  105. */
  106. function PMA_getHtmlForActivateTracking($url_query, $last_version)
  107. {
  108. $html = '<div id="div_activate_tracking">';
  109. $html .= '<form method="post" action="tbl_tracking.php?' . $url_query . '">';
  110. $html .= '<fieldset>';
  111. $html .= '<legend>';
  112. $html .= sprintf(
  113. __('Activate tracking for %s'),
  114. htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table'])
  115. );
  116. $html .= '</legend>';
  117. $html .= '<input type="hidden" name="version" value="' . $last_version . '" />';
  118. $html .= '<input type="hidden" name="submit_activate_now" value="1" />';
  119. $html .= '<input type="submit" value="' . __('Activate now') . '" />';
  120. $html .= '</fieldset>';
  121. $html .= '</form>';
  122. $html .= '</div>';
  123. return $html;
  124. }
  125. /**
  126. * Function to get html for deactivating tracking
  127. *
  128. * @param string $url_query url query
  129. * @param int $last_version last version
  130. *
  131. * @return string
  132. */
  133. function PMA_getHtmlForDeactivateTracking($url_query, $last_version)
  134. {
  135. $html = '<div id="div_deactivate_tracking">';
  136. $html .= '<form method="post" action="tbl_tracking.php?' . $url_query . '">';
  137. $html .= '<fieldset>';
  138. $html .= '<legend>';
  139. $html .= sprintf(
  140. __('Deactivate tracking for %s'),
  141. htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table'])
  142. );
  143. $html .= '</legend>';
  144. $html .= '<input type="hidden" name="version" value="' . $last_version . '" />';
  145. $html .= '<input type="hidden" name="submit_deactivate_now" value="1" />';
  146. $html .= '<input type="submit" value="' . __('Deactivate now') . '" />';
  147. $html .= '</fieldset>';
  148. $html .= '</form>';
  149. $html .= '</div>';
  150. return $html;
  151. }
  152. /**
  153. * Function to get the list versions of the table
  154. *
  155. * @return array
  156. */
  157. function PMA_getListOfVersionsOfTable()
  158. {
  159. $sql_query = " SELECT * FROM " .
  160. PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "." .
  161. PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) .
  162. " WHERE db_name = '" . PMA_Util::sqlAddSlashes($_REQUEST['db']) . "' " .
  163. " AND table_name = '" . PMA_Util::sqlAddSlashes($_REQUEST['table']) . "' " .
  164. " ORDER BY version DESC ";
  165. return PMA_queryAsControlUser($sql_query);
  166. }
  167. /**
  168. * Function to get html for displaying last version number
  169. *
  170. * @param array $sql_result sql result
  171. * @param int $last_version last version
  172. * @param array $url_params url parameters
  173. * @param string $url_query url query
  174. *
  175. * @return string
  176. */
  177. function PMA_getHtmlForTableVersionDetails($sql_result, $last_version, $url_params,
  178. $url_query
  179. ) {
  180. $html = '<table id="versions" class="data">';
  181. $html .= '<thead>';
  182. $html .= '<tr>';
  183. $html .= '<th>' . __('Database') . '</th>';
  184. $html .= '<th>' . __('Table') . '</th>';
  185. $html .= '<th>' . __('Version') . '</th>';
  186. $html .= '<th>' . __('Created') . '</th>';
  187. $html .= '<th>' . __('Updated') . '</th>';
  188. $html .= '<th>' . __('Status') . '</th>';
  189. $html .= '<th>' . __('Show') . '</th>';
  190. $html .= '</tr>';
  191. $html .= '</thead>';
  192. $html .= '<tbody>';
  193. $style = 'odd';
  194. $GLOBALS['dbi']->dataSeek($sql_result, 0);
  195. while ($version = $GLOBALS['dbi']->fetchArray($sql_result)) {
  196. if ($version['tracking_active'] == 1) {
  197. $version_status = __('active');
  198. } else {
  199. $version_status = __('not active');
  200. }
  201. if ($version['version'] == $last_version) {
  202. if ($version['tracking_active'] == 1) {
  203. $tracking_active = true;
  204. } else {
  205. $tracking_active = false;
  206. }
  207. }
  208. $html .= '<tr class="noclick ' . $style . '">';
  209. $html .= '<td>' . htmlspecialchars($version['db_name']) . '</td>';
  210. $html .= '<td>' . htmlspecialchars($version['table_name']) . '</td>';
  211. $html .= '<td>' . htmlspecialchars($version['version']) . '</td>';
  212. $html .= '<td>' . htmlspecialchars($version['date_created']) . '</td>';
  213. $html .= '<td>' . htmlspecialchars($version['date_updated']) . '</td>';
  214. $html .= '<td>' . $version_status . '</td>';
  215. $html .= '<td><a href="tbl_tracking.php';
  216. $html .= PMA_URL_getCommon(
  217. $url_params + array(
  218. 'report' => 'true', 'version' => $version['version']
  219. )
  220. );
  221. $html .= '">' . __('Tracking report') . '</a>';
  222. $html .= '&nbsp;|&nbsp;';
  223. $html .= '<a href="tbl_tracking.php';
  224. $html .= PMA_URL_getCommon(
  225. $url_params + array(
  226. 'snapshot' => 'true', 'version' => $version['version']
  227. )
  228. );
  229. $html .= '">' . __('Structure snapshot') . '</a>';
  230. $html .= '</td>';
  231. $html .= '</tr>';
  232. if ($style == 'even') {
  233. $style = 'odd';
  234. } else {
  235. $style = 'even';
  236. }
  237. }
  238. $html .= '</tbody>';
  239. $html .= '</table>';
  240. if ($tracking_active) {
  241. $html .= PMA_getHtmlForDeactivateTracking($url_query, $last_version);
  242. } else {
  243. $html .= PMA_getHtmlForActivateTracking($url_query, $last_version);
  244. }
  245. return $html;
  246. }
  247. /**
  248. * Function to get the last version number of a table
  249. *
  250. * @param array $sql_result sql result
  251. *
  252. * @return int
  253. */
  254. function PMA_getTableLastVersionNumber($sql_result)
  255. {
  256. $maxversion = $GLOBALS['dbi']->fetchArray($sql_result);
  257. $last_version = $maxversion['version'];
  258. return $last_version;
  259. }
  260. /**
  261. * Function to get sql results for selectable tables
  262. *
  263. * @return array
  264. */
  265. function PMA_getSQLResultForSelectableTables()
  266. {
  267. include_once 'libraries/relation.lib.php';
  268. $sql_query = " SELECT DISTINCT db_name, table_name FROM " .
  269. PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "." .
  270. PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) .
  271. " WHERE db_name = '" . PMA_Util::sqlAddSlashes($GLOBALS['db']) . "' " .
  272. " ORDER BY db_name, table_name";
  273. return PMA_queryAsControlUser($sql_query);
  274. }
  275. /**
  276. * Function to get html for selectable table rows
  277. *
  278. * @param array $selectable_tables_sql_result sql results for selectable rows
  279. * @param string $url_query url query
  280. *
  281. * @return string
  282. */
  283. function PMA_getHtmlForSelectableTables($selectable_tables_sql_result, $url_query)
  284. {
  285. $html = '<form method="post" action="tbl_tracking.php?' . $url_query . '">';
  286. $html .= '<select name="table">';
  287. while ($entries = $GLOBALS['dbi']->fetchArray($selectable_tables_sql_result)) {
  288. if (PMA_Tracker::isTracked($entries['db_name'], $entries['table_name'])) {
  289. $status = ' (' . __('active') . ')';
  290. } else {
  291. $status = ' (' . __('not active') . ')';
  292. }
  293. if ($entries['table_name'] == $_REQUEST['table']) {
  294. $s = ' selected="selected"';
  295. } else {
  296. $s = '';
  297. }
  298. $html .= '<option value="' . htmlspecialchars($entries['table_name'])
  299. . '"' . $s . '>' . htmlspecialchars($entries['db_name']) . ' . '
  300. . htmlspecialchars($entries['table_name']) . $status . '</option>'
  301. . "\n";
  302. }
  303. $html .= '</select>';
  304. $html .= '<input type="hidden" name="show_versions_submit" value="1" />';
  305. $html .= '<input type="submit" value="' . __('Show versions') . '" />';
  306. $html .= '</form>';
  307. return $html;
  308. }
  309. /**
  310. * Function to get html for tracking report and tracking report export
  311. *
  312. * @param string $url_query url query
  313. * @param array $data data
  314. * @param array $url_params url params
  315. * @param boolean $selection_schema selection schema
  316. * @param boolean $selection_data selection data
  317. * @param boolean $selection_both selection both
  318. * @param int $filter_ts_to filter time stamp from
  319. * @param int $filter_ts_from filter time stamp tp
  320. * @param array $filter_users filter users
  321. *
  322. * @return string
  323. */
  324. function PMA_getHtmlForTrackingReport($url_query, $data, $url_params,
  325. $selection_schema, $selection_data, $selection_both, $filter_ts_to,
  326. $filter_ts_from, $filter_users
  327. ) {
  328. $html = '<h3>' . __('Tracking report')
  329. . ' [<a href="tbl_tracking.php?' . $url_query . '">' . __('Close')
  330. . '</a>]</h3>';
  331. $html .= '<small>' . __('Tracking statements') . ' '
  332. . htmlspecialchars($data['tracking']) . '</small><br/>';
  333. $html .= '<br/>';
  334. list($str1, $str2, $str3, $str4, $str5) = PMA_getHtmlForElementsOfTrackingReport(
  335. $selection_schema, $selection_data, $selection_both
  336. );
  337. // Prepare delete link content here
  338. $drop_image_or_text = '';
  339. if (PMA_Util::showIcons('ActionsLinksMode')) {
  340. $drop_image_or_text .= PMA_Util::getImage(
  341. 'b_drop.png', __('Delete tracking data row from report')
  342. );
  343. }
  344. if (PMA_Util::showText('ActionLinksMode')) {
  345. $drop_image_or_text .= __('Delete');
  346. }
  347. /*
  348. * First, list tracked data definition statements
  349. */
  350. if (count($data['ddlog']) == 0 && count($data['dmlog']) == 0) {
  351. $msg = PMA_Message::notice(__('No data'));
  352. $msg->display();
  353. }
  354. $html .= PMA_getHtmlForTrackingReportExportForm1(
  355. $data, $url_params, $selection_schema, $selection_data, $selection_both,
  356. $filter_ts_to, $filter_ts_from, $filter_users, $str1, $str2, $str3,
  357. $str4, $str5, $drop_image_or_text
  358. );
  359. $html .= PMA_getHtmlForTrackingReportExportForm2(
  360. $url_params, $str1, $str2, $str3, $str4, $str5
  361. );
  362. $html .= "<br/><br/><hr/><br/>\n";
  363. return $html;
  364. }
  365. /**
  366. * Generate HTML element for report form
  367. *
  368. * @param boolean $selection_schema selection schema
  369. * @param boolean $selection_data selection data
  370. * @param boolean $selection_both selection both
  371. *
  372. * @return array
  373. */
  374. function PMA_getHtmlForElementsOfTrackingReport(
  375. $selection_schema, $selection_data, $selection_both
  376. ) {
  377. $str1 = '<select name="logtype">'
  378. . '<option value="schema"'
  379. . ($selection_schema ? ' selected="selected"' : '') . '>'
  380. . __('Structure only') . '</option>'
  381. . '<option value="data"'
  382. . ($selection_data ? ' selected="selected"' : '') . '>'
  383. . __('Data only') . '</option>'
  384. . '<option value="schema_and_data"'
  385. . ($selection_both ? ' selected="selected"' : '') . '>'
  386. . __('Structure and data') . '</option>'
  387. . '</select>';
  388. $str2 = '<input type="text" name="date_from" value="'
  389. . htmlspecialchars($_REQUEST['date_from']) . '" size="19" />';
  390. $str3 = '<input type="text" name="date_to" value="'
  391. . htmlspecialchars($_REQUEST['date_to']) . '" size="19" />';
  392. $str4 = '<input type="text" name="users" value="'
  393. . htmlspecialchars($_REQUEST['users']) . '" />';
  394. $str5 = '<input type="hidden" name="list_report" value="1" />'
  395. . '<input type="submit" value="' . __('Go') . '" />';
  396. return array($str1, $str2, $str3, $str4, $str5);
  397. }
  398. /**
  399. * Generate HTML for export form
  400. *
  401. * @param array $data data
  402. * @param array $url_params url params
  403. * @param boolean $selection_schema selection schema
  404. * @param boolean $selection_data selection data
  405. * @param boolean $selection_both selection both
  406. * @param int $filter_ts_to filter time stamp from
  407. * @param int $filter_ts_from filter time stamp tp
  408. * @param array $filter_users filter users
  409. * @param string $str1 HTML for logtype select
  410. * @param string $str2 HTML for "from date"
  411. * @param string $str3 HTML for "to date"
  412. * @param string $str4 HTML for user
  413. * @param string $str5 HTML for "list report"
  414. * @param string $drop_image_or_text HTML for image or text
  415. *
  416. * @return string HTML for form
  417. */
  418. function PMA_getHtmlForTrackingReportExportForm1(
  419. $data, $url_params, $selection_schema, $selection_data, $selection_both,
  420. $filter_ts_to, $filter_ts_from, $filter_users, $str1, $str2, $str3,
  421. $str4, $str5, $drop_image_or_text
  422. ) {
  423. $html = '<form method="post" action="tbl_tracking.php'
  424. . PMA_URL_getCommon(
  425. $url_params + array(
  426. 'report' => 'true', 'version' => $_REQUEST['version']
  427. )
  428. )
  429. . '">';
  430. $html .= sprintf(
  431. __('Show %1$s with dates from %2$s to %3$s by user %4$s %5$s'),
  432. $str1, $str2, $str3, $str4, $str5
  433. );
  434. if ($selection_schema || $selection_both && count($data['ddlog']) > 0) {
  435. list($temp, $ddlog_count) = PMA_getHtmlForDataDefinitionStatements(
  436. $data, $filter_users, $filter_ts_from, $filter_ts_to, $url_params,
  437. $drop_image_or_text
  438. );
  439. $html .= $temp;
  440. unset($temp);
  441. } //endif
  442. /*
  443. * Secondly, list tracked data manipulation statements
  444. */
  445. if (($selection_data || $selection_both) && count($data['dmlog']) > 0) {
  446. $html .= PMA_getHtmlForDataManipulationStatements(
  447. $data, $filter_users, $filter_ts_from, $filter_ts_to, $url_params,
  448. $ddlog_count, $drop_image_or_text
  449. );
  450. }
  451. $html .= '</form>';
  452. return $html;
  453. }
  454. /**
  455. * Generate HTML for export form
  456. *
  457. * @param array $url_params Parameters
  458. * @param string $str1 HTML for logtype select
  459. * @param string $str2 HTML for "from date"
  460. * @param string $str3 HTML for "to date"
  461. * @param string $str4 HTML for user
  462. * @param string $str5 HTML for "list report"
  463. *
  464. * @return string HTML for form
  465. */
  466. function PMA_getHtmlForTrackingReportExportForm2(
  467. $url_params, $str1, $str2, $str3, $str4, $str5
  468. ) {
  469. $html = '<form method="post" action="tbl_tracking.php'
  470. . PMA_URL_getCommon(
  471. $url_params + array(
  472. 'report' => 'true', 'version' => $_REQUEST['version']
  473. )
  474. )
  475. . '">';
  476. $html .= sprintf(
  477. __('Show %1$s with dates from %2$s to %3$s by user %4$s %5$s'),
  478. $str1, $str2, $str3, $str4, $str5
  479. );
  480. $html .= '</form>';
  481. $html .= '<form class="disableAjax" method="post" action="tbl_tracking.php'
  482. . PMA_URL_getCommon(
  483. $url_params
  484. + array('report' => 'true', 'version' => $_REQUEST['version'])
  485. )
  486. . '">';
  487. $html .= '<input type="hidden" name="logtype" value="'
  488. . htmlspecialchars($_REQUEST['logtype']) . '" />';
  489. $html .= '<input type="hidden" name="date_from" value="'
  490. . htmlspecialchars($_REQUEST['date_from']) . '" />';
  491. $html .= '<input type="hidden" name="date_to" value="'
  492. . htmlspecialchars($_REQUEST['date_to']) . '" />';
  493. $html .= '<input type="hidden" name="users" value="'
  494. . htmlspecialchars($_REQUEST['users']) . '" />';
  495. $str_export1 = '<select name="export_type">'
  496. . '<option value="sqldumpfile">' . __('SQL dump (file download)')
  497. . '</option>'
  498. . '<option value="sqldump">' . __('SQL dump') . '</option>'
  499. . '<option value="execution" onclick="alert(\''
  500. . PMA_escapeJsString(
  501. __('This option will replace your table and contained data.')
  502. )
  503. . '\')">' . __('SQL execution') . '</option>' . '</select>';
  504. $str_export2 = '<input type="hidden" name="report_export" value="1" />'
  505. . '<input type="submit" value="' . __('Go') . '" />';
  506. $html .= "<br/>" . sprintf(__('Export as %s'), $str_export1)
  507. . $str_export2 . "<br/>";
  508. $html .= '</form>';
  509. return $html;
  510. }
  511. /**
  512. * Function to get html for data manipulation statements
  513. *
  514. * @param array $data data
  515. * @param array $filter_users filter users
  516. * @param int $filter_ts_from filter time staml from
  517. * @param int $filter_ts_to filter time stamp to
  518. * @param array $url_params url parameters
  519. * @param int $ddlog_count data definition log count
  520. * @param string $drop_image_or_text drop image or text
  521. *
  522. * @return string
  523. */
  524. function PMA_getHtmlForDataManipulationStatements($data, $filter_users,
  525. $filter_ts_from, $filter_ts_to, $url_params, $ddlog_count,
  526. $drop_image_or_text
  527. ) {
  528. $i = $ddlog_count;
  529. $html = '<table id="dml_versions" class="data" width="100%">';
  530. $html .= '<thead>';
  531. $html .= '<tr>';
  532. $html .= '<th width="18">#</th>';
  533. $html .= '<th width="100">' . __('Date') . '</th>';
  534. $html .= '<th width="60">' . __('Username') . '</th>';
  535. $html .= '<th>' . __('Data manipulation statement') . '</th>';
  536. $html .= '<th>' . __('Delete') . '</th>';
  537. $html .= '</tr>';
  538. $html .= '</thead>';
  539. $html .= '<tbody>';
  540. $style = 'odd';
  541. foreach ($data['dmlog'] as $entry) {
  542. $html .= PMA_getHtmlForDataManipulationStatement(
  543. $entry, $filter_users, $filter_ts_from, $filter_ts_to, $style, $i,
  544. $url_params, $ddlog_count, $drop_image_or_text
  545. );
  546. if ($style == 'even') {
  547. $style = 'odd';
  548. } else {
  549. $style = 'even';
  550. }
  551. $i++;
  552. }
  553. $html .= '</tbody>';
  554. $html .= '</table>';
  555. return $html;
  556. }
  557. /**
  558. * Function to get html for one data manipulation statement
  559. *
  560. * @param array $entry entry
  561. * @param array $filter_users filter users
  562. * @param int $filter_ts_from filter time stamp from
  563. * @param int $filter_ts_to filter time stamp to
  564. * @param string $style style
  565. * @param int $i field number
  566. * @param array $url_params url parameters
  567. * @param int $ddlog_count data definition log count
  568. * @param string $drop_image_or_text drop image or text
  569. *
  570. * @return string
  571. */
  572. function PMA_getHtmlForDataManipulationStatement($entry, $filter_users,
  573. $filter_ts_from, $filter_ts_to, $style, $i, $url_params, $ddlog_count,
  574. $drop_image_or_text
  575. ) {
  576. $statement = PMA_Util::formatSql($entry['statement'], true);
  577. $timestamp = strtotime($entry['date']);
  578. $filtered_user = in_array($entry['username'], $filter_users);
  579. $html = null;
  580. if ($timestamp >= $filter_ts_from
  581. && $timestamp <= $filter_ts_to
  582. && (in_array('*', $filter_users) || $filtered_user)
  583. ) {
  584. $html = '<tr class="noclick ' . $style . '">';
  585. $html .= '<td><small>' . $i . '</small></td>';
  586. $html .= '<td><small>'
  587. . htmlspecialchars($entry['date']) . '</small></td>';
  588. $html .= '<td><small>'
  589. . htmlspecialchars($entry['username']) . '</small></td>';
  590. $html .= '<td>' . $statement . '</td>';
  591. $html .= '<td class="nowrap"><a href="tbl_tracking.php?'
  592. . PMA_URL_getCommon(
  593. $url_params + array(
  594. 'report' => 'true',
  595. 'version' => $_REQUEST['version'],
  596. 'delete_dmlog' => ($i - $ddlog_count),
  597. )
  598. )
  599. . '">'
  600. . $drop_image_or_text
  601. . '</a></td>';
  602. $html .= '</tr>';
  603. }
  604. return $html;
  605. }
  606. /**
  607. * Function to get html for data definition statements in schema snapshot
  608. *
  609. * @param array $data data
  610. * @param array $filter_users filter users
  611. * @param int $filter_ts_from filter time stamp from
  612. * @param int $filter_ts_to filter time stamp to
  613. * @param array $url_params url parameters
  614. * @param string $drop_image_or_text drop image or text
  615. *
  616. * @return string
  617. */
  618. function PMA_getHtmlForDataDefinitionStatements($data, $filter_users,
  619. $filter_ts_from, $filter_ts_to, $url_params, $drop_image_or_text
  620. ) {
  621. $i = 1;
  622. $html = '<table id="ddl_versions" class="data" width="100%">';
  623. $html .= '<thead>';
  624. $html .= '<tr>';
  625. $html .= '<th width="18">#</th>';
  626. $html .= '<th width="100">' . __('Date') . '</th>';
  627. $html .= '<th width="60">' . __('Username') . '</th>';
  628. $html .= '<th>' . __('Data definition statement') . '</th>';
  629. $html .= '<th>' . __('Delete') . '</th>';
  630. $html .= '</tr>';
  631. $html .= '</thead>';
  632. $html .= '<tbody>';
  633. $style = 'odd';
  634. foreach ($data['ddlog'] as $entry) {
  635. $html .= PMA_getHtmlForDataDefinitionStatement(
  636. $entry, $filter_users, $filter_ts_from, $filter_ts_to, $style, $i,
  637. $url_params, $drop_image_or_text
  638. );
  639. if ($style == 'even') {
  640. $style = 'odd';
  641. } else {
  642. $style = 'even';
  643. }
  644. $i++;
  645. }
  646. $html .= '</tbody>';
  647. $html .= '</table>';
  648. return array($html, $i);
  649. }
  650. /**
  651. * Function to get html for a data definition statement in schema snapshot
  652. *
  653. * @param array $entry entry
  654. * @param array $filter_users filter users
  655. * @param int $filter_ts_from filter time stamp from
  656. * @param int $filter_ts_to filter time stamp to
  657. * @param string $style style
  658. * @param int $i column number
  659. * @param array $url_params url parameters
  660. * @param string $drop_image_or_text drop image or text
  661. *
  662. * @return string
  663. */
  664. function PMA_getHtmlForDataDefinitionStatement($entry, $filter_users,
  665. $filter_ts_from, $filter_ts_to, $style, $i, $url_params, $drop_image_or_text
  666. ) {
  667. $statement = PMA_Util::formatSql($entry['statement'], true);
  668. $timestamp = strtotime($entry['date']);
  669. $filtered_user = in_array($entry['username'], $filter_users);
  670. $html = null;
  671. if ($timestamp >= $filter_ts_from
  672. && $timestamp <= $filter_ts_to
  673. && (in_array('*', $filter_users) || $filtered_user)
  674. ) {
  675. $html = '<tr class="noclick ' . $style . '">';
  676. $html .= '<td><small>' . $i . '</small></td>';
  677. $html .= '<td><small>'
  678. . htmlspecialchars($entry['date']) . '</small></td>';
  679. $html .= '<td><small>'
  680. . htmlspecialchars($entry['username']) . '</small></td>';
  681. $html .= '<td>' . $statement . '</td>';
  682. $html .= '<td class="nowrap"><a href="tbl_tracking.php'
  683. . PMA_URL_getCommon(
  684. $url_params + array(
  685. 'report' => 'true',
  686. 'version' => $_REQUEST['version'],
  687. 'delete_ddlog' => ($i - 1),
  688. )
  689. )
  690. . '">' . $drop_image_or_text
  691. . '</a></td>';
  692. $html .= '</tr>';
  693. }
  694. return $html;
  695. }
  696. /**
  697. * Function to get html for schema snapshot
  698. *
  699. * @param string $url_query url query
  700. *
  701. * @return string
  702. */
  703. function PMA_getHtmlForSchemaSnapshot($url_query)
  704. {
  705. $html = '<h3>' . __('Structure snapshot')
  706. . ' [<a href="tbl_tracking.php?' . $url_query . '">' . __('Close')
  707. . '</a>]</h3>';
  708. $data = PMA_Tracker::getTrackedData(
  709. $_REQUEST['db'], $_REQUEST['table'], $_REQUEST['version']
  710. );
  711. // Get first DROP TABLE/VIEW and CREATE TABLE/VIEW statements
  712. $drop_create_statements = $data['ddlog'][0]['statement'];
  713. if (strstr($data['ddlog'][0]['statement'], 'DROP TABLE')
  714. || strstr($data['ddlog'][0]['statement'], 'DROP VIEW')
  715. ) {
  716. $drop_create_statements .= $data['ddlog'][1]['statement'];
  717. }
  718. // Print SQL code
  719. $html .= PMA_Util::getMessage(
  720. sprintf(
  721. __('Version %s snapshot (SQL code)'),
  722. htmlspecialchars($_REQUEST['version'])
  723. ),
  724. $drop_create_statements
  725. );
  726. // Unserialize snapshot
  727. $temp = unserialize($data['schema_snapshot']);
  728. $columns = $temp['COLUMNS'];
  729. $indexes = $temp['INDEXES'];
  730. $html .= PMA_getHtmlForColumns($columns);
  731. if (count($indexes) > 0) {
  732. $html .= PMA_getHtmlForIndexes($indexes);
  733. } // endif
  734. $html .= '<br /><hr /><br />';
  735. return $html;
  736. }
  737. /**
  738. * Function to get html for displaying columns in the schema snapshot
  739. *
  740. * @param array $columns columns
  741. *
  742. * @return string
  743. */
  744. function PMA_getHtmlForColumns($columns)
  745. {
  746. $html = '<h3>' . __('Structure') . '</h3>';
  747. $html .= '<table id="tablestructure" class="data">';
  748. $html .= '<thead>';
  749. $html .= '<tr>';
  750. $html .= '<th>' . __('Column') . '</th>';
  751. $html .= '<th>' . __('Type') . '</th>';
  752. $html .= '<th>' . __('Collation') . '</th>';
  753. $html .= '<th>' . __('Null') . '</th>';
  754. $html .= '<th>' . __('Default') . '</th>';
  755. $html .= '<th>' . __('Extra') . '</th>';
  756. $html .= '<th>' . __('Comment') . '</th>';
  757. $html .= '</tr>';
  758. $html .= '</thead>';
  759. $html .= '<tbody>';
  760. $style = 'odd';
  761. foreach ($columns as $field) {
  762. $html .= PMA_getHtmlForField($field, $style);
  763. if ($style == 'even') {
  764. $style = 'odd';
  765. } else {
  766. $style = 'even';
  767. }
  768. }
  769. $html .= '</tbody>';
  770. $html .= '</table>';
  771. return $html;
  772. }
  773. /**
  774. * Function to get html for field
  775. *
  776. * @param array $field field
  777. * @param string $style style
  778. *
  779. * @return string
  780. */
  781. function PMA_getHtmlForField($field, $style)
  782. {
  783. $html = '<tr class="noclick ' . $style . '">';
  784. if ($field['Key'] == 'PRI') {
  785. $html .= '<td><b><u>' . htmlspecialchars($field['Field']) . '</u></b></td>';
  786. } else {
  787. $html .= '<td><b>' . htmlspecialchars($field['Field']) . '</b></td>';
  788. }
  789. $html .= "\n";
  790. $html .= '<td>' . htmlspecialchars($field['Type']) . '</td>';
  791. $html .= '<td>' . htmlspecialchars($field['Collation']) . '</td>';
  792. $html .= '<td>' . (($field['Null'] == 'YES') ? __('Yes') : __('No')) . '</td>';
  793. $html .= '<td>';
  794. if (isset($field['Default'])) {
  795. $extracted_columnspec = PMA_Util::extractColumnSpec($field['Type']);
  796. if ($extracted_columnspec['type'] == 'bit') {
  797. // here, $field['Default'] contains something like b'010'
  798. $html .= PMA_Util::convertBitDefaultValue($field['Default']);
  799. } else {
  800. $html .= htmlspecialchars($field['Default']);
  801. }
  802. } else {
  803. if ($field['Null'] == 'YES') {
  804. $html .= '<i>NULL</i>';
  805. } else {
  806. $html .= '<i>' . _pgettext('None for default', 'None') . '</i>';
  807. }
  808. }
  809. $html .= '</td>';
  810. $html .= '<td>' . htmlspecialchars($field['Extra']) . '</td>';
  811. $html .= '<td>' . htmlspecialchars($field['Comment']) . '</td>';
  812. $html .= '</tr>';
  813. return $html;
  814. }
  815. /**
  816. * Fuunction to get html for the indexes in schema snapshot
  817. *
  818. * @param array $indexes indexes
  819. *
  820. * @return string
  821. */
  822. function PMA_getHtmlForIndexes($indexes)
  823. {
  824. $html = '<h3>' . __('Indexes') . '</h3>';
  825. $html .= '<table id="tablestructure_indexes" class="data">';
  826. $html .= '<thead>';
  827. $html .= '<tr>';
  828. $html .= '<th>' . __('Keyname') . '</th>';
  829. $html .= '<th>' . __('Type') . '</th>';
  830. $html .= '<th>' . __('Unique') . '</th>';
  831. $html .= '<th>' . __('Packed') . '</th>';
  832. $html .= '<th>' . __('Column') . '</th>';
  833. $html .= '<th>' . __('Cardinality') . '</th>';
  834. $html .= '<th>' . __('Collation') . '</th>';
  835. $html .= '<th>' . __('Null') . '</th>';
  836. $html .= '<th>' . __('Comment') . '</th>';
  837. $html .= '</tr>';
  838. $html .= '<tbody>';
  839. $style = 'odd';
  840. foreach ($indexes as $index) {
  841. $html .= PMA_getHtmlForIndex($index, $style);
  842. if ($style == 'even') {
  843. $style = 'odd';
  844. } else {
  845. $style = 'even';
  846. }
  847. }
  848. $html .= '</tbody>';
  849. $html .= '</table>';
  850. return $html;
  851. }
  852. /**
  853. * Funtion to get html for an index in schema snapshot
  854. *
  855. * @param array $index index
  856. * @param string $style style
  857. *
  858. * @return string
  859. */
  860. function PMA_getHtmlForIndex($index, $style)
  861. {
  862. if ($index['Non_unique'] == 0) {
  863. $str_unique = __('Yes');
  864. } else {
  865. $str_unique = __('No');
  866. }
  867. if ($index['Packed'] != '') {
  868. $str_packed = __('Yes');
  869. } else {
  870. $str_packed = __('No');
  871. }
  872. $html = '<tr class="noclick ' . $style . '">';
  873. $html .= '<td><b>' . htmlspecialchars($index['Key_name']) . '</b></td>';
  874. $html .= '<td>' . htmlspecialchars($index['Index_type']) . '</td>';
  875. $html .= '<td>' . $str_unique . '</td>';
  876. $html .= '<td>' . $str_packed . '</td>';
  877. $html .= '<td>' . htmlspecialchars($index['Column_name']) . '</td>';
  878. $html .= '<td>' . htmlspecialchars($index['Cardinality']) . '</td>';
  879. $html .= '<td>' . htmlspecialchars($index['Collation']) . '</td>';
  880. $html .= '<td>' . htmlspecialchars($index['Null']) . '</td>';
  881. $html .= '<td>' . htmlspecialchars($index['Comment']) . '</td>';
  882. $html .= '</tr>';
  883. return $html;
  884. }
  885. /**
  886. * Function to handle the tracking report
  887. *
  888. * @param array &$data tracked data
  889. *
  890. * @return void
  891. */
  892. function PMA_deleteTrackingReportRows(&$data)
  893. {
  894. if (isset($_REQUEST['delete_ddlog'])) {
  895. // Delete ddlog row data
  896. PMA_handleDeleteDataDefinitionsLog($data);
  897. }
  898. if (isset($_REQUEST['delete_dmlog'])) {
  899. // Delete dmlog row data
  900. PMA_handleDeleteDataManipulationLog($data);
  901. }
  902. }
  903. /**
  904. * Function to handle the delete ddlog row data
  905. *
  906. * @param array &$data tracked data
  907. *
  908. * @return void
  909. */
  910. function PMA_handleDeleteDataDefinitionsLog(&$data)
  911. {
  912. $delete_id = $_REQUEST['delete_ddlog'];
  913. // Only in case of valable id
  914. if ($delete_id == (int)$delete_id) {
  915. unset($data['ddlog'][$delete_id]);
  916. $successfullyDeleted = PMA_Tracker::changeTrackingData(
  917. $_REQUEST['db'], $_REQUEST['table'],
  918. $_REQUEST['version'], 'DDL', $data['ddlog']
  919. );
  920. if ($successfullyDeleted) {
  921. $msg = PMA_Message::success(
  922. __('Tracking data definition successfully deleted')
  923. );
  924. } else {
  925. $msg = PMA_Message::rawError(__('Query error'));
  926. }
  927. $msg->display();
  928. }
  929. }
  930. /**
  931. * Function to handle the delete of fmlog rows
  932. *
  933. * @param array &$data tracked data
  934. *
  935. * @return void
  936. */
  937. function PMA_handleDeleteDataManipulationLog(&$data)
  938. {
  939. $delete_id = $_REQUEST['delete_dmlog'];
  940. // Only in case of valable id
  941. if ($delete_id == (int)$delete_id) {
  942. unset($data['dmlog'][$delete_id]);
  943. $successfullyDeleted = PMA_Tracker::changeTrackingData(
  944. $_REQUEST['db'], $_REQUEST['table'],
  945. $_REQUEST['version'], 'DML', $data['dmlog']
  946. );
  947. if ($successfullyDeleted) {
  948. $msg = PMA_Message::success(
  949. __('Tracking data manipulation successfully deleted')
  950. );
  951. } else {
  952. $msg = PMA_Message::rawError(__('Query error'));
  953. }
  954. $msg->display();
  955. }
  956. }
  957. /**
  958. * Function to export as sql dump
  959. *
  960. * @param array $entries entries
  961. *
  962. * @return void
  963. */
  964. function PMA_exportAsSQLDump($entries)
  965. {
  966. $new_query = "# "
  967. . __(
  968. 'You can execute the dump by creating and using a temporary database. '
  969. . 'Please ensure that you have the privileges to do so.'
  970. )
  971. . "\n"
  972. . "# " . __('Comment out these two lines if you do not need them.') . "\n"
  973. . "\n"
  974. . "CREATE database IF NOT EXISTS pma_temp_db; \n"
  975. . "USE pma_temp_db; \n"
  976. . "\n";
  977. foreach ($entries as $entry) {
  978. $new_query .= $entry['statement'];
  979. }
  980. $msg = PMA_Message::success(
  981. __('SQL statements exported. Please copy the dump or execute it.')
  982. );
  983. $msg->display();
  984. $db_temp = $GLOBALS['db'];
  985. $table_temp = $GLOBALS['table'];
  986. $GLOBALS['db'] = $GLOBALS['table'] = '';
  987. include_once './libraries/sql_query_form.lib.php';
  988. PMA_getHtmlForSqlQueryForm($new_query, 'sql');
  989. $GLOBALS['db'] = $db_temp;
  990. $GLOBALS['table'] = $table_temp;
  991. }
  992. /**
  993. * Function to export as sql execution
  994. *
  995. * @param array $entries entries
  996. *
  997. * @return array
  998. */
  999. function PMA_exportAsSQLExecution($entries)
  1000. {
  1001. foreach ($entries as $entry) {
  1002. $sql_result = $GLOBALS['dbi']->query("/*NOTRACK*/\n" . $entry['statement']);
  1003. }
  1004. $msg = PMA_Message::success(__('SQL statements executed.'));
  1005. $msg->display();
  1006. return $sql_result;
  1007. }
  1008. /**
  1009. * Function to export as entries
  1010. *
  1011. * @param array $entries entries
  1012. *
  1013. * @return void
  1014. */
  1015. function PMA_exportAsFileDownload($entries)
  1016. {
  1017. @ini_set('url_rewriter.tags', '');
  1018. $dump = "# " . sprintf(
  1019. __('Tracking report for table `%s`'), htmlspecialchars($_REQUEST['table'])
  1020. )
  1021. . "\n" . "# " . date('Y-m-d H:i:s') . "\n";
  1022. foreach ($entries as $entry) {
  1023. $dump .= $entry['statement'];
  1024. }
  1025. $filename = 'log_' . htmlspecialchars($_REQUEST['table']) . '.sql';
  1026. PMA_downloadHeader($filename, 'text/x-sql', strlen($dump));
  1027. $response = PMA_Response::getInstance();
  1028. $response->addHTML($dump);
  1029. exit();
  1030. }
  1031. /**
  1032. * Function to activate tracking
  1033. *
  1034. * @return void
  1035. */
  1036. function PMA_activateTracking()
  1037. {
  1038. $activated = PMA_Tracker::activateTracking(
  1039. $GLOBALS['db'], $GLOBALS['table'], $_REQUEST['version']
  1040. );
  1041. if ($activated) {
  1042. $msg = PMA_Message::success(
  1043. sprintf(
  1044. __('Tracking for %1$s was activated at version %2$s.'),
  1045. htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']),
  1046. htmlspecialchars($_REQUEST['version'])
  1047. )
  1048. );
  1049. $msg->display();
  1050. }
  1051. }
  1052. /**
  1053. * Function to deactivate tracking
  1054. *
  1055. * @return void
  1056. */
  1057. function PMA_deactivateTracking()
  1058. {
  1059. $deactivated = PMA_Tracker::deactivateTracking(
  1060. $GLOBALS['db'], $GLOBALS['table'], $_REQUEST['version']
  1061. );
  1062. if ($deactivated) {
  1063. $msg = PMA_Message::success(
  1064. sprintf(
  1065. __('Tracking for %1$s was deactivated at version %2$s.'),
  1066. htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table']),
  1067. htmlspecialchars($_REQUEST['version'])
  1068. )
  1069. );
  1070. $msg->display();
  1071. }
  1072. }
  1073. /**
  1074. * Function to get tracking set
  1075. *
  1076. * @return string
  1077. */
  1078. function PMA_getTrackingSet()
  1079. {
  1080. $tracking_set = '';
  1081. if ($_REQUEST['alter_table'] == true) {
  1082. $tracking_set .= 'ALTER TABLE,';
  1083. }
  1084. if ($_REQUEST['rename_table'] == true) {
  1085. $tracking_set .= 'RENAME TABLE,';
  1086. }
  1087. if ($_REQUEST['create_table'] == true) {
  1088. $tracking_set .= 'CREATE TABLE,';
  1089. }
  1090. if ($_REQUEST['drop_table'] == true) {
  1091. $tracking_set .= 'DROP TABLE,';
  1092. }
  1093. if ($_REQUEST['create_index'] == true) {
  1094. $tracking_set .= 'CREATE INDEX,';
  1095. }
  1096. if ($_REQUEST['drop_index'] == true) {
  1097. $tracking_set .= 'DROP INDEX,';
  1098. }
  1099. if ($_REQUEST['insert'] == true) {
  1100. $tracking_set .= 'INSERT,';
  1101. }
  1102. if ($_REQUEST['update'] == true) {
  1103. $tracking_set .= 'UPDATE,';
  1104. }
  1105. if ($_REQUEST['delete'] == true) {
  1106. $tracking_set .= 'DELETE,';
  1107. }
  1108. if ($_REQUEST['truncate'] == true) {
  1109. $tracking_set .= 'TRUNCATE,';
  1110. }
  1111. $tracking_set = rtrim($tracking_set, ',');
  1112. return $tracking_set;
  1113. }
  1114. /**
  1115. * Function to create the tracking version
  1116. *
  1117. * @return void
  1118. */
  1119. function PMA_createTrackingVersion()
  1120. {
  1121. $tracking_set = PMA_getTrackingSet();
  1122. $versionCreated = PMA_Tracker::createVersion(
  1123. $GLOBALS['db'],
  1124. $GLOBALS['table'],
  1125. $_REQUEST['version'],
  1126. $tracking_set,
  1127. PMA_Table::isView($GLOBALS['db'], $GLOBALS['table'])
  1128. );
  1129. if ($versionCreated) {
  1130. $msg = PMA_Message::success(
  1131. sprintf(
  1132. __('Version %1$s was created, tracking for %2$s is active.'),
  1133. htmlspecialchars($_REQUEST['version']),
  1134. htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table'])
  1135. )
  1136. );
  1137. $msg->display();
  1138. }
  1139. }
  1140. /**
  1141. * Function to get the entries
  1142. *
  1143. * @param array $data data
  1144. * @param int $filter_ts_from filter time stamp from
  1145. * @param int $filter_ts_to filter time stamp to
  1146. * @param array $filter_users filter users
  1147. *
  1148. * @return array
  1149. */
  1150. function PMA_getEntries($data, $filter_ts_from, $filter_ts_to, $filter_users)
  1151. {
  1152. $entries = array();
  1153. // Filtering data definition statements
  1154. if ($_REQUEST['logtype'] == 'schema'
  1155. || $_REQUEST['logtype'] == 'schema_and_data'
  1156. ) {
  1157. $entries = array_merge(
  1158. $entries,
  1159. PMA_filterTracking(
  1160. $data['ddlog'], $filter_ts_from, $filter_ts_to, $filter_users
  1161. )
  1162. );
  1163. }
  1164. // Filtering data manipulation statements
  1165. if ($_REQUEST['logtype'] == 'data'
  1166. || $_REQUEST['logtype'] == 'schema_and_data'
  1167. ) {
  1168. $entries = array_merge(
  1169. $entries,
  1170. PMA_filterTracking(
  1171. $data['dmlog'], $filter_ts_from, $filter_ts_to, $filter_users
  1172. )
  1173. );
  1174. }
  1175. // Sort it
  1176. $ids = $timestamps = $usernames = $statements = array();
  1177. foreach ($entries as $key => $row) {
  1178. $ids[$key] = $row['id'];
  1179. $timestamps[$key] = $row['timestamp'];
  1180. $usernames[$key] = $row['username'];
  1181. $statements[$key] = $row['statement'];
  1182. }
  1183. array_multisort(
  1184. $timestamps, SORT_ASC, $ids, SORT_ASC, $usernames,
  1185. SORT_ASC, $statements, SORT_ASC, $entries
  1186. );
  1187. return $entries;
  1188. }
  1189. ?>