From 9a4cb3a786a23511f4696437d37ba83663d414b4 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 24 Dec 2024 17:31:39 +0100 Subject: [PATCH] fix: uniformisation --- README.md | 4 ++ cli/sysinfo.php | 3 +- src/Contracts/OperatingSystem.php | 4 +- src/OperatingSystems/FreeBSD.php | 7 ++- src/OperatingSystems/Linux.php | 12 +++-- src/OperatingSystems/MacOS.php | 2 +- src/OperatingSystems/Windows.php | 85 ++++++++++++++++++++++++++++--- 7 files changed, 100 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index f197178..48d6181 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,10 @@ A modern PHP library to get system information with Enums and Value Objects. +The goal is to have reliable and consistent system information across different operating systems. + +This library use local commands to get the system information and parse the output to provide a consistent API. + It also provides a command line utility: `sysinfo`. Compatible with MacOS, Linux, and Windows. diff --git a/cli/sysinfo.php b/cli/sysinfo.php index cd9f690..75b92c9 100644 --- a/cli/sysinfo.php +++ b/cli/sysinfo.php @@ -26,4 +26,5 @@ echo '> OS : '.$os->name().PHP_EOL; echo '> Version : '.$os->version().PHP_EOL; -echo '> Release : '.$os->release().PHP_EOL; +echo '> Kernel : '.$os->kernel().PHP_EOL; +echo '> Build : '.$os->buildVersion().PHP_EOL; diff --git a/src/Contracts/OperatingSystem.php b/src/Contracts/OperatingSystem.php index 1435142..69e3856 100644 --- a/src/Contracts/OperatingSystem.php +++ b/src/Contracts/OperatingSystem.php @@ -8,5 +8,7 @@ public function name(): string; public function version(): string; - public function release(): string; + public function kernel(): string; + + public function buildVersion(): string; } diff --git a/src/OperatingSystems/FreeBSD.php b/src/OperatingSystems/FreeBSD.php index 570bb6e..5b4fe49 100644 --- a/src/OperatingSystems/FreeBSD.php +++ b/src/OperatingSystems/FreeBSD.php @@ -22,7 +22,12 @@ public function version(): string return php_uname('v'); } - public function release(): string + public function kernel(): string + { + return php_uname('r'); + } + + public function buildVersion(): string { return php_uname('r'); } diff --git a/src/OperatingSystems/Linux.php b/src/OperatingSystems/Linux.php index 1607b44..3234b99 100644 --- a/src/OperatingSystems/Linux.php +++ b/src/OperatingSystems/Linux.php @@ -10,8 +10,6 @@ final class Linux implements OperatingSystem private ?string $cached_version = null; - private ?string $cached_release = null; - public function __construct() { $this->retrieveFromEtcOsRelease(); @@ -34,7 +32,6 @@ private function retrieveFromEtcOsRelease(): void /** @var string[] $ini */ $this->cached_name = $ini['NAME'] ?? ''; $this->cached_version = preg_replace('/^((\d.?)*)\s.*/m', '$1', $ini['VERSION'] ?? ''); - $this->cached_release = $ini['VERSION_ID'] ?? ''; } public function name(): string @@ -47,8 +44,13 @@ public function version(): string return $this->cached_version ?? php_uname('v'); } - public function release(): string + public function kernel(): string + { + return php_uname('r'); + } + + public function buildVersion(): string { - return $this->cached_release ?? php_uname('r'); + return php_uname('r'); } } diff --git a/src/OperatingSystems/MacOS.php b/src/OperatingSystems/MacOS.php index aa8d16d..ca266fb 100644 --- a/src/OperatingSystems/MacOS.php +++ b/src/OperatingSystems/MacOS.php @@ -46,7 +46,7 @@ public function version(): string return $this->cached_version ?? Shell::execOrFail('sw_vers --productVersion'); } - public function release(): string + public function kernel(): string { return php_uname('r'); } diff --git a/src/OperatingSystems/Windows.php b/src/OperatingSystems/Windows.php index 7c2eb48..073bf40 100644 --- a/src/OperatingSystems/Windows.php +++ b/src/OperatingSystems/Windows.php @@ -3,6 +3,7 @@ namespace KnotsPHP\System\OperatingSystems; use KnotsPHP\System\Contracts\OperatingSystem; +use KnotsPHP\System\Exceptions\InvalidArgumentException; use KnotsPHP\System\Helpers\Shell; final class Windows implements OperatingSystem @@ -11,10 +12,10 @@ final class Windows implements OperatingSystem private ?string $cached_version = null; - private ?string $cached_release = null; - private ?string $cached_build_version = null; + private ?string $cached_kernel = null; + private ?string $cached_edition = null; public function __construct() @@ -25,6 +26,9 @@ public function __construct() private function retrieveFromSwVers(): void { $result = Shell::exec('wmic os get Caption, Version, BuildNumber /format:list'); + // BuildNumber=22631 + // Caption=Microsoft Windows 11 Famille + // Version=10.0.22631 $lines = explode(PHP_EOL, $result); @@ -35,12 +39,43 @@ private function retrieveFromSwVers(): void $infos[trim($parts[0])] = trim($parts[1] ?? ''); } - $this->cached_edition = preg_replace('/.+\s\d+\s(.*)/m', '$1', $infos['Caption'] ?? ''); + if (str_contains($infos['Caption'], 'Server')) { + // Server 2022 + $this->cached_edition = implode(' ', array_slice(explode(' ', $infos['Caption']), 2)); + $this->cached_version = $this->getWindowsVersion($infos['Version'] ?? ''); + } else { + // Pro / Family / Home + $this->cached_edition = preg_replace('/.+\s\d+\s(.*)/m', '$1', $infos['Caption'] ?? ''); + $this->cached_version = preg_replace('/.+\s(\d+)\s.*/m', '$1', $infos['Version'] ?? ''); + } $this->cached_name = preg_replace('/(.+\s)\d+\s.*/m', '$1', $infos['Caption'] ?? ''); - $this->cached_version = preg_replace('/.+\s(\d+)\s.*/m', '$1', $infos['Caption'] ?? ''); - $this->cached_release = $infos['Version'] ?? null; - $this->cached_build_version = $infos['BuildNumber'] ?? null; + + $this->cached_build_version = $this->getDisplayVersion(); + + $this->cached_kernel = $this->getFullVersionNumber() ?: ($infos['Version'] ?? null); + } + + private function getFullVersionNumber(): ?string + { + return preg_replace('/^.*\[version\s((\d+.?)*)\]/m', '$1', Shell::exec('ver')); + } + + /** + * Get the 23H2 version format + */ + private function getDisplayVersion(): ?string + { + // Execute the registry query + // or (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").DisplayVersion + $output = Shell::exec('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v DisplayVersion 2>&1'); + + // Use regular expression to extract the version + if (preg_match('/DisplayVersion\s+REG_SZ\s+(\S+)/', $output, $matches)) { + return $matches[1]; + } + + return null; } public function name(): string @@ -53,9 +88,38 @@ public function version(): string return $this->cached_version ?? ''; } - public function release(): string + public function getWindowsVersion(string $versionString): ?string { - return $this->cached_release ?? ''; + // 10.0.22631 / 10.0.20348 + $versionParts = explode('.', $versionString); + + // Check if the version string is valid + if (count($versionParts) < 2) { + throw new InvalidArgumentException('Invalid Windows version string: '.$versionString); + } + + // Extract major and minor version numbers + $majorVersion = (int) $versionParts[0]; + $minorVersion = (int) $versionParts[1]; + + // Determine the Windows version based on the major version + if ($majorVersion === 6) { + if ($minorVersion === 1) { + return '7'; + } elseif ($minorVersion === 2) { + return '8'; + } elseif ($minorVersion === 3) { + return '8.1'; + } + } elseif ($majorVersion === 10) { + if ($minorVersion >= 0 && $minorVersion < 22000) { + return '10'; + } elseif ($minorVersion >= 22000) { + return '11'; + } + } + + return null; } public function buildVersion(): string @@ -72,4 +136,9 @@ public function isServer(): bool { return str_contains($this->name(), 'Server'); } + + public function kernel(): string + { + return $this->cached_kernel ?? ''; + } }