Passed
Push — master ( 683d13...106e7b )
by Pol
02:01
created

OsInfo::uuid()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 45
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 23.2584

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 7
eloc 26
c 1
b 1
f 0
nc 10
nop 0
dl 0
loc 45
ccs 8
cts 26
cp 0.3076
crap 23.2584
rs 8.5706
1
<?php
2
3
/**
4
 * For the full copyright and license information, please view
5
 * the LICENSE file that was distributed with this source code.
6
 */
7
8
declare(strict_types=1);
9
10
namespace loophp\phposinfo;
11
12
use Exception;
13
use loophp\phposinfo\Enum\Family;
14
use loophp\phposinfo\Enum\FamilyName;
15
use loophp\phposinfo\Enum\Os;
16
use loophp\phposinfo\Enum\OsName;
17
18
use function define;
19
use function defined;
20
use function is_string;
21
22
use const PHP_OS;
23
use const PHP_OS_FAMILY;
24
25
final class OsInfo implements OsInfoInterface
26
{
27 1
    public static function arch(): string
28
    {
29 1
        return php_uname('m');
30
    }
31
32 3
    public static function family(): string
33
    {
34 3
        return sprintf('%s', FamilyName::value(Family::key(self::detectFamily())));
35
    }
36
37 1
    public static function hostname(): string
38
    {
39 1
        return php_uname('n');
40
    }
41
42 1
    public static function isApple(): bool
43
    {
44 1
        return self::isFamily(Family::DARWIN);
45
    }
46
47 1
    public static function isBSD(): bool
48
    {
49 1
        return self::isFamily(Family::BSD);
50
    }
51
52 1
    public static function isFamily($family): bool
53
    {
54 1
        $detectedFamily = self::detectFamily();
55
56 1
        if (true === is_string($family)) {
57 1
            $family = self::normalizeConst($family);
58
59 1
            if (false === Family::has($family)) {
60 1
                return false;
61
            }
62
63 1
            $family = Family::value($family);
64
        }
65
66 1
        return $detectedFamily === $family;
67
    }
68
69 1
    public static function isOs($os): bool
70
    {
71 1
        $detectedOs = self::detectOs();
72
73 1
        if (true === is_string($os)) {
74 1
            $os = self::normalizeConst($os);
75
76 1
            if (false === Os::has($os)) {
77 1
                return false;
78
            }
79
80 1
            $os = Os::value($os);
81
        }
82
83 1
        return $detectedOs === $os;
84
    }
85
86 1
    public static function isUnix(): bool
87
    {
88 1
        return self::isFamily(Family::LINUX);
89
    }
90
91 1
    public static function isWindows(): bool
92
    {
93 1
        return self::isFamily(Family::WINDOWS);
94
    }
95
96 2
    public static function os(): string
97
    {
98 2
        return sprintf('%s', OsName::value(Os::key(self::detectOs())));
99
    }
100
101 1
    public static function register(): void
102
    {
103 1
        $family = self::family();
104 1
        $os = self::os();
105
106 1
        if (false === defined('PHP_OS_FAMILY')) {
107
            define('PHP_OS_FAMILY', $family);
108
        }
109
110 1
        if (false === defined('PHP_OS')) {
111
            define('PHP_OS', $os);
112
        }
113
114 1
        if (false === defined('PHPOSINFO_OS_FAMILY')) {
115 1
            define('PHPOSINFO_OS_FAMILY', $family);
116
        }
117
118 1
        if (false === defined('PHPOSINFO_OS')) {
119 1
            define('PHPOSINFO_OS', $os);
120
        }
121 1
    }
122
123 1
    public static function release(): string
124
    {
125 1
        return php_uname('r');
126
    }
127
128 1
    public static function uuid(): ?string
129
    {
130 1
        $uuidGenerator = 'shell_exec';
131 1
        $uuidCommand = null;
132
133 1
        switch (self::family()) {
134 1
            case FamilyName::LINUX:
135
                // phpcs:disable
136 1
                $uuidCommand = '( cat /var/lib/dbus/machine-id /etc/machine-id 2> /dev/null || hostname ) | head -n 1 || :';
137
                // phpcs:enable
138
139 1
                break;
140
            case FamilyName::DARWIN:
141
                $uuidCommand = 'ioreg -rd1 -c IOPlatformExpertDevice | grep IOPlatformUUID';
142
                $uuidGenerator = static function (string $command) use ($uuidGenerator): ?string {
143
                    $output = $uuidGenerator($command);
144
                    $uuid = null;
145
146
                    if (null !== $output) {
147
                        $parts = explode('=', str_replace('"', '', $output));
148
                        $uuid = strtolower(trim($parts[1]));
149
                    }
150
151
                    return $uuid;
152
                };
153
154
                break;
155
            case FamilyName::WINDOWS:
156
                // phpcs:disable
157
                $uuidCommand = '%windir%\\System32\\reg query "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography" /v MachineGuid';
158
                // phpcs:enable
159
160
                break;
161
            case FamilyName::BSD:
162
                $uuidCommand = 'kenv -q smbios.system.uuid';
163
164
                break;
165
166
            default:
167
                $uuidGenerator = static function (?string $command): ?string {
168
                    return $command;
169
                };
170
        }
171
172 1
        return null !== $uuidCommand ? $uuidGenerator($uuidCommand) : null;
173
    }
174
175 1
    public static function version(): string
176
    {
177 1
        return php_uname('v');
178
    }
179
180
    /**
181
     * @throws Exception
182
     */
183 3
    private static function detectFamily(?int $os = null): int
184
    {
185 3
        $os = $os ?? self::detectOs();
186
187
        // Get the last 4 bits.
188 3
        $family = $os - (($os >> 16) << 16);
189
190 3
        if (true === Family::isValid($family)) {
191 3
            return $family;
192
        }
193
194
        if (true === defined(PHP_OS_FAMILY)) {
195
            $phpOsFamily = self::normalizeConst(PHP_OS_FAMILY);
196
197
            if (true === Family::has($phpOsFamily)) {
198
                return (int) Family::value($phpOsFamily);
199
            }
200
        }
201
202
        throw self::errorMessage();
203
    }
204
205
    /**
206
     * @throws Exception
207
     */
208 3
    private static function detectOs(): int
209
    {
210 3
        foreach ([php_uname('s'), PHP_OS] as $os) {
211 3
            $os = self::normalizeConst($os);
212
213 3
            if (true === Os::has($os)) {
214 3
                return (int) Os::value($os);
215
            }
216
        }
217
218
        throw self::errorMessage();
219
    }
220
221
    /**
222
     * @throws Exception
223
     */
224
    private static function errorMessage(): Exception
225
    {
226
        $uname = php_uname();
227
        $os = php_uname('s');
228
229
        $message = <<<EOF
230
            Unable to find a proper information for this operating system.
231
232
            Please open an issue on https://github.com/loophp/phposinfo and attach the
233
            following information so I can update the library:
234
235
            ---8<---
236
            php_uname(): {$uname}
237
            php_uname('s'): {$os}
238
            --->8---
239
240
            Thanks.
241
242
            EOF;
243
244
        throw new Exception($message);
245
    }
246
247 3
    private static function normalizeConst(string $name): string
248
    {
249 3
        return strtoupper(
250 3
            str_replace('-.', '', (string) preg_replace('/[^a-zA-Z0-9]/', '', $name))
251
        );
252
    }
253
}
254