networkRangeRepository = $networkRangeRepository; $this->scanJobRepository = $scanJobRepository; $this->discoveredHostRepository = $discoveredHostRepository; } public function index(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { ob_start(); $username = $_SESSION['username'] ?? 'User'; $ranges = $this->networkRangeRepository->findAll(); $activeJobs = $this->scanJobRepository->findActive(); $scanJobs = $this->scanJobRepository->findRecent(10); require dirname(__DIR__, 2) . '/templates/discovery/index.php'; $body = ob_get_clean(); $response->getBody()->write($body); return $response; } public function startScan(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { $data = $request->getParsedBody(); $rangeId = $data['range_id'] ?? null; // Create scan job(s) if ($rangeId !== null) { $range = $this->networkRangeRepository->findById((int)$rangeId); if ($range === null || !$range->enabled) { return $response->withStatus(404)->write('Range not found'); } $this->createScanJob('network_discovery', $range->id); } else { // Scan all enabled ranges $ranges = $this->networkRangeRepository->findEnabled(); foreach ($ranges as $range) { $this->createScanJob('network_discovery', $range->id); } } return $response ->withHeader('Location', '/discovery') ->withStatus(302); } public function ignoreHost(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { $data = $request->getParsedBody(); $hostId = $data['host_id'] ?? null; if ($hostId !== null) { $host = $this->discoveredHostRepository->findById((int)$hostId); if ($host !== null) { $host->status = 'ignored'; $this->discoveredHostRepository->save($host); } } return $response ->withHeader('Location', '/discovery') ->withStatus(302); } public function activeJobs(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { $activeJobs = $this->scanJobRepository->findActive(); ob_start(); require dirname(__DIR__, 2) . '/templates/discovery/_active_jobs.php'; $body = ob_get_clean(); $response->getBody()->write($body); return $response; } public function scanHistory(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { $scanJobs = $this->scanJobRepository->findRecent(10); ob_start(); require dirname(__DIR__, 2) . '/templates/discovery/_scan_history.php'; $body = ob_get_clean(); $response->getBody()->write($body); return $response; } public function pauseJob(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface { $job = $this->scanJobRepository->findById((int)$args['id']); if ($job !== null && $job->status === 'running') { $this->scanJobRepository->updateStatus($job->id, 'paused'); } return $this->activeJobs($request, $response); } public function resumeJob(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface { $job = $this->scanJobRepository->findById((int)$args['id']); if ($job !== null && $job->status === 'paused') { $this->scanJobRepository->updateStatus($job->id, 'pending'); } return $this->activeJobs($request, $response); } public function cancelJob(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface { $job = $this->scanJobRepository->findById((int)$args['id']); if ($job !== null && in_array($job->status, ['pending', 'running', 'paused'], true)) { $this->scanJobRepository->updateStatus($job->id, 'cancelled'); } return $this->activeJobs($request, $response); } private function createScanJob(string $type, int $rangeId): void { $job = new \Domovoy\Models\ScanJob(); $job->type = $type; $job->status = 'pending'; $job->networkRangeId = $rangeId; $job->createdBy = $_SESSION['user_id'] ?? null; $this->scanJobRepository->save($job); } }