<?php
declare(strict_types=1);
namespace ReallySimplePlugins\RSS\Core\Features\Vulnerability\Dtos;
/**
* Immutable data transfer object representing a locally installed WordPress component.
*
* A component can be a plugin, theme, or WordPress core. This DTO captures the
* *runtime installation state* of that component and is primarily used to:
* - Enrich vulnerability data with local context (installed version, update availability).
* - Decide whether actions such as updates or notifications are relevant.
*
* This object contains state only:
* - No persistence logic
* - No vulnerability or policy logic
* - No WordPress hook or scheduling concerns
*/
final class InstalledComponentDto
{
/**
* @var string Component type (`plugin`, `theme`, or `core`)
*/
private string $type;
/**
* @var string Unique identifier used to match vulnerabilities
*/
public string $slug;
/**
* @var string Human-readable component name
*/
private string $name;
/**
* @var string Currently installed version
*/
private string $installedVersion;
/**
* @var string|null Latest available version (null if unknown)
*/
private ?string $latestVersion;
/**
* @var string Plugin file path (empty for themes/core)
*/
private string $file;
/**
* @var bool Whether the component is currently active
*/
private bool $isActive;
/**
* InstalledComponentDto constructor.
*
* @param string $type The type of the component (plugin, theme, or core)
* @param string $slug Unique identifier for matching vulnerabilities
* @param string $name Human-readable name of the component
* @param string $version Currently installed version of the component
* @param string|null $pluginFile Plugin file path, or null if not applicable
* @param bool $isActive Whether the component is currently active
* @param string|null $latestVersion Latest available version, or null if unknown
*/
public function __construct(
string $type,
string $slug,
string $name,
string $version,
?string $pluginFile,
bool $isActive,
?string $latestVersion
) {
$this->type = $type;
$this->slug = $slug;
$this->name = $name;
$this->installedVersion = $version;
$this->file = $pluginFile ?? '';
$this->isActive = $isActive;
$this->latestVersion = $latestVersion;
}
/**
* Get the component type.
*/
public function getType(): string
{
return $this->type;
}
/**
* Get the unique slug identifier.
*/
public function getSlug(): string
{
return $this->slug;
}
/**
* Get the human-readable component name.
*/
public function getName(): string
{
return $this->name;
}
/**
* Get the installed version of the component.
*/
public function getInstalledVersion(): string
{
return $this->installedVersion;
}
/**
* Get the latest available version of the component, or null if unknown.
*/
public function getLatestVersion(): ?string
{
return $this->latestVersion;
}
/**
* Determine if an update is available by comparing installed and latest versions.
*/
public function hasUpdate(): bool
{
if ($this->latestVersion === null) {
return false;
}
return version_compare(
$this->installedVersion,
$this->latestVersion,
'<'
);
}
/**
* Get the plugin file path (empty string if not applicable).
*/
public function getFile(): string
{
return $this->file;
}
/**
* Check if the component is currently active.
*/
public function isActive(): bool
{
return $this->isActive;
}
}