dd = $dd; } public function __toString(): string { if($this->dd->isBot()) { $botInfo = $this->dd->getBot(); return $botInfo['name'] ?? 'an unknown bot'; } $clientInfo = $this->dd->getClient(); if(empty($clientInfo['name'])) return 'an unknown browser'; $string = $clientInfo['name']; if(!empty($clientInfo['version'])) $string .= ' ' . $clientInfo['version']; $osInfo = $this->dd->getOs(); $hasOsInfo = !empty($osInfo['name']); $brandName = $this->dd->getBrandName(); $modelName = $this->dd->getModel(); $hasModelName = !empty($modelName); if($hasOsInfo || $hasModelName) $string .= ' on '; if($hasModelName) { $deviceName = trim($brandName . ' ' . $modelName); // most naive check in the world but it works well enough for this lol $firstCharIsVowel = in_array(strtolower($deviceName[0]), ['a', 'i', 'u', 'e', 'o']); $string .= ($firstCharIsVowel ? 'an' : 'a') . ' ' . $deviceName; } if($hasOsInfo) { if($hasModelName) $string .= ' running '; $string .= $osInfo['name']; if(!empty($osInfo['version'])) $string .= ' ' . $osInfo['version']; if(!empty($osInfo['platform'])) $string .= ' (' . $osInfo['platform'] . ')'; } return $string; } public static function parse(array|string $serverVarsOrUserAgent): self { if(is_string($serverVarsOrUserAgent)) { $userAgent = $serverVarsOrUserAgent; $clientHints = null; } else { $userAgent = array_key_exists('HTTP_USER_AGENT', $serverVarsOrUserAgent) ? $serverVarsOrUserAgent['HTTP_USER_AGENT'] : ''; $clientHints = ClientHints::factory($serverVarsOrUserAgent); } $dd = new DeviceDetector($userAgent, $clientHints); $dd->parse(); return new static($dd); } }