DiscoveryLocator   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 53
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 9
eloc 17
c 1
b 0
f 0
dl 0
loc 53
ccs 22
cts 22
cp 1
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A register() 0 5 1
A unregister() 0 10 1
A assertValidImplementation() 0 8 3
A locate() 0 9 4
1
<?php
2
declare(strict_types=1);
3
4
namespace Http\Factory\Discovery;
5
6
use InvalidArgumentException;
7
use RuntimeException;
8
9
abstract class DiscoveryLocator
10
{
11
    /** @var array  */
12
    protected static $candidates = [];
13
14
    /**
15
     * @throws RuntimeException If no implementation is available
16
     */
17 16
    public static function locate(string $interface): string
18
    {
19 16
        foreach (static::$candidates[$interface] ?? [] as $candidate) {
20 14
            if (class_exists($candidate) && is_subclass_of($candidate, $interface, true)) {
21 14
                return $candidate;
22
            }
23
        }
24
25 2
        throw new RuntimeException("$interface has no available implementations");
26
    }
27
28 11
    public static function register(string $interface, string $implementation): void
29
    {
30 11
        self::assertValidImplementation($interface, $implementation);
31
32 7
        array_unshift(static::$candidates[$interface], $implementation);
33 7
    }
34
35 11
    public static function unregister(string $interface, string $implementation): void
36
    {
37 11
        self::assertValidImplementation($interface, $implementation);
38
39 7
        static::$candidates[$interface] = array_diff(
40 7
            static::$candidates[$interface],
41 7
            [$implementation]
42
        );
43
44 7
        static::clearCache($interface);
45 7
    }
46
47
    /**
48
     * @throws InvalidArgumentException If the factory is not supported or the implementation is invalid
49
     */
50 15
    private static function assertValidImplementation(string $interface, string $implementation): void
51
    {
52 15
        if (! isset(static::$candidates[$interface])) {
53 4
            throw new InvalidArgumentException("$interface is not a supported factory");
54
        }
55
56 11
        if (! is_subclass_of($implementation, $interface, true)) {
57 4
            throw new InvalidArgumentException("$implementation does not implement $interface");
58
        }
59 7
    }
60
61
    abstract protected static function clearCache(?string $interface = null): void;
62
}
63