bot = $values['bot'] ?? null; $this->brand = $values['brand'] ?? ''; $this->client = $values['client'] ?? null; $this->device = $values['device'] ?? null; $this->model = $values['model'] ?? ''; $this->os = $values['os'] ?? null; // Or cached entries only use the useragents, so if we have some client hints provided, // We use some special parsers, which use the cached user agent result and parses it again using client hints if (!empty($clientHints) && !empty($values['client']['type']) && $values['client']['type'] === 'browser') { $browserParser = new CachedBrowserParser($userAgent, $clientHints); $browserParser->setCachedResult($this->client); $this->client = $browserParser->parse(); } if (!empty($clientHints)) { $osParser = new CachedOperatingSystemParser($userAgent, $clientHints); $osParser->setCachedResult($this->os); $this->os = $osParser->parse(); } } public static function getCached(string $userAgent): ?array { // we check if file exists and include the file here directly as it needs to be kind of atomic... // if we only checked if file exists, and then choose to use cached entry which would then include the file, // then there's a risk that between the file_exists and the include the cache file was removed $path = self::getCachePath($userAgent); $exists = file_exists($path); if ($exists) { $values = @include($path); if (!empty($values) && is_array($values) && isset($values['os'])) { return $values; } } return null; } public static function writeToCache(string $userAgent): ?string { if (self::getCached($userAgent)) { return null; // already cached } if (empty(self::$customCache)) { self::$customCache = StaticContainer::get('DeviceDetector\Cache\Cache'); } // we don't use device detector factory because this way we can cache the cache instance and // lower memory since the factory would store an instance of every user agent in a static variable $deviceDetector = new DeviceDetector($userAgent); $deviceDetector->discardBotInformation(); $deviceDetector->setCache(self::$customCache); $deviceDetector->parse(); $outputArray = [ 'bot' => $deviceDetector->getBot(), 'brand' => $deviceDetector->getBrandName(), 'client' => $deviceDetector->getClient(), 'device' => $deviceDetector->getDevice(), 'model' => $deviceDetector->getModel(), 'os' => $deviceDetector->getOs() ]; $outputPath = self::getCachePath($userAgent, true); $content = " $time) { if ($numFilesDeleted > $numFilesToDelete) { break; } else { Filesystem::deleteFileIfExists($file); $numFilesDeleted++; } } } }