Passed
Push — master ( 5988e7...23b4c3 )
by stéphane
02:08
created

NodeHandlers::onHyphen()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 20
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 16
nc 5
nop 2
dl 0
loc 20
rs 9.1111
c 0
b 0
f 0
1
<?php
2
3
namespace Dallgoot\Yaml;
4
5
use Dallgoot\Yaml\{Yaml as Y, Regex as R};
6
7
/**
8
 *
9
 * @author  Stéphane Rebai <[email protected]>
10
 * @license Apache 2.0
11
 * @link    TODO : url to specific online doc
12
 */
13
final class NodeHandlers
14
{
15
16
    public static function onQuoted($nodeValue, Node $node)
17
    {
18
        $node->type = R::isProperlyQuoted($nodeValue) ? Y::QUOTED : Y::PARTIAL;
19
        $node->value = $nodeValue;
20
    }
21
22
    public static function onSetElement($nodeValue, Node $node)
23
    {
24
        $node->type = $nodeValue[0] === '?' ? Y::SET_KEY : Y::SET_VALUE;
25
        $v = trim(substr($nodeValue, 1));
26
        if (!empty($v)) {
27
            $node->value = new NodeList(new Node($v, $node->line));
28
        }
29
    }
30
31
    /**
32
     * Process when a "key: value" syntax is found in the parsed string
33
     * Note : key is match 1, value is match 2 as per regex from R::KEY
34
     *
35
     * @param array $matches The matches provided by 'preg_match' function in Node::parse
36
     */
37
    public static function onKey(array $matches, Node $node)
38
    {
39
        $node->type = Y::KEY;
40
        $node->identifier = trim($matches[1], '"\' ');
41
        $value = isset($matches[2]) ? trim($matches[2]) : null;
42
        if (!empty($value)) {
43
            $hasComment = strpos($value, ' #');
44
            if (is_bool($hasComment)) {
45
                $n = new Node($value, $node->line);
46
            } else {
47
                $n = new Node(trim(substr($value, 0, $hasComment)), $node->line);
48
                if ($n->type !== Y::PARTIAL) {
49
                    $comment = new Node(trim(substr($value, $hasComment + 1)), $node->line);
50
                    $comment->identifier = true; //to specify it is NOT a fullline comment
51
                    $node->add($comment);
52
                }
53
            }
54
            $n->indent = $node->indent + strlen($node->identifier);
55
            $node->add($n);
56
        }
57
    }
58
59
    /**
60
     * Determines the correct type and value when a compact object/array syntax is found
61
     *
62
     * @param string $value The value assumed to start with { or [ or characters
63
     *
64
     * @see Node::identify
65
     */
66
    public static function onCompact($value, Node $node)
67
    {
68
        $node->value = json_decode($value, false, 512, JSON_PARTIAL_OUTPUT_ON_ERROR|JSON_UNESCAPED_SLASHES);
69
        if (json_last_error() === JSON_ERROR_NONE){
70
            $node->type = Y::JSON;
71
            return;
72
        }
73
        $node->value = new NodeList();
74
        if (preg_match(R::MAPPING, $value)){
75
            $node->type = Y::COMPACT_MAPPING;
76
            $node->value->type = Y::COMPACT_MAPPING;
77
            preg_match_all(R::MAPPING_VALUES, trim(substr($value, 1,-1)), $matches);
78
            foreach ($matches['k'] as $index => $property) {
79
                $n = new Node('', $node->line);
80
                $n->type = Y::KEY;
81
                $n->identifier = trim($property, '"\' ');//TODO : maybe check for proper quoting first ?
82
                $n->value = new Node($matches['v'][$index], $node->line);
83
                $node->value->push($n);
84
            }
85
            return;
86
        }
87
        if (preg_match(R::SEQUENCE, $value)){
88
            $node->type = Y::COMPACT_SEQUENCE;
89
            $node->value->type = Y::COMPACT_SEQUENCE;
90
            preg_match_all(R::SEQUENCE_VALUES, trim(substr($value, 1,-1)), $matches);
91
            foreach ($matches['item'] as $key => $item) {
92
                $i = new Node('', $node->line);
93
                $i->type = Y::ITEM;
94
                $i->add(new Node($item, $node->line));
95
                $node->value->push($i);
96
            }
97
            return;
98
        }
99
        $node->value = $value;
100
        $node->type  = Y::PARTIAL;
101
    }
102
103
    /**
104
     * Determines type and value when an hyphen "-" is found
105
     *
106
     * @param string $nodeValue The node value
107
     *
108
     * @see Node::identify
109
     */
110
    public static function onHyphen($nodeValue, Node $node)
111
    {
112
        if (substr($nodeValue, 0, 3) === '---') {
113
            $node->type = Y::DOC_START;
114
            $rest = trim(substr($nodeValue, 3));
115
            if (!empty($rest)) {
116
                $n = new Node($rest, $node->line);
117
                $n->indent = $node->indent + 4;
118
                $node->value = $n->setParent($node);
119
            }
120
        } elseif (preg_match(R::ITEM, $nodeValue, $matches)) {
121
            $node->type = Y::ITEM;
122
            if (isset($matches[1]) && !empty(trim($matches[1]))) {
123
                $n = new Node(trim($matches[1]), $node->line);
124
                $n->indent = $node->indent + 2;
125
                $node->value = $n->setParent($node);
126
            }
127
        } else {
128
            $node->type  = Y::SCALAR;
129
            $node->value = $nodeValue;
130
        }
131
    }
132
133
    /**
134
     * Determines the type and value according to $nodeValue when one of these characters is found : !,&,*
135
     *
136
     * @param string $nodeValue The node value
137
     *
138
     * @see  Node::identify
139
     * @todo handle tags like  <tag:clarkevans.com,2002:invoice>
140
     */
141
    public static function onNodeAction($nodeValue, Node $node)
142
    {
143
        $v = substr($nodeValue, 1);
144
        $node->type = ['!' => Y::TAG, '&' => Y::REF_DEF, '*' => Y::REF_CALL][$nodeValue[0]];
145
        $node->identifier = $v;
146
        $pos = strpos($v, ' ');
147
        if ($node->type & (Y::TAG|Y::REF_DEF) && is_int($pos)) {
148
            $node->identifier = strstr($v, ' ', true);
149
            $value = trim(substr($nodeValue, $pos + 1));
150
            $value = R::isProperlyQuoted($value) ? trim($value, "\"'") : $value;
151
            $node->add((new Node($value, $node->line))->setParent($node));
152
        }
153
    }
154
155
}