XMLConverter   A
last analyzed

Coupling/Cohesion

Components 1
Dependencies 1

Complexity

Total Complexity 13

Size/Duplication

Total Lines 237
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 237
ccs 48
cts 48
cp 1
rs 10
c 0
b 0
f 0
wmc 13
lcom 1
cbo 1

10 Methods

Rating   Name   Duplication   Size   Complexity  
A convert() 0 14 2
A recordToElementWithAttribute() 0 11 1
A recordToElement() 0 10 2
A fieldToElementWithAttribute() 0 7 1
A fieldToElement() 0 7 1
A rootElement() 0 7 1
A filterElementName() 0 4 1
A recordElement() 0 8 1
A filterAttributeName() 0 8 2
A fieldElement() 0 8 1
1
<?php
2
/**
3
* This file is part of the League.csv library
4
*
5
* @license http://opensource.org/licenses/MIT
6
* @link https://github.com/thephpleague/csv/
7
* @version 9.0.0
8
* @package League.csv
9
*
10
* For the full copyright and license information, please view the LICENSE
11
* file that was distributed with this source code.
12
*/
13
declare(strict_types=1);
14
15
namespace League\Csv;
16
17
use DOMAttr;
18
use DOMDocument;
19
use DOMElement;
20
use DOMException;
21
use Traversable;
22
23
/**
24
 * A class to convert CSV records into a DOMDOcument object
25
 *
26
 * @package League.csv
27
 * @since   9.0.0
28
 * @author  Ignace Nyamagana Butera <[email protected]>
29
 */
