[a-z0-9.+-]+) \((?P\S+).*?; PHP (?P[0-9.]+)[^;]*(?:; (?Pstreams|curl [0-9.]+)[^;]*)?(?P; CI)?#i', $userAgent, $matches)) { if ($matches['composer'] === 'source' || preg_match('{^[a-f0-9]{40}$}', $matches['composer'])) { $matches['composer'] = 'pre-1.8.5'; } $this->composerVersion = preg_replace('{\+[a-f0-9]{40}}', '', $matches['composer']); $this->phpVersion = $matches['php']; $this->os = preg_replace('{^cygwin_nt-.*}', 'cygwin', strtolower($matches['os'])); $this->httpVersion = $matches['http'] ?? null; $this->ci = (bool) ($matches['ci'] ?? null); } } public function getComposerVersion(): ?string { return $this->composerVersion; } public function getPhpVersion(): ?string { return $this->phpVersion; } public function getOs(): ?string { return $this->os; } public function getHttpVersion(): ?string { return $this->httpVersion; } public function getCI(): ?bool { return $this->ci; } }