Completed
Pull Request — master (#59)
by Tobias
11:53 queued 01:54
created

ClassDiscovery::getPuliDiscovery()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 6
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 11
ccs 7
cts 7
cp 1
crap 2
rs 9.4285
1
<?php
2
3
namespace Http\Discovery;
4
5
use Http\Discovery\Exception\DiscoveryFailedException;
6
use Http\Discovery\Exception\StrategyUnavailableException;
7
use Http\Discovery\Exception\NotFoundException;
8
use Http\Discovery\Strategy\DiactorosFactory;
9
use Http\Discovery\Strategy\GuzzleFactory;
10
use Http\Discovery\Strategy\HttpClients;
11
use Http\Discovery\Strategy\Puli;
12
13
/**
14
 * Registry that based find results on class existence.
15
 *
16
 * @author David de Boer <[email protected]>
17
 * @author Márk Sági-Kazár <[email protected]>
18
 * @author Tobias Nyholm <[email protected]>
19
 */
20
abstract class ClassDiscovery
21
{
22
    /**
23
     * A list of strategies to find classes.
24
     *
25
     * @var array
26
     */
27
    public static $strategies = [
28 10
        Puli::class,
29
        HttpClients::class,
30 10
        GuzzleFactory::class,
31
        DiactorosFactory::class,
32
    ];
33
34
    /**
35
     * Discovery cache to make the second time we use discovery faster.
36
     *
37
     * @var array
38
     */
39
    private static $cache = [];
40
41
    /**
42
     * Finds a class.
43
     *
44 10
     * @param $type
45
     *
46
     * @return string
47
     *
48
     * @throws NotFoundException
49
     */
50
    public static function findOneByType($type)
51
    {
52 21
        $exceptions = [];
53
54 21
        if (null !== $class = self::getFromCache($type)) {
55
            return $class;
56
        }
57
58 21
        foreach (self::$strategies as $strategy) {
59 21
            try {
60 21
                $bindings = call_user_func($strategy.'::find', $type);
61
            } catch (StrategyUnavailableException $e) {
62
                $exceptions[] = $e;
63
                continue;
64
            }
65 21
66
            foreach ($bindings as $binding) {
67 21
                if ($binding['condition']) {
68 21
                    if (!self::evaluateCondition($binding['condition'])) {
69 21
                        continue;
70
                    }
71
                }
72
73
                // save the result for later use
74
                self::storeInCache($type, $binding['class']);
75
76 9
                return $binding['class'];
77
            }
78 9
        }
79 9
80 9
        throw new DiscoveryFailedException('Could not find resource using any discovery strategy', $exceptions);
81
    }
82 9
83 9
    /**
84
     * Get a value from cache.
85 9
     *
86
     * @param string $type
87
     *
88
     * @return string|null
89
     */
90
    private static function getFromCache($type)
91
    {
92
        if (isset(self::$cache[$type])) {
93
            return self::$cache[$type];
94
        }
95
96
        return;
97 8
    }
98
99 8
    /**
100
     * Store a value in cache.
101 8
     *
102 7
     * @param string $type
103 1
     * @param string $class
104
     */
105 1
    private static function storeInCache($type, $class)
106 1
    {
107
        self::$cache[$type] = $class;
108
    }
109
110
    /**
111 7
     * Evaulates conditions to boolean.
112 1
     *
113
     * @param mixed $condition
114 1
     *
115
     * @return bool
116
     */
117
    protected static function evaluateCondition($condition)
118
    {
119
        if (is_string($condition)) {
120
            // Should be extended for functions, extensions???
121
            return class_exists($condition);
122
        } elseif (is_callable($condition)) {
123
            return $condition();
124
        } elseif (is_bool($condition)) {
125
            return $condition;
126
        } elseif (is_array($condition)) {
127
            $evaluatedCondition = true;
128
129
            // Immediately stop execution if the condition is false
130
            for ($i = 0; $i < count($condition) && false !== $evaluatedCondition; ++$i) {
131
                $evaluatedCondition &= static::evaluateCondition($condition[$i]);
132
            }
133
134 1
            return $evaluatedCondition;
135
        }
136 1
137
        return false;
138
    }
139
}
140