Completed
Pull Request — master (#59)
by Tobias
09:25
created

ClassDiscovery::getFromCache()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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