<?php
declare(strict_types=1);
namespace ReallySimplePlugins\RSS\Core\Features\Vulnerability\Dtos;
use ReallySimplePlugins\RSS\Core\Support\Helpers\Storage;
/**
* Immutable data transfer object representing a vulnerability snapshot summary.
*
* A snapshot captures the aggregated vulnerability state of the system at a
* specific point in time. It is used to:
* - Compare the current state against a previously stored snapshot.
* - Decide whether notifications should be sent (via policy logic).
* - Persist historical state for idempotent scheduled runs.
*
* This DTO contains data only:
* - No business logic
* - No persistence logic
* - No scheduling concerns
*/
final class VulnerabilitySnapshotDto
{
/**
* Highest severity label present in the snapshot (or null if none).
*/
private ?string $highestSeverity;
/**
* Normalized numeric severity score used for comparisons.
*/
private int $severityScore;
/**
* Total number of vulnerable components.
*/
private int $vulnerableCount;
/**
* Number of vulnerable components with updates available.
*/
private int $updatableComponents;
/**
* UNIX timestamp when the snapshot was generated.
*/
private int $generatedAt;
public function __construct(
?string $highestSeverity,
int $severityScore,
int $vulnerableCount,
int $updatableComponents,
int $generatedAt
) {
$this->highestSeverity = $highestSeverity;
$this->severityScore = $severityScore;
$this->vulnerableCount = $vulnerableCount;
$this->updatableComponents = $updatableComponents;
$this->generatedAt = $generatedAt;
}
/**
* Returns the highest severity label present in the snapshot (or null if none).
*/
public function getHighestSeverity(): ?string
{
return $this->highestSeverity;
}
/**
* Returns the normalized numeric severity score used for comparisons.
*/
public function getSeverityScore(): int
{
return $this->severityScore;
}
/**
* Returns the total number of vulnerable components.
*/
public function getVulnerableCount(): int
{
return $this->vulnerableCount;
}
/**
* Returns the number of vulnerable components with updates available.
*/
public function getUpdatableComponents(): int
{
return $this->updatableComponents;
}
/**
* Returns the UNIX timestamp when the snapshot was generated.
*/
public function getGeneratedAt(): int
{
return $this->generatedAt;
}
/**
* Returns an array representation of the snapshot intended for persistence (options/storage).
*
* The array shape is stable and versioned implicitly by the DTO.
*
* @return array{
* highestSeverity: ?string,
* severityScore: int,
* vulnerableCount: int,
* updatableComponents: int,
* generatedAt: int
* }
*/
public function toArray(): array
{
return [
'highestSeverity' => $this->highestSeverity,
'severityScore' => $this->severityScore,
'vulnerableCount' => $this->vulnerableCount,
'updatableComponents' => $this->updatableComponents,
'generatedAt' => $this->generatedAt,
];
}
/**
* Rebuilds a snapshot DTO from persisted storage.
*
* Missing keys are handled defensively via the Storage helper.
*
* @param array<string, mixed> $data
*/
public static function fromArray(array $data): self
{
$storage = new Storage($data);
return new self(
$storage->getString('highestSeverity'),
$storage->getInt('severityScore'),
$storage->getInt('vulnerableCount'),
$storage->getInt('updatableComponents'),
$storage->getInt('generatedAt'),
);
}
}