Completed
Pull Request — master (#59)
by Tobias
08:06
created

ClassDiscovery::getPuliFactory()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 9.488

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 18
ccs 3
cts 10
cp 0.3
rs 9.2
cc 4
eloc 9
nc 4
nop 0
crap 9.488
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
     * @var array
37
     */
38
    private static $cache = [];
39
40
    /**
41
     * Finds a class.
42
     *
43
     * @param $type
44 10
     *
45
     * @return string
46
     *
47
     * @throws NotFoundException
48
     */
49
    public static function findOneByType($type)
50
    {
51
        $exceptions = [];
52 21
53
        if (null !== $class = self::getFromCache($type)) {
54 21
            return $class;
55
        }
56
57
        foreach (self::$strategies as $strategy) {
58 21
            try {
59 21
                $bindings = call_user_func($strategy.'::find', $type);
60 21
            } catch (StrategyUnavailableException $e) {
61
                $exceptions[] = $e;
62
                continue;
63
            }
64
65 21
            foreach ($bindings as $binding) {
66
                if ($binding['condition']) {
67 21
                    if (!self::evaluateCondition($binding['condition'])) {
68 21
                        continue;
69 21
                    }
70
                }
71
72
                // save the result for later use
73
                self::storeInCache($type, $binding['class']);
74
75
                return $binding['class'];
76 9
            }
77
        }
78 9
79 9
        throw new DiscoveryFailedException('Could not find resource using any discovery strategy', $exceptions);
80 9
    }
81
82 9
    /**
83 9
     * Get a value from cache
84
     *
85 9
     * @param string $type
86
     *
87
     * @return string|null
88
     */
89
    private static function getFromCache($type)
90
    {
91
        if (isset(self::$cache[$type])) {
92
            return self::$cache[$type];
93
        }
94
95
        return null;
96
    }
97 8
98
    /**
99 8
     * Store a value in cache
100
     *
101 8
     * @param string $type
102 7
     * @param string $class
103 1
     */
104
    private static function storeInCache($type, $class)
105 1
    {
106 1
        self::$cache[$type] = $class;
107
    }
108
109
    /**
110
     * Evaulates conditions to boolean.
111 7
     *
112 1
     * @param mixed $condition
113
     *
114 1
     * @return bool
115
     */
116
    protected static function evaluateCondition($condition)
117
    {
118
        if (is_string($condition)) {
119
            // Should be extended for functions, extensions???
120
            return class_exists($condition);
121
        } elseif (is_callable($condition)) {
122
            return $condition();
123
        } elseif (is_bool($condition)) {
124
            return $condition;
125
        } elseif (is_array($condition)) {
126
            $evaluatedCondition = true;
127
128
            // Immediately stop execution if the condition is false
129
            for ($i = 0; $i < count($condition) && false !== $evaluatedCondition; ++$i) {
130
                $evaluatedCondition &= static::evaluateCondition($condition[$i]);
131
            }
132
133
            return $evaluatedCondition;
134 1
        }
135
136 1
        return false;
137
    }
138
}
139