Completed
Pull Request — master (#59)
by Tobias
16:15 queued 06:17
created

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