Logs.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <?php
  2. /**
  3. * This file is part of the ForkBB <https://github.com/forkbb>.
  4. *
  5. * @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
  6. * @license The MIT License (MIT)
  7. */
  8. declare(strict_types=1);
  9. namespace ForkBB\Models\Pages\Admin;
  10. use ForkBB\Models\Page;
  11. use ForkBB\Models\Pages\Admin;
  12. use Throwable;
  13. use function \ForkBB\__;
  14. class Logs extends Admin
  15. {
  16. /**
  17. * Подготавливает данные для шаблона
  18. */
  19. public function info(): Page
  20. {
  21. $this->c->Lang->load('admin_logs');
  22. $logsFiles = $this->c->LogViewer->files();
  23. $info = $this->c->LogViewer->info($logsFiles);
  24. $i = 0;
  25. foreach ($info as $hash => &$cur) {
  26. ++$i;
  27. $cur['linkView'] = $this->c->Router->link(
  28. 'AdminLogsAction',
  29. [
  30. 'action' => 'view',
  31. 'hash' => $hash,
  32. ]
  33. );
  34. $cur['linkDownload'] = $this->c->Router->link(
  35. 'AdminLogsAction',
  36. [
  37. 'action' => 'download',
  38. 'hash' => $hash,
  39. ]
  40. );
  41. if ($i < 15) {
  42. continue;
  43. }
  44. $cur['linkDelete'] = $this->c->Router->link(
  45. 'AdminLogsAction',
  46. [
  47. 'action' => 'delete',
  48. 'hash' => $hash,
  49. ]
  50. );
  51. }
  52. unset($cur);
  53. $this->nameTpl = 'admin/logs';
  54. $this->aIndex = 'logs';
  55. $this->logsInfo = $info;
  56. return $this;
  57. }
  58. public function action(array $args, string $method): Page
  59. {
  60. if (! $this->c->Csrf->verify($args['token'], 'AdminLogsAction', $args)) {
  61. return $this->c->Message->message($this->c->Csrf->getError());
  62. }
  63. $path = $this->c->LogViewer->getPath($args['hash']);
  64. if (
  65. ! \is_string($path)
  66. || ! \is_file($path)
  67. ) {
  68. return $this->c->Message->message('Not Found', true, 404);
  69. }
  70. $this->c->Lang->load('admin_logs');
  71. $this->aIndex = 'logs';
  72. switch ($args['action']) {
  73. case 'view':
  74. return $this->view($path, $args, $method);
  75. case 'delete':
  76. return $this->delete($path, $args, $method);
  77. case 'download':
  78. return $this->download($path, $args, $method);
  79. default:
  80. return $this->c->Message->message('Not Found', true, 404);
  81. }
  82. }
  83. protected function download(string $path, array $args, string $method): Page
  84. {
  85. $this->c->DEBUG = 0;
  86. $this->nameTpl = 'layouts/plain_raw';
  87. $this->plainRaw = \trim(\file_get_contents($path)); // ???? возможности XSendFile/Nginx использовать?
  88. $this->header('Content-type', 'application/octet-stream')
  89. ->header('Content-Transfer-Encoding', 'binary')
  90. ->header('Content-Disposition', 'attachment; filename=' . $this->c->LogViewer->getName($path));
  91. return $this;
  92. }
  93. protected function delete(string $path, array $args, string $method): Page
  94. {
  95. if ('POST' === $method) {
  96. $v = $this->c->Validator->reset()
  97. ->addRules([
  98. 'delete' => 'required|string',
  99. ])->addAliases([
  100. ])->addArguments([
  101. ]);
  102. try {
  103. if (
  104. $v->validation($_POST)
  105. && \unlink($path)
  106. ) {
  107. return $this->c->Redirect->page('AdminLogs')->message('Log deleted redirect');
  108. }
  109. } catch (Throwable $e) {
  110. $this->c->Log->error('Delete log: failed', [
  111. 'exception' => $e,
  112. 'headers' => false,
  113. ]);
  114. }
  115. return $this->c->Redirect->page('AdminLogs')->message('Failed to delete log redirect');
  116. }
  117. $this->nameTpl = 'admin/form';
  118. $this->titleForm = 'Delete log head';
  119. $this->classForm = ['logdel'];
  120. $this->form = $this->formDelete($path, $args);
  121. $this->aCrumbs[] = [$this->c->Router->link('AdminLogsAction', $args), 'Delete log head'];
  122. return $this;
  123. }
  124. protected function formDelete(string $path, array $args): array
  125. {
  126. $form = [
  127. 'action' => $this->c->Router->link('AdminLogsAction', $args),
  128. 'hidden' => [], // токен в url передается для всех действий с логами
  129. 'sets' => [],
  130. 'btns' => [
  131. 'delete' => [
  132. 'type' => 'submit',
  133. 'value' => __(['Delete log %s', $this->c->LogViewer->getName($path)]),
  134. ],
  135. 'cancel' => [
  136. 'type' => 'btn',
  137. 'value' => __('Cancel'),
  138. 'link' => $this->c->Router->link('AdminLogs'),
  139. ],
  140. ],
  141. ];
  142. return $form;
  143. }
  144. protected function view(string $path, array $args, string $method): Page
  145. {
  146. $data = $this->c->LogViewer->parse($path);
  147. foreach ($data as &$cur) {
  148. $cur['context'] = \print_r($cur['context'], true);
  149. }
  150. unset($cur);
  151. $this->nameTpl = 'admin/logs';
  152. $this->logData = $data;
  153. $this->logName = $this->c->LogViewer->getName($path);
  154. $this->aCrumbs[] = [$this->c->Router->link('AdminLogsAction', $args), ['Log %s', $this->logName]];
  155. return $this;
  156. }
  157. }