Completed
Pull Request — master (#77)
by Márk
13:41
created

HttplugFactory   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 1 Features 1
Metric Value
wmc 13
c 3
b 1
f 1
lcom 1
cbo 3
dl 0
loc 91
ccs 35
cts 35
cp 1
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B findOneByType() 0 22 4
A find() 0 6 1
C evaluateCondition() 0 22 7
1
<?php
2
3
namespace Http\HttplugBundle;
4
5
use Puli\Discovery\Api\Discovery;
6
use Puli\Discovery\Binding\ClassBinding;
7
use Webmozart\Expression\Expr;
8
9
/**
10
 * This class is a wrapper around Puli discovery.
11
 *
12
 * @author Márk Sági-Kazár <[email protected]>
13
 */
14
final class HttplugFactory
15
{
16
    /**
17
     * @var Discovery
18
     */
19
    private $discovery;
20
21
    /**
22
     * @param Discovery $discovery
23
     */
24 11
    public function __construct(Discovery $discovery)
25
    {
26 11
        $this->discovery = $discovery;
27 11
    }
28
29
    /**
30
     * Creates a class of type.
31
     *
32
     * @param string $type
33
     *
34
     * @return object
35
     */
36 11
    public function find($type)
37
    {
38 11
        $class = $this->findOneByType($type);
39
40 6
        return new $class();
41 1
    }
42
43
    /**
44
     * Finds a class of type and resolves optional dependency conditions.
45
     *
46
     * @param string $type
47
     *
48
     * @return string
49
     *
50
     * @throws \RuntimeException if no class is found.
51
     */
52 11
    private function findOneByType($type)
53
    {
54
        /** @var ClassBinding[] $bindings */
55 11
        $bindings = $this->discovery->findBindings(
56 11
            $type,
57 11
            Expr::isInstanceOf('Puli\Discovery\Binding\ClassBinding')
58 11
        );
59
60 11
        foreach ($bindings as $binding) {
61 11
            if ($binding->hasParameterValue('depends')) {
62 10
                $dependency = $binding->getParameterValue('depends');
63
64 10
                if (false === $this->evaluateCondition($dependency)) {
65 5
                    continue;
66
                }
67 5
            }
68
69 6
            return $binding->getClassName();
70 5
        }
71
72 5
        throw new \RuntimeException(sprintf('Class binding of type "%s" is not found', $type));
73
    }
74
75
    /**
76
     * Evaluates conditions to boolean.
77
     *
78
     * @param mixed $condition
79
     *
80
     * @return bool
81
     */
82 10
    protected function evaluateCondition($condition)
83
    {
84 10
        if (is_string($condition)) {
85
            // Should be extended for functions, extensions???
86 2
            return class_exists($condition);
87 8
        } elseif (is_callable($condition)) {
88 2
            return $condition();
89 6
        } elseif (is_bool($condition)) {
90 5
            return $condition;
91 4
        } elseif (is_array($condition)) {
92 3
            $evaluatedCondition = true;
93
94
            // Immediately stop execution if the condition is false
95 3
            while (count($condition) > 0 && $evaluatedCondition) {
96 3
                $evaluatedCondition = $this->evaluateCondition(array_shift($condition));
97 3
            }
98
99 3
            return $evaluatedCondition;
100
        }
101
102 1
        return false;
103
    }
104
}
105