Completed
Push — master ( 7e830d...06fe07 )
by Saurabh
01:08
created

XmlConstruct::isJson()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace Sausin\XmlConstruct;
4
5
use XMLWriter;
6
use JsonSerializable;
7
use BadFunctionCallException;
8
9
/**
10
 * Credit goes to the commenters on php.net for the basic structure of this.
11
 * @see http://php.net/manual/en/ref.xmlwriter.php
12
 */
13
class XmlConstruct extends XMLWriter
14
{
15
    protected $separator;
16
17
    /**
18
     * Constructor.
19
     *
20
     * @param  string $rootElementName
21
     * @param  string $separator
22
     */
23
    public function __construct(string $rootElementName, string $separator = '|')
24
    {
25
        $this->openMemory();
26
        $this->setIndent(true);
27
        $this->setIndentString('  ');
28
        $this->startDocument('1.0', 'UTF-8');
29
30
        $this->startElement($rootElementName);
31
        $this->separator = $separator;
32
    }
33
34
    /**
35
     * Construct elements and texts from an array. The array should contain an
36
     * attribute's name in index part and a attribute's text in value part.
37
     *
38
     * @param  array  $prmArray Contains values
39
     * @return XmlConstruct
40
     */
41
    public function fromArray(array $prmArray): XmlConstruct
42
    {
43
        foreach ($prmArray as $key => $val) {
44
            if (is_array($val)) {
45
                if (is_numeric($key)) {
46
                    // numeric keys aren't allowed so we'll skip the key
47
                    $this->fromArray($val);
48
                } else {
49
                    $this->writeKey($key);
50
51
                    $this->fromArray($val);
52
                    $this->endElement();
53
                }
54
            } else {
55
                $this->setElement($key, $val);
56
            }
57
        }
58
59
        return $this;
60
    }
61
62
    /**
63
     * Construct elements and texts from a json string.
64
     *
65
     * @param  string $jsonString
66
     * @return XmlConstruct
67
     */
68
    public function fromJson(string $jsonString): XmlConstruct
69
    {
70
        if (! $this->isJson($jsonString)) {
71
            throw new UnexpectedValueException('Invalid string provided');
72
        }
73
74
        return $this->fromArray(json_decode($jsonString, true));
75
    }
76
77
    /**
78
     * Construct elements and texts from a json string.
79
     *
80
     * @param  JsonSerializable $jsonObject
81
     * @return XmlConstruct
82
     */
83
    public function fromJsonSerializable(JsonSerializable $jsonObject): XmlConstruct
84
    {
85
        return $this->fromArray(json_decode(json_encode($jsonObject), true));
86
    }
87
88
    /**
89
     * Return the content of a current xml document.
90
     *
91
     * @return string XML document
92
     */
93
    public function getDocument(): string
94
    {
95
        $this->endElement();
96
        $this->endDocument();
97
98
        return $this->outputMemory();
99
    }
100
101
    /**
102
     * Write a key.
103
     *
104
     * @param  string $key
105
     * @return void|BadFunctionCallException
106
     */
107
    protected function writeKey(string $key)
108
    {
109
        if (mb_strpos($key, $this->separator)) {
110
            $pieces = explode($this->separator, $key);
111
112
            // begin the element
113
            $this->startElement(array_shift($pieces));
114
115
            if (count($pieces) % 2 === 1) {
116
                throw new BadFunctionCallException('Invalid attribute pair at '.end($pieces));
117
            }
118
119
            // write the attributes
120
            foreach (array_chunk($pieces, 2) as list($attr, $val)) {
121
                $this->writeAttribute($attr, $val);
122
            }
123
        } else {
124
            // info($key);
125
            $this->startElement($key);
126
        }
127
    }
128
129
    /**
130
     * Set an element with a text to a current xml document.
131
     *
132
     * @param  string $name An element's name
133
     * @param  string $text An element's text
134
     * @return void|BadFunctionCallException
135
     */
136
    protected function setElement(string $name, string $text)
137
    {
138
        $this->writeKey($name);
139
140
        $this->text($text);
141
142
        $this->endElement();
143
    }
144
145
    /**
146
     * Check if provided string is Json string.
147
     *
148
     * @param  string  $string
149
     * @return boolean
150
     */
151
    protected function isJson(string $string): bool
152
    {
153
        json_decode($string);
154
        return (json_last_error() == JSON_ERROR_NONE);
155
    }
156
}
157