30
class XMLConverter
31
{
32
    use ValidatorTrait;
33
34
    /**
35
     * XML Root name
36
     *
37
     * @var string
38
     */
39
    protected $root_name = 'csv';
40
41
    /**
42
     * XML Node name
43
     *
44
     * @var string
45
     */
46
    protected $record_name = 'row';
47
48
    /**
49
     * XML Item name
50
     *
51
     * @var string
52
     */
53
    protected $field_name = 'cell';
54
55
    /**
56
     * XML column attribute name
57
     *
58
     * @var string
59
     */
60
    protected $column_attr = '';
61
62
    /**
63
     * XML offset attribute name
64
     *
65
     * @var string
66
     */
67
    protected $offset_attr = '';
68
69
    /**
70
     * Conversion method list
71
     *
72
     * @var array
73
     */
74
    protected $encoder = [
75
        'field' => [
76
            true => 'fieldToElementWithAttribute',
77
            false => 'fieldToElement',
78
        ],
79
        'record' => [
80
            true => 'recordToElementWithAttribute',
81
            false => 'recordToElement',
82
        ],
83
    ];
84
85
    /**
86
     * Convert an Record collection into a DOMDocument
87
     *
88
     * @param array|Traversable $records the CSV records collection
89
     *
90
     * @return DOMDocument
91
     */
92 2
    public function convert($records): DOMDocument
93
    {
94 2
        $field_encoder = $this->encoder['field']['' !== $this->column_attr];
95 2
        $record_encoder = $this->encoder['record']['' !== $this->offset_attr];
96 2
        $doc = new DOMDocument('1.0');
97 2
        $root = $doc->createElement($this->root_name);
98 2
        foreach ($this->filterIterable($records, __METHOD__) as $offset => $record) {
99 2
            $node = $this->{$record_encoder}($doc, $record, $field_encoder, $offset);
100 2
            $root->appendChild($node);
101
        }
102 2
        $doc->appendChild($root);
103
104 2
        return $doc;
105
    }
106
107
    /**
108
     * Convert a CSV record into a DOMElement and
109
     * adds its offset as DOMElement attribute
110
     *
111
     * @param DOMDocument $doc
112
     * @param array       $record        CSV record
113
     * @param string      $field_encoder CSV Cell encoder method name
114
     * @param int         $offset        CSV record offset
115
     *
116
     * @return DOMElement
117
     */
118 2
    protected function recordToElementWithAttribute(
119
        DOMDocument $doc,
120
        array $record,
121
        string $field_encoder,
122
        int $offset
123
    ): DOMElement {
124 2
        $node = $this->recordToElement($doc, $record, $field_encoder);
125 2
        $node->setAttribute($this->offset_attr, (string) $offset);
126
127 2
        return $node;
128
    }
129
130
    /**
131
     * Convert a CSV record into a DOMElement
132
     *
133
     * @param DOMDocument $doc
134
     * @param array       $record        CSV record
135
     * @param string      $field_encoder CSV Cell encoder method name
136
     *
137
     * @return DOMElement
138
     */
139 2
    protected function recordToElement(DOMDocument $doc, array $record, string $field_encoder): DOMElement
140
    {
141 2
        $node = $doc->createElement($this->record_name);
142 2
        foreach ($record as $node_name => $value) {
143 2
            $item = $this->{$field_encoder}($doc, $value, $node_name);
144 2
            $node->appendChild($item);
145
        }
146
147 2
        return $node;
148
    }
149
150
    /**
151
     * Convert Cell to Item.
152
     *
153
     * Convert the CSV item into a DOMElement and adds the item offset
154
     * as attribute to the returned DOMElement
155
     *
156
     * @param DOMDocument $doc
157
     * @param string      $value     Record item value
158
     * @param int|string  $node_name Record item offset
159
     *
160
     * @return DOMElement
161
     */
162 2
    protected function fieldToElementWithAttribute(DOMDocument $doc, string $value, $node_name): DOMElement
163
    {
164 2
        $item = $this->fieldToElement($doc, $value);
165 2
        $item->setAttribute($this->column_attr, (string) $node_name);
166
167 2
        return $item;
168
    }
169
170
    /**
171
     * Convert Cell to Item
172
     *
173
     * @param DOMDocument $doc
174
     * @param string      $value Record item value
175
     *
176
     * @return DOMElement
177
     */
178 2
    protected function fieldToElement(DOMDocument $doc, string $value): DOMElement
179
    {
180 2
        $item = $doc->createElement($this->field_name);
181 2
        $item->appendChild($doc->createTextNode($value));
182
183 2
        return $item;
184
    }
185
186
    /**
187
     * XML root element setter
188
     *
189
     * @param string $node_name
190
     *
191
     * @return self
192
     */
193 4
    public function rootElement(string $node_name): self
194
    {
195 4
        $clone = clone $this;
196 4
        $clone->root_name = $this->filterElementName($node_name);
197
198 2
        return $clone;
199
    }
200
201
    /**
202
     * Filter XML element name
203
     *
204
     * @param string $value Element name
205
     *
206
     * @throws DOMException If the Element name is invalid
207
     *
208
     * @return string
209
     */
210 4
    protected function filterElementName(string $value): string
211
    {
212 4
        return (new DOMElement($value))->tagName;
213
    }
214
215
    /**
216
     * XML Record element setter
217
     *
218
     * @param string $node_name
219
     * @param string $record_offset_attribute_name
220
     *
221
     * @return self
222
     */
223 2
    public function recordElement(string $node_name, string $record_offset_attribute_name = ''): self
224
    {
225 2
        $clone = clone $this;
226 2
        $clone->record_name = $this->filterElementName($node_name);
227 2
        $clone->offset_attr = $this->filterAttributeName($record_offset_attribute_name);
228
229 2
        return $clone;
230
    }
231
232
    /**
233
     * Filter XML attribute name
234
     *
235
     * @param string $value Element name
236
     *
237
     * @throws DOMException If the Element attribute name is invalid
238
     *
239
     * @return string
240
     */
241 4
    protected function filterAttributeName(string $value): string
242
    {
243 4
        if ('' === $value) {
244 2
            return $value;
245
        }
246
247 2
        return (new DOMAttr($value))->name;
248
    }
249
250
    /**
251
     * XML Field element setter
252
     *
253
     * @param string $node_name
254
     * @param string $fieldname_attribute_name
255
     *
256
     * @return self
257
     */
258 2
    public function fieldElement(string $node_name, string $fieldname_attribute_name = ''): self
259
    {
260 2
        $clone = clone $this;
261 2
        $clone->field_name = $this->filterElementName($node_name);
262 2
        $clone->column_attr = $this->filterAttributeName($fieldname_attribute_name);
263
264 2
        return $clone;
265
    }
266
}
267