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
This commit is contained in:
root
2026-05-19 20:44:21 +02:00
parent f5666c104d
commit 976b990a8a
4 changed files with 74 additions and 145 deletions
+69 -111
View File
@@ -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
? '<span style="color:#22c55e;">✓ Online</span>'
@@ -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 .= '<div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid #f1f5f9;"><span>JAR:</span><span style="color:#22c55e;font-weight:600;">✓ ' . basename($matches[1]) . '</span></div>';
}
}
@@ -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 .= <<<HTML
<div style="display:flex;align-items:center;gap:12px;padding:12px;border-bottom:1px solid #e2e8f0;">
@@ -2069,4 +2005,26 @@ final class Commandocentrum extends Page implements HasForms
</div>
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');
}
}