'boolean', 'is_open' => 'boolean', 'last_checked_at' => 'datetime', ]; /** * Get the site that owns the TCP port. */ public function site(): BelongsTo { return $this->belongsTo(Site::class); } /** * Scope to filter active ports. */ public function scopeActive($query) { return $query->where('is_active', true); } /** * Scope to filter open ports. */ public function scopeOpen($query) { return $query->where('is_open', true); } /** * Scope to filter closed ports. */ public function scopeClosed($query) { return $query->where('is_open', false); } /** * Get common port names. */ public static function getCommonPorts(): array { return [ 21 => 'FTP', 22 => 'SSH', 23 => 'Telnet', 25 => 'SMTP', 53 => 'DNS', 80 => 'HTTP', 110 => 'POP3', 143 => 'IMAP', 443 => 'HTTPS', 465 => 'SMTPS', 587 => 'SMTP (Submission)', 993 => 'IMAPS', 995 => 'POP3S', 3306 => 'MySQL', 3389 => 'RDP', 5432 => 'PostgreSQL', 6379 => 'Redis', 8080 => 'HTTP Alternate', 8443 => 'HTTPS Alternate', 27017 => 'MongoDB', ]; } /** * Get display name for the port. */ public function getDisplayNameAttribute(): string { if ($this->name) { return $this->name; } $commonPorts = self::getCommonPorts(); return $commonPorts[$this->port] ?? "Port {$this->port}"; } /** * Get status badge color. */ public function getStatusColorAttribute(): string { if ($this->is_open === null) { return 'secondary'; } return $this->is_open ? 'success' : 'danger'; } /** * Get status text. */ public function getStatusTextAttribute(): string { if ($this->is_open === null) { return 'Unknown'; } return $this->is_open ? 'Open' : 'Closed'; } }