• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mimmi20 / device-detector-factory / 21544425640

31 Jan 2026 12:23PM UTC coverage: 94.595% (-5.4%) from 100.0%
21544425640

push

github

web-flow
Merge pull request #667 from mimmi20/dependabot/composer/production-dependencies-b703e661c4

composer (master)(deps): update matomo/device-detector requirement from ^6.4.8 to ^6.5.0 in the production-dependencies group

2 of 4 new or added lines in 1 file covered. (50.0%)

35 of 37 relevant lines covered (94.59%)

3.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.86
/src/DeviceDetectorFactory.php
1
<?php
2

3
/**
4
 * This file is part of the mimmi20/device-detector-factory package.
5
 *
6
 * Copyright (c) 2022-2026, Thomas Mueller <mimmi20@live.de>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types = 1);
13

14
namespace Mimmi20\Detector;
15

16
use DeviceDetector\Cache\PSR16Bridge;
17
use DeviceDetector\Cache\PSR6Bridge;
18
use DeviceDetector\ClientHints;
19
use DeviceDetector\DeviceDetector;
20
use Laminas\Http\Header\HeaderInterface;
21
use Laminas\Http\Headers;
22
use Laminas\Http\PhpEnvironment\Request;
23
use Laminas\ServiceManager\Exception\ServiceNotCreatedException;
24
use Laminas\ServiceManager\Factory\FactoryInterface;
25
use Override;
26
use Psr\Cache\CacheItemPoolInterface;
27
use Psr\Container\ContainerExceptionInterface;
28
use Psr\Container\ContainerInterface;
29
use Psr\SimpleCache\CacheInterface;
30
use Throwable;
31

32
use function assert;
33

34
final class DeviceDetectorFactory implements FactoryInterface
35
{
36
    /**
37
     * @param array<mixed>|null $options
38
     * @phpstan-param array<mixed>|null $options
39
     *
40
     * @throws ServiceNotCreatedException
41
     *
42
     * @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter.UnusedParameter
43
     */
44
    #[Override]
11✔
45
    public function __invoke(
46
        ContainerInterface $container,
47
        string $requestedName,
48
        array | null $options = null,
49
    ): DeviceDetector {
50
        try {
51
            $request = $container->get('Request');
11✔
52
        } catch (ContainerExceptionInterface $e) {
2✔
53
            throw new ServiceNotCreatedException($e->getMessage(), $e->getCode(), $e);
2✔
54
        }
55

56
        assert($request instanceof Request);
9✔
57

58
        try {
59
            $detector = new DeviceDetector();
8✔
NEW
60
        } catch (Throwable $e) {
×
NEW
61
            throw new ServiceNotCreatedException($e->getMessage(), (int) $e->getCode(), $e);
×
62
        }
63

64
        $headers = $request->getHeaders();
8✔
65
        assert($headers instanceof Headers);
8✔
66

67
        if ($headers->has('user-agent')) {
7✔
68
            $uaHader = $headers->get('user-agent');
4✔
69
            assert($uaHader instanceof HeaderInterface);
4✔
70
            $detector->setUserAgent($uaHader->getFieldValue());
3✔
71
        }
72

73
        $clientHints = ClientHints::factory($headers->toArray());
6✔
74
        $detector->setClientHints($clientHints);
6✔
75

76
        try {
77
            $config = $container->get(ConfigInterface::class);
6✔
78
        } catch (ContainerExceptionInterface $e) {
2✔
79
            throw new ServiceNotCreatedException($e->getMessage(), $e->getCode(), $e);
2✔
80
        }
81

82
        assert($config instanceof ConfigInterface);
4✔
83

84
        $cacheStorage = $config->getCache();
3✔
85

86
        if ($cacheStorage instanceof CacheInterface) {
3✔
87
            $detector->setCache(new PSR16Bridge($cacheStorage));
1✔
88
        } elseif ($cacheStorage instanceof CacheItemPoolInterface) {
2✔
89
            $detector->setCache(new PSR6Bridge($cacheStorage));
1✔
90
        }
91

92
        $detector->discardBotInformation($config->discardBotInformation());
3✔
93
        $detector->skipBotDetection($config->skipBotDetection());
3✔
94

95
        return $detector;
3✔
96
    }
97
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc