DeviceDetectorFactory.php
67 lines
| 1 | <?php |
| 2 | |
| 3 | /** |
| 4 | * Matomo - free/libre analytics platform |
| 5 | * |
| 6 | * @link https://matomo.org |
| 7 | * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later |
| 8 | */ |
| 9 | namespace Piwik\DeviceDetector; |
| 10 | |
| 11 | use DeviceDetector\ClientHints; |
| 12 | use DeviceDetector\DeviceDetector; |
| 13 | use Piwik\Container\StaticContainer; |
| 14 | class DeviceDetectorFactory |
| 15 | { |
| 16 | protected static $deviceDetectorInstances = []; |
| 17 | /** |
| 18 | * Returns an instance of DeviceDetector for the given user agent. Uses template method pattern |
| 19 | * and calls getDeviceDetectionInfo() when it doesn't find a matching instance in the cache. |
| 20 | * @param string $userAgent |
| 21 | * @param array $clientHints |
| 22 | * @return DeviceDetector |
| 23 | */ |
| 24 | public function makeInstance($userAgent, array $clientHints = []) |
| 25 | { |
| 26 | $cacheKey = self::getNormalizedUserAgent($userAgent, $clientHints); |
| 27 | if (array_key_exists($cacheKey, self::$deviceDetectorInstances)) { |
| 28 | return self::$deviceDetectorInstances[$cacheKey]; |
| 29 | } |
| 30 | $deviceDetector = $this->getDeviceDetectionInfo($userAgent, $clientHints); |
| 31 | self::$deviceDetectorInstances[$cacheKey] = $deviceDetector; |
| 32 | return $deviceDetector; |
| 33 | } |
| 34 | public static function getNormalizedUserAgent($userAgent, array $clientHints = []) |
| 35 | { |
| 36 | $normalizedClientHints = ''; |
| 37 | if (is_array($clientHints) && count($clientHints)) { |
| 38 | $hints = ClientHints::factory($clientHints); |
| 39 | $brands = $hints->getBrandList(); |
| 40 | ksort($brands); |
| 41 | // we only take the (sorted) list of brand, os + version and model name into account, as the other values |
| 42 | // are actually not used and should not change the result |
| 43 | $normalizedClientHints = md5(json_encode($brands) . $hints->getOperatingSystem() . $hints->getOperatingSystemVersion() . $hints->getModel()); |
| 44 | } |
| 45 | return mb_substr($normalizedClientHints . trim($userAgent), 0, 500); |
| 46 | } |
| 47 | /** |
| 48 | * Creates a new DeviceDetector for the user agent. Called by makeInstance() when no matching instance |
| 49 | * was found in the cache. |
| 50 | * @param string $userAgent |
| 51 | * @param array $clientHints |
| 52 | * @return DeviceDetector |
| 53 | */ |
| 54 | protected function getDeviceDetectionInfo($userAgent, array $clientHints = []) |
| 55 | { |
| 56 | $deviceDetector = new DeviceDetector($userAgent, ClientHints::factory($clientHints)); |
| 57 | $deviceDetector->discardBotInformation(); |
| 58 | $deviceDetector->setCache(StaticContainer::get('DeviceDetector\\Cache\\Cache')); |
| 59 | $deviceDetector->parse(); |
| 60 | return $deviceDetector; |
| 61 | } |
| 62 | public static function clearInstancesCache() |
| 63 | { |
| 64 | self::$deviceDetectorInstances = []; |
| 65 | } |
| 66 | } |
| 67 |