Passed
Push — master ( f8295f...487b9a )
by stéphane
02:46
created

Builder::buildDocument()   A

Complexity

Conditions 4
Paths 11

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4.074

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 11
nop 2
dl 0
loc 16
ccs 10
cts 12
cp 0.8333
crap 4.074
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
namespace Dallgoot\Yaml;
4
5
use Dallgoot\Yaml\Nodes\NodeGeneric;
6
use Dallgoot\Yaml\NodeList;
7
use Dallgoot\Yaml\Nodes\Root;
8
use Dallgoot\Yaml\Nodes\DocEnd;
9
use Dallgoot\Yaml\Nodes\DocStart;
10
11
/**
12
 * Constructs the result (YamlObject or array) according to every Nodes and their values
13
 *
14
 * @author  Stéphane Rebai <[email protected]>
15
 * @license Apache 2.0
16
 * @link    https://github.com/dallgoot/yaml
17
 */
18
final class Builder
19
{
20
    /** @var boolean */
21
    public $dateAsObject = false;
22
23
    private $_options;
24
    private $_debug = 0;
25
26
    const INVALID_DOCUMENT = "DOCUMENT %d is invalid,";
27
28 10
    public function __construct($options, $debug)
29
    {
30 10
        $this->_options = $options;
31 10
        $this->_debug = $debug;
32 10
    }
33
    /**
34
     * Builds a YAM content.  check multiple documents & split if more than one documents
35
     *
36
     * @param Root $root  The NodeRoot node
37
     *
38
     * @return array|YamlObject|null   list of documents or just one, null if appropriate debug lvl
39
     */
40 5
    public function buildContent(Root $root)
41
    {
42 5
        if ($this->_debug === 2) {
43 1
            print_r($root);
44 1
            return null;
45
        }
46 4
        $documents = [];
47 4
        $buffer = new NodeList();
48
        try {
49 4
            foreach ($root->value as $child) {
50 3
                if ($child instanceof DocEnd && $child !== $root->value->top()) {
51 1
                    $this->pushAndSave($child, $buffer, $documents);
52 3
                } elseif ($child instanceof DocStart) {
53 1
                    $this->saveAndPush($child, $buffer, $documents);
54
                } else {
55 3
                    $buffer->push($child);
56
                }
57
            }
58 3
            $documents[] = $this->buildDocument($buffer, count($documents) + 1);
59 1
        } catch (\Throwable $e) {
60 1
            throw new \Exception($e->getMessage(), 1, $e);
61
        }
62 3
        return count($documents) === 1 ? $documents[0] : $documents;
63
    }
64
65
    /**
66
     *  Builds the tree of Node (NodeList) for this document
67
     *
68
     * @param NodeList $list   the list of nodes that constitutes the current document
69
     * @param int      $docNum the index (starts @ 0) of this document in the whole YAML content provided to $this->buildContent
70
     *
71
     * @return YamlObject the YAML document as an object
72
     */
73 7
    public function buildDocument(NodeList &$list, int $docNum):YamlObject
74
    {
75 7
        $yamlObject = new YamlObject($this->_options);
76 7
        $rootNode   = new Root();
77 7
        $list->setIteratorMode(NodeList::IT_MODE_DELETE);
78
        try {
79 7
            foreach ($list as $child) {
80 6
                $rootNode->add($child);
81
            }
82 7
            if ($this->_debug === 3) {
83 1
                echo "Document #$docNum\n";
84 1
                print_r($rootNode);
85
            }
86 7
            return $rootNode->build($yamlObject);
87
        } catch (\Throwable $e) {
88
            throw new \ParseError(sprintf(self::INVALID_DOCUMENT, $docNum).':'.$e->getMessage(), 2, $e);
89
        }
90
    }
91
92 2
    public function pushAndSave(DocEnd $child, NodeList &$buffer, array &$documents)
93
    {
94 2
        $buffer->push($child);
95 2
        $documents[] = $this->buildDocument($buffer, count($documents) + 1);
96 2
        $buffer = new NodeList();
97 2
    }
98
99 2
    public function saveAndPush(DocStart $child, NodeList &$buffer, array &$documents)
100
    {
101 2
        if ($buffer->count() > 0 && $buffer->hasContent()) {
102 2
            $documents[] = $this->buildDocument($buffer, count($documents) + 1);
103 2
            $buffer = new NodeList($child);
104
        } else {
105 1
            $buffer->push($child);
106
        }
107 2
    }
108
109
110
}
111