You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
4.1KB

  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controllers;
  4. use App\Repositories\BoardRepository;
  5. use App\Services\AuthService;
  6. use Core\Controller;
  7. use Core\Request;
  8. class AdminController extends Controller
  9. {
  10. private const SETTINGS_FILE = '/storage/cron-settings.json';
  11. private const LOG_LINES = 300;
  12. private function settingsPath(): string
  13. {
  14. return dirname(__DIR__, 2) . self::SETTINGS_FILE;
  15. }
  16. private function logPath(): string
  17. {
  18. return dirname(__DIR__, 2) . '/storage/import.log';
  19. }
  20. private function loadCronSettings(): array
  21. {
  22. $path = $this->settingsPath();
  23. if (!file_exists($path)) {
  24. return ['enabled' => true, 'interval_minutes' => 30, 'last_run' => null];
  25. }
  26. return json_decode((string) file_get_contents($path), true)
  27. ?? ['enabled' => true, 'interval_minutes' => 30, 'last_run' => null];
  28. }
  29. private function writeCronSettings(array $settings): void
  30. {
  31. file_put_contents(
  32. $this->settingsPath(),
  33. json_encode($settings, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n"
  34. );
  35. }
  36. private function boards(): BoardRepository
  37. {
  38. return new BoardRepository(database());
  39. }
  40. private function readLog(): string
  41. {
  42. $path = $this->logPath();
  43. if (!file_exists($path) || !is_readable($path)) {
  44. return '';
  45. }
  46. $lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: [];
  47. $slice = array_slice($lines, -self::LOG_LINES);
  48. return implode("\n", array_reverse($slice));
  49. }
  50. public function index(): mixed
  51. {
  52. if ($guard = AuthService::requireLogin()) {
  53. return $guard;
  54. }
  55. return $this->view('admin.cron', [
  56. 'pageTitle' => 'PrintStream Import',
  57. 'boards' => $this->boards()->getAll(),
  58. 'settings' => $this->loadCronSettings(),
  59. 'log' => $this->readLog(),
  60. 'logLines' => self::LOG_LINES,
  61. ]);
  62. }
  63. public function saveSettings(Request $request): mixed
  64. {
  65. if ($guard = AuthService::requireLogin()) {
  66. return $guard;
  67. }
  68. $settings = $this->loadCronSettings();
  69. $settings['enabled'] = $request->input('enabled') === 'on';
  70. $settings['interval_minutes'] = max(1, min(120, (int) $request->input('interval_minutes', 30)));
  71. $this->writeCronSettings($settings);
  72. return $this->redirect('/admin/cron');
  73. }
  74. public function runNow(): mixed
  75. {
  76. if ($guard = AuthService::requireLogin()) {
  77. return $guard;
  78. }
  79. // Prefer the known Docker CLI binary; fall back to PHP_BINARY for other environments.
  80. $php = is_executable('/usr/local/bin/php') ? '/usr/local/bin/php' : PHP_BINARY;
  81. $script = dirname(__DIR__, 2) . '/scripts/import-printstream.php';
  82. $log = $this->logPath();
  83. set_time_limit(120);
  84. $output = [];
  85. $returnCode = 0;
  86. exec(escapeshellarg($php) . ' ' . escapeshellarg($script) . ' --force 2>&1', $output, $returnCode);
  87. if (!empty($output)) {
  88. file_put_contents($log, implode("\n", $output) . "\n", FILE_APPEND | LOCK_EX);
  89. }
  90. return $this->redirect('/admin/cron');
  91. }
  92. public function toggleBoard(int $id): mixed
  93. {
  94. if ($guard = AuthService::requireLogin()) {
  95. return $guard;
  96. }
  97. $db = database();
  98. $row = $db->first('SELECT import_from_printstream FROM boards WHERE id = :id', ['id' => $id]);
  99. if ($row === null) {
  100. return $this->redirect('/admin/cron');
  101. }
  102. $newVal = ((int) $row['import_from_printstream']) === 0 ? 1 : 0;
  103. $db->execute(
  104. 'UPDATE boards
  105. SET import_from_printstream = :v, updated_at = :t, updated_by = :u
  106. WHERE id = :id',
  107. [
  108. 'v' => $newVal,
  109. 't' => date('Y-m-d H:i:s'),
  110. 'u' => AuthService::getCurrentUsername(),
  111. 'id' => $id,
  112. ]
  113. );
  114. return $this->redirect('/admin/cron');
  115. }
  116. }

Powered by TurnKey Linux.