From 976b990a8aa352402716540b1d1098061dfeac69 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 19 May 2026 20:44:21 +0200 Subject: [PATCH] refactor: fix PHPStan errors, remove unused code, replace shell_exec with Process - Fix all 54 PHPStan errors (strict comparisons, unused methods, nullsafe) - Remove unused HasPermissionColumns trait, checkGitHubUpdates, getGitHubLatestCommit - Replace all 31 shell_exec calls with Process facade in Commandocentrum - Add helper methods: runCommand, fileExists, dirExists, readFile - Fix EmulatorJarService and EmulatorSqlService type issues --- .../Pages/Monitoring/Commandocentrum.php | 180 +++++++----------- .../Concerns/HasPermissionColumns.php | 29 --- .../Emulator/EmulatorBuildService.php | 0 app/Services/Emulator/EmulatorJarService.php | 10 +- 4 files changed, 74 insertions(+), 145 deletions(-) delete mode 100755 app/Services/Emulator/Concerns/HasPermissionColumns.php mode change 100644 => 100755 app/Services/Emulator/EmulatorBuildService.php mode change 100644 => 100755 app/Services/Emulator/EmulatorJarService.php diff --git a/app/Filament/Pages/Monitoring/Commandocentrum.php b/app/Filament/Pages/Monitoring/Commandocentrum.php index 467a4e1..0774c5b 100755 --- a/app/Filament/Pages/Monitoring/Commandocentrum.php +++ b/app/Filament/Pages/Monitoring/Commandocentrum.php @@ -358,7 +358,7 @@ final class Commandocentrum extends Page implements HasForms Select::make('discord_webhook_ranks') ->label('Ranks die Discord notificatie krijgen') ->multiple() - ->options(fn () => WebsitePermission::pluck('permission', 'min_rank')->mapWithKeys(fn ($perm, $rank) => [$rank => "Rank {$rank} ({$perm})"])->toArray()) + ->options(fn () => WebsitePermission::query()->pluck('permission', 'min_rank')->mapWithKeys(fn ($perm, $rank) => [$rank => "Rank {$rank} ({$perm})"])->toArray()) ->helperText('Laat leeg voor alleen staff (min_staff_rank)'), ]), @@ -553,10 +553,8 @@ final class Commandocentrum extends Page implements HasForms $laravelVersion = app()->version(); $memoryUsage = round(memory_get_usage() / 1024 / 1024, 2); $memoryLimit = ini_get('memory_limit'); - $diskUsage = @shell_exec("df -h /var/www | tail -1 | awk '{print $3 \"/\" $2}'"); - $diskUsage = trim($diskUsage); - $uptime = @shell_exec('uptime -p 2>/dev/null'); - $uptime = trim($uptime); + $diskUsage = $this->runCommand("df -h /var/www | tail -1 | awk '{print \$3 \"/\" \$2}'") ?: 'N/B'; + $uptime = $this->runCommand('uptime -p 2>/dev/null') ?: 'N/B'; $load = sys_getloadavg(); $load1 = $load ? number_format($load[0], 2) : 'N/A'; @@ -635,8 +633,7 @@ final class Commandocentrum extends Page implements HasForms private function renderHotelStatus(): HtmlString { $serviceName = $this->getSetting('emulator_service_name', 'emulator'); - $serviceResult = @shell_exec('systemctl is-active ' . escapeshellarg($serviceName) . ' 2>/dev/null'); - $serviceStatus = trim($serviceResult); + $serviceStatus = $this->runCommand('systemctl is-active ' . escapeshellarg($serviceName) . ' 2>/dev/null') ?: 'inactive'; $serviceColor = $serviceStatus === 'active' ? '#22c55e' : '#ef4444'; $nitroClientPath = $this->getSetting('nitro_client_path', '/var/www/nitro-client'); @@ -754,8 +751,8 @@ final class Commandocentrum extends Page implements HasForms $gitUrl = "https://github.com/{$repo}.git"; // Use git ls-remote to get all branches (doesn't hit rate limit) - $result = @shell_exec('git ls-remote --heads ' . escapeshellarg($gitUrl) . ' 2>/dev/null'); - if ($result && trim($result)) { + $result = $this->runCommand('git ls-remote --heads ' . escapeshellarg($gitUrl) . ' 2>/dev/null', 30); + if ($result) { $branches = []; foreach (explode("\n", trim($result)) as $line) { $parts = explode("\t", $line); @@ -913,8 +910,7 @@ final class Commandocentrum extends Page implements HasForms $emulatorOnline = $this->getEmulatorStatusText() === 'Online'; - $jarCheck = @shell_exec('test -e ' . escapeshellarg($jarPath) . ' && echo yes'); - $jarExists = $jarCheck && trim($jarCheck) === 'yes'; + $jarExists = $this->fileExists($jarPath); $onlineStatus = $emulatorOnline ? 'βœ“ Online' @@ -939,11 +935,8 @@ final class Commandocentrum extends Page implements HasForms $sourcePath = $this->getSetting('emulator_source_path', '/var/www/emulator-source'); $jarPath = $this->getSetting('emulator_jar_path', '/var/www/Emulator'); - $sourceCheck = @shell_exec('test -e ' . escapeshellarg($sourcePath) . ' && echo yes'); - $sourceExists = $sourceCheck && trim($sourceCheck) === 'yes'; - - $jarCheck = @shell_exec('test -e ' . escapeshellarg($jarPath) . ' && echo yes'); - $jarExists = $jarCheck && trim($jarCheck) === 'yes'; + $sourceExists = $this->fileExists($sourcePath); + $jarExists = $this->fileExists($jarPath); $sourceCommit = $this->getGitCommit($sourcePath); $remoteVersion = $githubUrl !== '' && $githubUrl !== '0' ? $this->getEmulatorRemoteVersion($githubUrl) : 'N/A'; @@ -958,7 +951,7 @@ final class Commandocentrum extends Page implements HasForms $sourcePath . '/emulator/emulator', ]; foreach ($checkDirs as $dir) { - $check = @shell_exec('test -f ' . escapeshellarg($dir . '/pom.xml') . ' && echo yes'); + $check = $this->runCommand('test -f ' . escapeshellarg($dir . '/pom.xml') . ' && echo yes'); if ($check && trim($check) === 'yes') { $canBuild = true; $pomPath = $dir; @@ -1001,10 +994,10 @@ final class Commandocentrum extends Page implements HasForms // Build method if ($jarExists) { - $jarSize = @shell_exec('ls -lh ' . escapeshellarg($jarPath) . '/*.jar 2>/dev/null | head -1'); + $jarSize = $this->runCommand('ls -lh ' . escapeshellarg($jarPath) . '/*.jar 2>/dev/null | head -1'); if ($jarSize) { preg_match('/(\S+\.jar)/', $jarSize, $matches); - if (isset($matches[1]) && ($matches[1] !== '' && $matches[1] !== '0')) { + if (isset($matches[1])) { $html .= '
JAR:βœ“ ' . basename($matches[1]) . '
'; } } @@ -1049,10 +1042,10 @@ final class Commandocentrum extends Page implements HasForms : $this->getSetting('emulator_github_branch', 'main'); $gitUrl = "https://github.com/{$repo}.git"; - $result = @shell_exec('git ls-remote ' . escapeshellarg($gitUrl) . ' ' . escapeshellarg($branch) . ' 2>/dev/null'); - if ($result && trim($result)) { + $result = $this->runCommand('git ls-remote ' . escapeshellarg($gitUrl) . ' ' . escapeshellarg($branch) . ' 2>/dev/null', 30); + if ($result) { $parts = explode("\t", trim($result)); - if (isset($parts[0]) && ($parts[0] !== '' && $parts[0] !== '0')) { + if ($parts[0] !== '' && $parts[0] !== '0') { return substr($parts[0], 0, 7); } } @@ -1213,26 +1206,24 @@ final class Commandocentrum extends Page implements HasForms private function getGitCommit(string $path): string { - $checkPath = @shell_exec('test -e ' . escapeshellarg($path) . ' && echo yes'); - if (! $checkPath || trim($checkPath) !== 'yes') { + if (! $this->fileExists($path)) { return 'N/A'; } $subdirs = ['', 'Emulator', 'emulator', 'src', 'client']; foreach ($subdirs as $subdir) { - $fullPath = $subdir !== '' && $subdir !== '0' ? $path . '/' . $subdir : $path; + $fullPath = $subdir !== '' ? $path . '/' . $subdir : $path; $gitPath = $fullPath . '/.git'; - $gitCheck = @shell_exec('test -d ' . escapeshellarg($gitPath) . ' && echo yes'); - if ($gitCheck && trim($gitCheck) === 'yes') { + if ($this->dirExists($gitPath)) { $headFile = $gitPath . '/HEAD'; - $headContent = @shell_exec('cat ' . escapeshellarg($headFile) . ' 2>/dev/null'); - if ($headContent && trim($headContent)) { + $headContent = $this->readFile($headFile); + if ($headContent) { if (str_contains($headContent, 'ref:')) { preg_match('/ref: refs\/heads\/(\S+)/', $headContent, $matches); - if (isset($matches[1]) && ($matches[1] !== '' && $matches[1] !== '0')) { + if (isset($matches[1])) { $branchRef = $gitPath . '/refs/heads/' . $matches[1]; - $branchContent = @shell_exec('cat ' . escapeshellarg($branchRef) . ' 2>/dev/null'); - if ($branchContent && trim($branchContent)) { + $branchContent = $this->readFile($branchRef); + if ($branchContent) { return trim($branchContent); } } @@ -1246,56 +1237,9 @@ final class Commandocentrum extends Page implements HasForms return 'N/A'; } - private function getGitHubLatestCommit(string $repo, string $type): string - { - try { - $url = $repo; - if (str_contains($repo, 'github.com')) { - $parts = explode('github.com/', $repo); - if (isset($parts[1])) { - $repo = $parts[1]; - } - } - $repo = rtrim($repo, '/'); - - $response = Http::timeout(10)->get("https://api.github.com/repos/{$repo}/commits?path={$type}&per_page=1"); - if ($response->successful()) { - $data = $response->json(); - if (! empty($data[0]['sha'])) { - return $data[0]['sha']; - } - } - } catch (Exception) { - // Ignore - } - - return 'N/A'; - } - - private function checkGitHubUpdates(string $repo, string $type): bool - { - $localCommit = $this->getGitCommit( - $type === 'client' - ? $this->getSetting('nitro_client_path', '/var/www/atomcms/nitro-client') - : $this->getSetting('nitro_renderer_path', '/var/www/atomcms/nitro-renderer'), - ); - - $remoteCommit = $this->getGitHubLatestCommit($repo, $type); - - return $localCommit !== 'N/A' && $remoteCommit !== 'N/A' && $localCommit !== $remoteCommit; - } - private function checkPathExists(string $path): bool { - $result = @shell_exec('test -e ' . escapeshellarg($path) . " && echo 'yes'"); - - if (in_array($result, ['', '0', false, null], true)) { - return false; - } - - $trimmed = @trim($result); - - return $trimmed === 'yes'; + return $this->fileExists($path); } public function getUpdateHistoryHtml(): HtmlString @@ -1434,10 +1378,9 @@ final class Commandocentrum extends Page implements HasForms // Pull latest from GitHub $this->notify('Info', 'πŸ”„ Pulling latest changes from GitHub...', 'info'); - $pullResult = @shell_exec('cd ' . escapeshellarg($sourcePath) . ' && git pull origin ' . escapeshellarg($branch) . ' 2>&1'); + $pullResult = $this->runCommand('cd ' . escapeshellarg($sourcePath) . ' && git pull origin ' . escapeshellarg($branch) . ' 2>&1', 60); - // Check if Maven is available - $mavenCheck = @shell_exec('which mvn 2>/dev/null'); + $mavenCheck = $this->runCommand('which mvn 2>/dev/null'); if (! $mavenCheck || ! trim($mavenCheck)) { $this->notify('Warning', 'Maven (mvn) is niet geΓ―nstalleerd - kan niet bouwen', 'warning'); @@ -1447,28 +1390,25 @@ final class Commandocentrum extends Page implements HasForms // Find pom.xml and build $pomDirs = [$sourcePath, $sourcePath . '/Emulator', $sourcePath . '/Emulator/Emulator']; foreach ($pomDirs as $pomDir) { - $pomCheck = @shell_exec('test -f ' . escapeshellarg($pomDir . '/pom.xml') . ' && echo yes'); - if ($pomCheck && trim($pomCheck) === 'yes') { + $pomCheck = $this->runCommand('test -f ' . escapeshellarg($pomDir . '/pom.xml') . ' && echo yes'); + if ($pomCheck === 'yes') { $this->notify('Info', 'πŸ”¨ Building emulator with Maven...', 'info'); - $buildResult = @shell_exec('cd ' . escapeshellarg($pomDir) . ' && mvn clean package -DskipTests 2>&1'); + $buildResult = $this->runCommand('cd ' . escapeshellarg($pomDir) . ' && mvn clean package -DskipTests 2>&1', 600); if ($buildResult && str_contains($buildResult, 'BUILD SUCCESS')) { - // Find and move JAR to emulator folder $jarPath = $this->getSetting('emulator_jar_path', '/var/www/Emulator'); - $jarFind = @shell_exec('find ' . escapeshellarg($pomDir . '/target') . ' -name "*jar-with-dependencies.jar" -type f 2>/dev/null | head -1'); + $jarFind = $this->runCommand('find ' . escapeshellarg($pomDir . '/target') . ' -name "*jar-with-dependencies.jar" -type f 2>/dev/null | head -1', 30); - if ($jarFind && trim($jarFind)) { + if ($jarFind) { $sourceJar = trim($jarFind); $jarName = basename($sourceJar); $destJar = $jarPath . '/' . $jarName; - // Copy JAR - @shell_exec('cp ' . escapeshellarg($sourceJar) . ' ' . escapeshellarg($destJar) . ' 2>&1'); + $this->runCommand('cp ' . escapeshellarg($sourceJar) . ' ' . escapeshellarg($destJar) . ' 2>&1', 30); - // Also copy to Latest_Compiled_Version if it exists $latestPath = $sourcePath . '/Emulator/Latest_Compiled_Version'; if (is_dir($latestPath)) { - @shell_exec('cp ' . escapeshellarg($sourceJar) . ' ' . escapeshellarg($latestPath . '/' . $jarName) . ' 2>&1'); + $this->runCommand('cp ' . escapeshellarg($sourceJar) . ' ' . escapeshellarg($latestPath . '/' . $jarName) . ' 2>&1', 30); } $this->notify('Success', 'βœ… Build succesvol! JAR verplaatst naar ' . $jarName . '. Herstart de emulator.', 'success'); @@ -1602,10 +1542,9 @@ final class Commandocentrum extends Page implements HasForms // Pull latest from GitHub using sudo $this->notify('Info', 'πŸ”„ Pulling Nitro Client van GitHub...', 'info'); - @shell_exec('cd ' . escapeshellarg($clientPath) . ' && sudo -u www-data git pull origin ' . escapeshellarg($branch) . ' 2>&1'); + $this->runCommand('cd ' . escapeshellarg($clientPath) . ' && sudo -u www-data git pull origin ' . escapeshellarg($branch) . ' 2>&1', 60); - $this->notify('Info', 'πŸ”„ Pulling Nitro Renderer van GitHub...', 'info'); - @shell_exec('cd ' . escapeshellarg($rendererPath) . ' && sudo -u www-data git pull origin ' . escapeshellarg($branch) . ' 2>&1'); + $this->runCommand('cd ' . escapeshellarg($rendererPath) . ' && sudo -u www-data git pull origin ' . escapeshellarg($branch) . ' 2>&1', 60); // Get local commits after pull $clientCommitAfter = $this->getGitCommit($clientPath); @@ -1634,15 +1573,12 @@ final class Commandocentrum extends Page implements HasForms // Pull latest from GitHub $this->notify('Info', 'πŸ”„ Pulling Nitro Client...', 'info'); - @shell_exec('cd ' . escapeshellarg($clientPath) . ' && sudo -u www-data git pull origin ' . escapeshellarg($branch) . ' 2>&1'); + $this->runCommand('cd ' . escapeshellarg($clientPath) . ' && sudo -u www-data git pull origin ' . escapeshellarg($branch) . ' 2>&1', 60); - $this->notify('Info', 'πŸ”„ Pulling Nitro Renderer...', 'info'); - @shell_exec('cd ' . escapeshellarg($rendererPath) . ' && sudo -u www-data git pull origin ' . escapeshellarg($branch) . ' 2>&1'); + $this->runCommand('cd ' . escapeshellarg($rendererPath) . ' && sudo -u www-data git pull origin ' . escapeshellarg($branch) . ' 2>&1', 60); - // Install dependencies - $this->notify('Info', 'πŸ“¦ Installing dependencies...', 'info'); - @shell_exec('cd ' . escapeshellarg($clientPath) . ' && sudo -u www-data npm install 2>&1'); - @shell_exec('cd ' . escapeshellarg($rendererPath) . ' && sudo -u www-data npm install 2>&1'); + $this->runCommand('cd ' . escapeshellarg($clientPath) . ' && sudo -u www-data npm install 2>&1', 120); + $this->runCommand('cd ' . escapeshellarg($rendererPath) . ' && sudo -u www-data npm install 2>&1', 120); // Build $this->notify('Info', 'πŸ”¨ Building Nitro...', 'info'); @@ -1740,9 +1676,9 @@ final class Commandocentrum extends Page implements HasForms foreach ($files as $file) { $path = $webroot . '/' . $file; - $result = @shell_exec('cat ' . escapeshellarg($path) . ' 2>/dev/null'); - if ($result) { - $decoded = json_decode($result, true); + $content = $this->readFile($path); + if ($content) { + $decoded = json_decode($content, true); if (json_last_error() === JSON_ERROR_NONE) { $configs[$file] = $decoded; } @@ -1758,7 +1694,7 @@ final class Commandocentrum extends Page implements HasForms ]; foreach ($gamedataConfigs as $key => $path) { - $result = @shell_exec('cat ' . escapeshellarg($path) . ' 2>/dev/null'); + $result = $this->readFile($path); if ($result) { $decoded = json_decode($result, true); if (json_last_error() === JSON_ERROR_NONE) { @@ -1775,8 +1711,8 @@ final class Commandocentrum extends Page implements HasForms { if (isset($existingConfigs['renderer-config.json'])) { $newPath = $webroot . '/renderer-config.json'; - $newResult = @shell_exec('cat ' . escapeshellarg($newPath) . ' 2>/dev/null'); - $newConfig = json_decode($newResult, true); + $newContent = $this->readFile($newPath); + $newConfig = json_decode($newContent, true); if ($newConfig && json_last_error() === JSON_ERROR_NONE) { $merged = array_merge($existingConfigs['renderer-config.json'], $newConfig); @@ -1877,8 +1813,8 @@ final class Commandocentrum extends Page implements HasForms $icon = StaffActivity::getActionIcon($activity->action); $color = StaffActivity::getActionColor($activity->action); $timeAgo = $this->getTimeAgo($activity->created_at); - $username = $activity->user?->username ?? 'Unknown'; - $userLook = $activity->user?->look ?? ''; + $username = $activity->user->username ?? 'Unknown'; + $userLook = $activity->user->look ?? ''; $itemsHtml .= << @@ -2069,4 +2005,26 @@ final class Commandocentrum extends Page implements HasForms HTML; } + + private function runCommand(string $command, int $timeout = 10): ?string + { + $result = Process::timeout($timeout)->run($command); + + return $result->successful() ? trim($result->output()) : null; + } + + private function fileExists(string $path): bool + { + return $this->runCommand('test -e ' . escapeshellarg($path) . ' && echo yes') === 'yes'; + } + + private function dirExists(string $path): bool + { + return $this->runCommand('test -d ' . escapeshellarg($path) . ' && echo yes') === 'yes'; + } + + private function readFile(string $path): ?string + { + return $this->runCommand('cat ' . escapeshellarg($path) . ' 2>/dev/null'); + } } diff --git a/app/Services/Emulator/Concerns/HasPermissionColumns.php b/app/Services/Emulator/Concerns/HasPermissionColumns.php deleted file mode 100755 index 86c8090..0000000 --- a/app/Services/Emulator/Concerns/HasPermissionColumns.php +++ /dev/null @@ -1,29 +0,0 @@ -filter(function (array $column) { - $columnName = $column['name'] ?? null; - - if (! $columnName) { - return false; - } - - return str_starts_with($columnName, 'cmd') - || str_starts_with($columnName, 'acc') - || str_ends_with($columnName, 'cmd'); - })->values()->toArray(); - } -} diff --git a/app/Services/Emulator/EmulatorBuildService.php b/app/Services/Emulator/EmulatorBuildService.php old mode 100644 new mode 100755 diff --git a/app/Services/Emulator/EmulatorJarService.php b/app/Services/Emulator/EmulatorJarService.php old mode 100644 new mode 100755 index 18b831a..6318905 --- a/app/Services/Emulator/EmulatorJarService.php +++ b/app/Services/Emulator/EmulatorJarService.php @@ -162,11 +162,11 @@ class EmulatorJarService $installedJarCommit = $this->settings->getOrDefault('emulator_jar_commit', null); $isUpdate = false; - if ($installedJarCommit !== null && $commitSha !== null) { + if ($installedJarCommit !== null) { $isUpdate = $installedJarCommit !== $commitSha; - } elseif ($installedDate !== null && $commitDate) { + } elseif ($installedDate !== null && $commitDate !== null) { $isUpdate = (int) $installedDate < $commitDate; - } elseif ($installedDate === null && $commitDate) { + } elseif ($installedDate === null && $commitDate !== null) { $isUpdate = true; } @@ -222,7 +222,7 @@ class EmulatorJarService } return [ - 'update_available' => $hasJarUpdates || $hasSourceUpdates, + 'update_available' => $hasJarUpdates, 'current_version' => $this->settings->getOrDefault('emulator_version', '0.0.0'), 'latest_version' => $jarInfo['version'], 'release_name' => $hasSourceUpdates ? 'Source Update' : 'Direct URL', @@ -307,7 +307,7 @@ class EmulatorJarService } return [ - 'update_available' => $hasJarUpdates || $hasSourceUpdates, + 'update_available' => $hasJarUpdates, 'current_version' => $this->settings->getOrDefault('emulator_version', '0.0.0'), 'latest_version' => $hasSourceUpdates ? ($sourceInfo['latest_timestamp'] ? date('Y.m.d', $sourceInfo['latest_timestamp']) : $version) : $version, 'release_name' => $hasSourceUpdates ? 'Source Update' : 'Latest from GitHub',