TrackingController.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <?php
  2. declare(strict_types=1);
  3. namespace PhpMyAdmin\Controllers\Table;
  4. use PhpMyAdmin\DbTableExists;
  5. use PhpMyAdmin\Message;
  6. use PhpMyAdmin\Response;
  7. use PhpMyAdmin\Template;
  8. use PhpMyAdmin\Tracker;
  9. use PhpMyAdmin\Tracking;
  10. use PhpMyAdmin\Url;
  11. use PhpMyAdmin\Util;
  12. use function array_map;
  13. use function define;
  14. use function explode;
  15. use function htmlspecialchars;
  16. use function sprintf;
  17. use function strtotime;
  18. final class TrackingController extends AbstractController
  19. {
  20. /** @var Tracking */
  21. private $tracking;
  22. /**
  23. * @param Response $response
  24. * @param string $db Database name.
  25. * @param string $table Table name.
  26. */
  27. public function __construct(
  28. $response,
  29. Template $template,
  30. $db,
  31. $table,
  32. Tracking $tracking
  33. ) {
  34. parent::__construct($response, $template, $db, $table);
  35. $this->tracking = $tracking;
  36. }
  37. public function index(): void
  38. {
  39. global $text_dir, $url_params, $msg, $PMA_Theme, $err_url;
  40. global $data, $entries, $filter_ts_from, $filter_ts_to, $filter_users, $selection_schema;
  41. global $selection_data, $selection_both, $sql_result, $db, $table, $cfg;
  42. $this->addScriptFiles(['vendor/jquery/jquery.tablesorter.js', 'table/tracking.js']);
  43. define('TABLE_MAY_BE_ABSENT', true);
  44. Util::checkParameters(['db', 'table']);
  45. $url_params = ['db' => $db, 'table' => $table];
  46. $err_url = Util::getScriptNameForOption($cfg['DefaultTabTable'], 'table');
  47. $err_url .= Url::getCommon($url_params, '&');
  48. DbTableExists::check();
  49. $activeMessage = '';
  50. if (Tracker::isActive()
  51. && Tracker::isTracked($GLOBALS['db'], $GLOBALS['table'])
  52. && ! (isset($_POST['toggle_activation'])
  53. && $_POST['toggle_activation'] === 'deactivate_now')
  54. && ! (isset($_POST['report_export'])
  55. && $_POST['export_type'] === 'sqldumpfile')
  56. ) {
  57. $msg = Message::notice(
  58. sprintf(
  59. __('Tracking of %s is activated.'),
  60. htmlspecialchars($GLOBALS['db'] . '.' . $GLOBALS['table'])
  61. )
  62. );
  63. $activeMessage = $msg->getDisplay();
  64. }
  65. $url_params['goto'] = Url::getFromRoute('/table/tracking');
  66. $url_params['back'] = Url::getFromRoute('/table/tracking');
  67. $data = [];
  68. $entries = [];
  69. $filter_ts_from = null;
  70. $filter_ts_to = null;
  71. $filter_users = [];
  72. $selection_schema = false;
  73. $selection_data = false;
  74. $selection_both = false;
  75. // Init vars for tracking report
  76. if (isset($_POST['report']) || isset($_POST['report_export'])) {
  77. $data = Tracker::getTrackedData(
  78. $GLOBALS['db'],
  79. $GLOBALS['table'],
  80. $_POST['version']
  81. );
  82. if (! isset($_POST['logtype'])) {
  83. $_POST['logtype'] = 'schema_and_data';
  84. }
  85. if ($_POST['logtype'] === 'schema') {
  86. $selection_schema = true;
  87. } elseif ($_POST['logtype'] === 'data') {
  88. $selection_data = true;
  89. } else {
  90. $selection_both = true;
  91. }
  92. if (! isset($_POST['date_from'])) {
  93. $_POST['date_from'] = $data['date_from'];
  94. }
  95. if (! isset($_POST['date_to'])) {
  96. $_POST['date_to'] = $data['date_to'];
  97. }
  98. if (! isset($_POST['users'])) {
  99. $_POST['users'] = '*';
  100. }
  101. $filter_ts_from = strtotime($_POST['date_from']);
  102. $filter_ts_to = strtotime($_POST['date_to']);
  103. $filter_users = array_map('trim', explode(',', $_POST['users']));
  104. }
  105. // Prepare export
  106. if (isset($_POST['report_export'])) {
  107. $entries = $this->tracking->getEntries(
  108. $data,
  109. (int) $filter_ts_from,
  110. (int) $filter_ts_to,
  111. $filter_users
  112. );
  113. }
  114. // Export as file download
  115. if (isset($_POST['report_export'])
  116. && $_POST['export_type'] === 'sqldumpfile'
  117. ) {
  118. $this->tracking->exportAsFileDownload($entries);
  119. }
  120. $actionMessage = '';
  121. if (isset($_POST['submit_mult'])) {
  122. if (! empty($_POST['selected_versions'])) {
  123. if ($_POST['submit_mult'] === 'delete_version') {
  124. foreach ($_POST['selected_versions'] as $version) {
  125. $this->tracking->deleteTrackingVersion($version);
  126. }
  127. $actionMessage = Message::success(
  128. __('Tracking versions deleted successfully.')
  129. )->getDisplay();
  130. }
  131. } else {
  132. $actionMessage = Message::notice(
  133. __('No versions selected.')
  134. )->getDisplay();
  135. }
  136. }
  137. $deleteVersion = '';
  138. if (isset($_POST['submit_delete_version'])) {
  139. $deleteVersion = $this->tracking->deleteTrackingVersion($_POST['version']);
  140. }
  141. $createVersion = '';
  142. if (isset($_POST['submit_create_version'])) {
  143. $createVersion = $this->tracking->createTrackingVersion();
  144. }
  145. $deactivateTracking = '';
  146. if (isset($_POST['toggle_activation'])
  147. && $_POST['toggle_activation'] === 'deactivate_now'
  148. ) {
  149. $deactivateTracking = $this->tracking->changeTracking('deactivate');
  150. }
  151. $activateTracking = '';
  152. if (isset($_POST['toggle_activation'])
  153. && $_POST['toggle_activation'] === 'activate_now'
  154. ) {
  155. $activateTracking = $this->tracking->changeTracking('activate');
  156. }
  157. // Export as SQL execution
  158. $message = '';
  159. if (isset($_POST['report_export']) && $_POST['export_type'] === 'execution') {
  160. $sql_result = $this->tracking->exportAsSqlExecution($entries);
  161. $msg = Message::success(__('SQL statements executed.'));
  162. $message = $msg->getDisplay();
  163. }
  164. $sqlDump = '';
  165. if (isset($_POST['report_export']) && $_POST['export_type'] === 'sqldump') {
  166. $sqlDump = $this->tracking->exportAsSqlDump($entries);
  167. }
  168. $schemaSnapshot = '';
  169. if (isset($_POST['snapshot'])) {
  170. $schemaSnapshot = $this->tracking->getHtmlForSchemaSnapshot($url_params);
  171. }
  172. $trackingReportRows = '';
  173. if (isset($_POST['report'])
  174. && (isset($_POST['delete_ddlog']) || isset($_POST['delete_dmlog']))
  175. ) {
  176. $trackingReportRows = $this->tracking->deleteTrackingReportRows($data);
  177. }
  178. $trackingReport = '';
  179. if (isset($_POST['report']) || isset($_POST['report_export'])) {
  180. $trackingReport = $this->tracking->getHtmlForTrackingReport(
  181. $data,
  182. $url_params,
  183. $selection_schema,
  184. $selection_data,
  185. $selection_both,
  186. (int) $filter_ts_to,
  187. (int) $filter_ts_from,
  188. $filter_users
  189. );
  190. }
  191. $main = $this->tracking->getHtmlForMainPage(
  192. $url_params,
  193. $PMA_Theme->getImgPath(),
  194. $text_dir
  195. );
  196. $this->render('table/tracking/index', [
  197. 'active_message' => $activeMessage,
  198. 'action_message' => $actionMessage,
  199. 'delete_version' => $deleteVersion,
  200. 'create_version' => $createVersion,
  201. 'deactivate_tracking' => $deactivateTracking,
  202. 'activate_tracking' => $activateTracking,
  203. 'message' => $message,
  204. 'sql_dump' => $sqlDump,
  205. 'schema_snapshot' => $schemaSnapshot,
  206. 'tracking_report_rows' => $trackingReportRows,
  207. 'tracking_report' => $trackingReport,
  208. 'main' => $main,
  209. ]);
  210. }
  211. }