Issues (11)

src/Data/Xml.php (3 issues)

1
<?php
2
/**
3
 * extend DOMDocument to use framework xml configuration files
4
 *
5
 * @package     BlueData
6
 * @subpackage  Data
7
 * @author      MichaƂ Adamiak    <[email protected]>
8
 * @copyright   bluetree-service
9
 */
10
namespace BlueData\Data;
11
12
use DOMDocument;
13
use DOMNodeList;
14
use DomElement;
15
16
class Xml extends DOMDocument
17
{
18
    /**
19
     * node type
20
     * ELEMENT_NODE                 (1) element
21
     * ATTRIBUTE_NODE               (2) attribute
22
     * TEXT_NODE                    (3) text node (element or attribute)
23
     * CDATA_SECTION_NODE           (4) CDATA section
24
     * ENTITY_REFERENCE_NODE        (5) entity reference
25
     * ENTITY_NODE                  (6) entity
26
     * PROCESSING_INSTRUCTION_NODE  (7) process instruction
27
     * COMMENT_NODE                 (8) comment
28
     * DOCUMENT_NODE                (9) main document element
29
     * @var integer
30
     */
31
    public $nodeType;
32
33
    /**
34
     * error information
35
     * @var string
36
     */
37
    public $error;
38
39
    /**
40
     * last free id
41
     * @var string
42
     */
43
    protected $idList;
44
45
    /**
46
     * default constructor options
47
     *
48
     * @var array
49
     */
50
    protected $options = [
51
        'version' => '1.0',
52
        'encoding' => 'UTF-8'
53
    ];
54
55
    /**
56
     * start DOMDocument, optionally create new document
57
     *
58
     * @param array $options
59
     */
60 12
    public function __construct(array $options = [])
61
    {
62 12
        $this->options = array_merge($this->options, $options);
63
64 12
        parent::__construct(
65 12
            $this->options['version'],
66 12
            $this->options['encoding']
67 12
        );
68 12
    }
69
70
    /**
71
     * load xml file, optionally check file DTD
72
     *
73
     * @param string $path xml file path
74
     * @param boolean $parse if true will check file DTD
75
     * @return boolean
76
     * @example loadXmlFile('cfg/config.xml', true)
77
     */
78 7
    public function loadXmlFile($path, $parse = false)
79
    {
80 7
        $this->preserveWhiteSpace = false;
81 7
        $bool = file_exists($path);
82
83 7
        if (!$bool) {
84 1
            $this->error = 'file_not_exists';
85 1
            return false;
86
        }
87
88 6
        $bool = @$this->load($path);
89 6
        if (!$bool) {
90 1
            $this->error = 'loading_file_error';
91 1
            return false;
92
        }
93
94 5
        if ($parse && !@$this->validate()) {
95 1
            $this->error = 'parse_file_error';
96 1
            return false;
97
        }
98
99 4
        return true;
100
    }
101
102
    /**
103
     * save xml file, optionally will return as string
104
     *
105
     * @param string $path xml file path
106
     * @return string|boolean
107
     *
108
     * @example saveXmlFile('path/filename.xml'); save to file
109
     * @example saveXmlFile() will return as simple text
110
     */
111 3
    public function saveXmlFile($path = '')
112
    {
113 3
        $this->formatOutput = true;
114
115 3
        if ($path) {
116 2
            $bool = @$this->save($path);
117 2
            if (!$bool) {
118 1
                $this->error = 'save_file_error';
119 1
                return false;
120
            }
121
122 1
            return true;
123
        }
124
125 1
        return $this->saveXML();
126
    }
127
128
    /**
129
     * search for all nodes with given attribute
130
     * return list of nodes with attribute value as key
131
     *
132
     * @param DOMNodeList $node
133
     * @param string $value attribute value to search
134
     * @param array|boolean $list list of find nodes for recurrence
135
     * @return array
136
     */
137 1
    protected function searchByAttributeRecurrent(
138
        DOMNodeList $node,
139
        $value,
140
        array $list = []
141
    ) {
142
        /** @var DomElement $child */
143 1
        foreach ($node as $child) {
144 1
            if ($child->nodeType === 1) {
145 1
                if ($child->hasChildNodes()) {
146 1
                    $list = $this->searchByAttributeRecurrent(
147 1
                        $child->childNodes,
148 1
                        $value,
149
                        $list
150 1
                    );
151 1
                }
152
153 1
                $attribute = $child->getAttribute($value);
154 1
                if ($attribute) {
155 1
                    $list[$attribute] = $child;
156 1
                }
157 1
            }
158 1
        }
159
160 1
        return $list;
161
    }
162
163
    protected function processNode()
164
    {
165
        if ($child->hasChildNodes()) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $child seems to be never defined.
Loading history...
166
            $list = $this->searchByAttributeRecurrent(
167
                $child->childNodes,
168
                $value,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $value seems to be never defined.
Loading history...
169
                $list
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $list seems to be never defined.
Loading history...
170
            );
171
        }
172
173
        $attribute = $child->getAttribute($value);
174
        if ($attribute) {
175
            $list[$attribute] = $child;
176
        }
177
    }
178
179
    /**
180
     * search node for elements that contains element with give attribute
181
     *
182
     * @param DOMNodeList $node
183
     * @param string $value attribute value to search
184
     * @return array
185
     */
186 1
    public function searchByAttribute(DOMNodeList $node, $value)
187
    {
188 1
        return $this->searchByAttributeRecurrent($node, $value);
189
    }
190
191
    /**
192
     * check that element with given id exists
193
     *
194
     * @param string $elementId
195
     * @return boolean return true if exists
196
     */
197 1
    public function checkId($elementId)
198
    {
199 1
        return (bool)$this->getElementById($elementId);
200
    }
201
202
    /**
203
     * shorter version to return element with given id
204
     *
205
     * @param string $elementId
206
     * @return DOMElement
207
     */
208 1
    public function getId($elementId)
209
    {
210 1
        return $this->getElementById($elementId);
211
    }
212
213
    /**
214
     * check that Xml object has error
215
     *
216
     * @return bool
217
     */
218 8
    public function hasErrors()
219
    {
220 8
        if ($this->error) {
221 4
            return true;
222
        }
223
224 5
        return false;
225
    }
226
227
    /**
228
     * clear error information
229
     *
230
     * @return Xml
231
     */
232 1
    public function clearErrors()
233
    {
234 1
        $this->error = null;
235 1
        return $this;
236
    }
237
238
    /**
239
     * return error code
240
     *
241
     * @return string
242
     */
243 4
    public function getError()
244
    {
245 4
        return $this->error;
246
    }
247
248
    /**
249
     * return xml string
250
     *
251
     * @return bool|string
252
     */
253 1
    public function __toString()
254
    {
255 1
        return (string)$this->saveXmlFile();
256
    }
257
}
258