Completed
Push — master ( 4700f8...b32d7e )
by Tomasz
02:09
created

FallbackNormalizerContainer::getRoot()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 4
Ratio 100 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 4
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
namespace Thunder\Serializard\NormalizerContainer;
3
4
/**
5
 * @author Tomasz Kowalczyk <[email protected]>
6
 */
7
final class FallbackNormalizerContainer implements NormalizerContainerInterface
8
{
9
    private $handlers = array();
10
    private $interfaces = array();
11
    private $aliases = array();
12
13 20
    public function add($class, $handler)
14
    {
15 20
        if(false === is_callable($handler)) {
16 1
            throw new \RuntimeException(sprintf('Invalid handler for class %s!', $class));
17
        }
18
19 19
        if(class_exists($class)) {
20 15
            $this->aliases[$class] = $class;
21 15
            $this->handlers[$class] = $handler;
22 19
        } elseif(interface_exists($class)) {
23 3
            $this->aliases[$class] = $class;
24 3
            $this->interfaces[$class] = $handler;
25 3
        } else {
26 1
            throw new \RuntimeException(sprintf('Given value %s is neither class nor interface name!', $class));
27
        }
28 18
    }
29
30 2
    public function addAlias($alias, $class)
31
    {
32 2
        $handler = $this->getHandler($class);
33
34 2
        if(null === $handler) {
35 1
            throw new \RuntimeException(sprintf('Handler for class %s does not exist!', $class));
36
        }
37
38 1
        $this->handlers[$alias] = $handler;
39 1
        $this->aliases[$alias] = $this->aliases[$class];
40 1
    }
41
42 17
    public function getHandler($class)
43
    {
44 17
        if(array_key_exists($class, $this->handlers)) {
45 12
            return $this->handlers[$class];
46
        }
47
48 7
        $parents = array_intersect(array_keys($this->handlers), class_parents($class));
49 7
        if($parents) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $parents of type array<integer|string> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
50 2
            return $this->handlers[array_pop($parents)];
51
        }
52
53 5
        $interfaces = array_intersect(array_keys($this->interfaces), array_values(class_implements($class)));
54 5
        if($interfaces) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $interfaces of type array<integer|string> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
55 3
            if(count($interfaces) > 1) {
56 1
                throw new \RuntimeException(sprintf('Class %s implements interfaces with colliding handlers!', $class));
57
            }
58
59 2
            return $this->interfaces[array_shift($interfaces)];
60
        }
61
62 2
        return null;
63
    }
64
}
65