Completed
Push — master ( af3067...26e39e )
by ignace nyamagana
04:48 queued 02:45
created

XMLConverter::convert()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 15
c 0
b 0
f 0
cc 2
eloc 11
nc 2
nop 1
ccs 11
cts 11
cp 1
crap 2
rs 9.4285
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 DOMDocument;
18
use DOMElement;
19
use Traversable;
20
21
/**
22
 * A class to convert CSV records into a DOMDOcument object
23
 *
24
 * @package League.csv
25
 * @since   9.0.0
26
 * @author  Ignace Nyamagana Butera <[email protected]>
27
 */
28
class XMLConverter implements ConverterInterface
29
{
30
    use ConverterTrait;
31
32
    /**
33
     * XML Root name
34
     *
35
     * @var string
36
     */
37
    protected $root_name = 'csv';
38
39
    /**
40
     * XML Node name
41
     *
42
     * @var string
43
     */
44
    protected $record_name = 'row';
45
46
    /**
47
     * XML Item name
48
     *
49
     * @var string
50
     */
51
    protected $field_name = 'cell';
52
53
    /**
54
     * XML column attribute name
55
     *
56
     * @var string
57
     */
58
    protected $column_attr = '';
59
60
    /**
61
     * XML offset attribute name
62
     *
63
     * @var string
64
     */
65
    protected $offset_attr = '';
66
67
    /**
68
     * Conversion method list
69
     *
70
     * @var array
71
     */
72
    protected $encoder = [
73
        'field' => [
74
            true => 'fieldToElementWithAttribute',
75
            false => 'fieldToElement',
76
        ],
77
        'record' => [
78
            true => 'recordToElementWithAttribute',
79
            false => 'recordToElement',
80
        ],
81
    ];
82
83 4
    public function rootElement(string $node_name): self
84
    {
85 4
        $clone = clone $this;
86 4
        $clone->root_name = $this->filterElementName($node_name, 'root_name', __METHOD__);
87
88 2
        return $clone;
89
    }
90
91 4
    public function recordElement(string $node_name, string $offset_attribute = ''): self
92
    {
93 4
        $clone = clone $this;
94 4
        $clone->record_name = $this->filterElementName($node_name, 'record_name', __METHOD__);
95 4
        $clone->offset_attr = trim(filter_var($offset_attribute, FILTER_SANITIZE_STRING, [
96 4
            'flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH,
97
        ]));
98
99 4
        return $clone;
100
    }
101
102 2
    public function fieldElement(string $node_name, string $fieldname_attribute = '')
103
    {
104 2
        $clone = clone $this;
105 2
        $clone->field_name = $this->filterElementName($node_name, 'field_name', __METHOD__);
106 2
        $clone->column_attr = trim(filter_var($fieldname_attribute, FILTER_SANITIZE_STRING, [
107 2
            'flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH,
108
        ]));
109
110 2
        return $clone;
111
    }
112
113
    /**
114
     * Convert an Record collection into a DOMDocument
115
     *
116
     * @param array|Traversable $records the CSV records collection
117
     *
118
     * @return DOMDocument
119
     */
120 4
    public function convert($records)
121
    {
122 4
        $field_encoder = $this->encoder['field']['' !== $this->column_attr];
123 4
        $record_encoder = $this->encoder['record']['' !== $this->offset_attr];
124 4
        $doc = new DOMDocument('1.0', 'UTF-8');
125 4
        $root = $doc->createElement($this->root_name);
126 4
        $records = $this->convertToUtf8($this->filterIterable($records, __METHOD__));
127 4
        foreach ($records as $offset => $record) {
128 4
            $node = $this->{$record_encoder}($doc, $record, $field_encoder, $offset);
129 4
            $root->appendChild($node);
130
        }
131 4
        $doc->appendChild($root);
132
133 4
        return $doc;
134
    }
135
136
    /**
137
     * Convert a CSV record into a DOMElement and
138
     * adds its offset as DOMElement attribute
139
     *
140
     * @param DOMDocument $doc
141
     * @param array       $record        CSV record
142
     * @param string      $field_encoder CSV Cell encoder method name
143
     * @param int         $offset        CSV record offset
144
     *
145
     * @return DOMElement
146
     */
147 4
    protected function recordToElementWithAttribute(DOMDocument $doc, array $record, string $field_encoder, int $offset): DOMElement
148
    {
149 4
        $node = $this->recordToElement($doc, $record, $field_encoder);
150 4
        $node->setAttribute($this->offset_attr, (string) $offset);
151
152 4
        return $node;
153
    }
154
155
    /**
156
     * Convert a CSV record into a DOMElement
157
     *
158
     * @param DOMDocument $doc
159
     * @param array       $record        CSV record
160
     * @param string      $field_encoder CSV Cell encoder method name
161
     *
162
     * @return DOMElement
163
     */
164 4
    protected function recordToElement(DOMDocument $doc, array $record, string $field_encoder): DOMElement
165
    {
166 4
        $node = $doc->createElement($this->record_name);
167 4
        foreach ($record as $node_name => $value) {
168 4
            $item = $this->{$field_encoder}($doc, $value, $node_name);
169 4
            $node->appendChild($item);
170
        }
171
172 4
        return $node;
173
    }
174
175
    /**
176
     * Convert Cell to Item.
177
     *
178
     * Convert the CSV item into a DOMElement and adds the item offset
179
     * as attribute to the returned DOMElement
180
     *
181
     * @param DOMDocument $doc
182
     * @param string      $value     Record item value
183
     * @param int|string  $node_name Record item offset
184
     *
185
     * @return DOMElement
186
     */
187 2
    protected function fieldToElementWithAttribute(DOMDocument $doc, string $value, $node_name): DOMElement
188
    {
189 2
        $item = $this->fieldToElement($doc, $value);
190 2
        $item->setAttribute($this->column_attr, (string) $node_name);
191
192 2
        return $item;
193
    }
194
195
    /**
196
     * Convert Cell to Item
197
     *
198
     * @param DOMDocument $doc
199
     * @param string      $value Record item value
200
     *
201
     * @return DOMElement
202
     */
203 4
    protected function fieldToElement(DOMDocument $doc, string $value): DOMElement
204
    {
205 4
        $item = $doc->createElement($this->field_name);
206 4
        $item->appendChild($doc->createTextNode($value));
207
208 4
        return $item;
209
    }
210
}
211