Completed
Pull Request — master (#2)
by Colin
02:06
created

Feature::container()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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