Passed
Push — dev ( 0679fe...0efacf )
by Fike
05:23
created

Locator::locate()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 7.0099

Importance

Changes 0
Metric Value
cc 7
eloc 16
nc 6
nop 3
dl 0
loc 23
ccs 16
cts 17
cp 0.9412
crap 7.0099
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
namespace AmaTeam\TreeAccess;
4
5
use AmaTeam\TreeAccess\API\Exception\IllegalTargetException;
6
use AmaTeam\TreeAccess\API\Exception\MissingNodeException;
7
use AmaTeam\TreeAccess\API\NodeInterface;
8
use AmaTeam\TreeAccess\Locator\Context;
9
use AmaTeam\TreeAccess\Type\Registry;
10
11
class Locator
12
{
13
    /**
14
     * @var Registry
15
     */
16
    private $registry;
17
18 21
    public function __construct(Registry $registry)
19
    {
20 21
        $this->registry = $registry;
21 21
    }
22
23
    /**
24
     * @param NodeInterface $root
25
     * @param array $path
26
     * @param Context $context
27
     *
28
     * @return NodeInterface|null
29
     *
30
     * @throws MissingNodeException
31
     * @throws IllegalTargetException
32
     */
33 19
    public function locate(NodeInterface $root, array $path, Context $context)
34
    {
35 19
        $currentPath = [];
36 19
        $cursor = $root;
37 19
        foreach ($path as $segment) {
38 14
            $currentPath[] = $segment;
39 14
            $value = &$cursor->getValue();
40 14
            $accessor = $this->registry->getAccessor(gettype($value));
41 14
            if (!$accessor) {
42 1
                if ($context->shouldIgnoreIllegal()) {
43
                    return null;
44
                }
45 1
                throw new IllegalTargetException($currentPath);
46
            }
47 13
            if (!$accessor || !$accessor->exists($value, $segment)) {
48 3
                if ($context->shouldIgnoreMissing()) {
49 2
                    return null;
50
                }
51 1
                throw new MissingNodeException($currentPath);
52
            }
53 10
            $cursor = $accessor->read($value, $segment);
54
        }
55 15
        return Node::withPath($cursor, $path);
56
    }
57
}
58