Passed
Push — master ( b48009...a47442 )
by Pol
02:39
created

Text::parse()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 11
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 22
ccs 10
cts 10
cp 1
crap 2
rs 9.9
1
<?php
2
3
declare(strict_types=1);
4
5
namespace loophp\phptree\Importer;
6
7
use loophp\phptree\Node\AttributeNode;
8
use loophp\phptree\Node\AttributeNodeInterface;
9
use loophp\phptree\Node\NodeInterface;
10
11
/**
12
 * Class Text.
13
 */
14
final class Text implements ImporterInterface
15
{
16
    /**
17
     * {@inheritdoc}
18
     */
19 2
    public function import($data): NodeInterface
20
    {
21 2
        return $this->parseNode(new AttributeNode(['label' => 'root']), $data);
22
    }
23
24
    /**
25
     * Create a node.
26
     *
27
     * @param string $label
28
     *   The node label
29
     *
30
     * @return AttributeNodeInterface
31
     *   The node
32
     */
33 2
    private function createNode(string $label): AttributeNodeInterface
34
    {
35 2
        return new AttributeNode([
36 2
            'label' => $label,
37
        ]);
38
    }
39
40
    /**
41
     * Parse a string into an array.
42
     *
43
     * @param string $subject
44
     *   The subject string
45
     *
46
     * @return array<string, mixed>
47
     *   The array
48
     */
49 2
    private function parse(string $subject): array
50
    {
51
        $result = [
52 2
            'value' => mb_substr($subject, 1, mb_strpos($subject, '[', 1) - 1),
53
            'children' => [],
54
        ];
55
56 2
        if (false === $nextBracket = mb_strpos($subject, '[', 1)) {
57 2
            return $result;
58
        }
59
60
        // Todo: Improve the regex.
61 2
        preg_match_all('#[^\[\]]+|\[(?<nested>(?R)*)]#', mb_substr($subject, $nextBracket, -1), $matches);
62
63 2
        $result['children'] = array_map(
64
            static function (string $match): string {
65 2
                return sprintf('[%s]', $match);
66 2
            },
67 2
            array_filter((array) $matches['nested'])
68
        );
69
70 2
        return $result;
71
    }
72
73
    /**
74
     * @param AttributeNodeInterface $parent
75
     * @param string ...$nodes
76
     *
77
     * @return \loophp\phptree\Node\NodeInterface
78
     */
79 2
    private function parseNode(AttributeNodeInterface $parent, string ...$nodes): NodeInterface
80
    {
81 2
        return array_reduce(
82 2
            $nodes,
83
            function (AttributeNodeInterface $carry, string $node): NodeInterface {
84 2
                $data = $this->parse($node);
85
86
                return $carry
87 2
                    ->add(
88 2
                        $this->parseNode(
89 2
                            $this->createNode($data['value']),
90 2
                            ...$data['children']
91
                        )
92
                    );
93 2
            },
94
            $parent
95
        );
96
    }
97
}
98