Completed
Push — master ( 1772c3...f9e47a )
by Colin
01:50 queued 25s
created

Feature::registerResolver()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Vehikl\Flip;
4
5
/**
6
 * @method boolean enabled(...$params)
7
 */
8
abstract class Feature
9
{
10
    private static $resolver;
11
    protected $caller;
12
13
    // Maybe it's worth requiring an interface be applied?
14 34
    public function __construct($caller)
15
    {
16 34
        $this->caller = $caller;
17 34
    }
18
19 16
    public static function new($caller): Feature
20
    {
21 16
        return new static($caller);
22
    }
23
24
    abstract public function toggles(): array;
25
26 20
    public static function registerResolver($resolver)
27
    {
28 20
        self::$resolver = $resolver;
29 20
    }
30
31 24
    public function resolver()
32
    {
33 24
        if (! self::$resolver) {
34 18
            self::registerResolver(new DefaultResolver);
35
        }
36
37 24
        return self::$resolver;
38
    }
39
40 10
    public function hasToggle(string $method): bool
41
    {
42 10
        return array_key_exists($method, $this->toggles());
43
    }
44
45 8
    protected function caller()
46
    {
47 8
        return $this->caller;
48
    }
49
50 22
    private function methodToCall(string $toggle): string
51
    {
52 22
        $toggles = $this->toggles();
53
54 22
        if (array_key_exists($toggle, $toggles)) {
55
            // if $toggles was a class, it'd be a lot less error prone.
56 20
            return $this->resolver()->resolve($this, 'enabled') ? $toggles[$toggle]['on'] : $toggles[$toggle]['off'];
57
        }
58
59 8
        return $toggle;
60
    }
61
62 22
    public function __call($name, $arguments)
63
    {
64 22
        $methodToCall = $this->methodToCall($name);
65
66 22
        if (method_exists($this, $methodToCall)) {
67 20
            return $this->{$methodToCall}(...$arguments);
68
        }
69
70
        // Probably easier to just expect a public method.
71 8
        $name = (new \ReflectionClass($this->caller()))->getMethod($methodToCall);
72 4
        $name->setAccessible(true);
73
74 4
        return $name->invoke($this->caller(), $arguments);
75
    }
76
77 2
    public static function __callStatic($method, $arguments)
78
    {
79
        // Could be extracted, but I wonder how reliable this would be?
80
        // Does it really improve the API that much?
81 2
        $caller = Caller::guess();
82
83 2
        $instance = new static($caller);
84
85 2
        return $instance->{$method}($arguments);
86
    }
87
}
88