1 | <?php |
||
29 | class XMLConverter |
||
30 | { |
||
31 | /** |
||
32 | * XML Root name. |
||
33 | * |
||
34 | * @var string |
||
35 | */ |
||
36 | protected $root_name = 'csv'; |
||
37 | |||
38 | /** |
||
39 | * XML Node name. |
||
40 | * |
||
41 | * @var string |
||
42 | */ |
||
43 | protected $record_name = 'row'; |
||
44 | |||
45 | /** |
||
46 | * XML Item name. |
||
47 | * |
||
48 | * @var string |
||
49 | */ |
||
50 | protected $field_name = 'cell'; |
||
51 | |||
52 | /** |
||
53 | * XML column attribute name. |
||
54 | * |
||
55 | * @var string |
||
56 | */ |
||
57 | protected $column_attr = ''; |
||
58 | |||
59 | /** |
||
60 | * XML offset attribute name. |
||
61 | * |
||
62 | * @var string |
||
63 | */ |
||
64 | protected $offset_attr = ''; |
||
65 | |||
66 | /** |
||
67 | * Conversion method list. |
||
68 | * |
||
69 | * @var array |
||
70 | */ |
||
71 | protected $encoder = [ |
||
72 | 'field' => [ |
||
73 | true => 'fieldToElementWithAttribute', |
||
74 | false => 'fieldToElement', |
||
75 | ], |
||
76 | 'record' => [ |
||
77 | true => 'recordToElementWithAttribute', |
||
78 | false => 'recordToElement', |
||
79 | ], |
||
80 | ]; |
||
81 | |||
82 | /** |
||
83 | * Convert a Record collection into a DOMDocument. |
||
84 | * |
||
85 | * @param array|Traversable $records the CSV records collection |
||
86 | */ |
||
87 | 6 | public function convert($records): DOMDocument |
|
88 | { |
||
89 | 6 | if (!is_iterable($records)) { |
|
90 | 3 | throw new TypeError(sprintf('%s() expects argument passed to be iterable, %s given', __METHOD__, gettype($records))); |
|
91 | } |
||
92 | |||
93 | 3 | $doc = new DOMDocument('1.0'); |
|
94 | 3 | $node = $this->import($records, $doc); |
|
95 | 3 | $doc->appendChild($node); |
|
96 | |||
97 | 3 | return $doc; |
|
98 | } |
||
99 | |||
100 | /** |
||
101 | * Create a new DOMElement related to the given DOMDocument. |
||
102 | * |
||
103 | * **DOES NOT** attach to the DOMDocument |
||
104 | * |
||
105 | * @param array|Traversable $records |
||
106 | */ |
||
107 | 6 | public function import($records, DOMDocument $doc): DOMElement |
|
108 | { |
||
109 | 6 | if (!is_iterable($records)) { |
|
110 | 3 | throw new TypeError(sprintf('%s() expects argument passed to be iterable, %s given', __METHOD__, gettype($records))); |
|
111 | } |
||
112 | |||
113 | 3 | $field_encoder = $this->encoder['field']['' !== $this->column_attr]; |
|
114 | 3 | $record_encoder = $this->encoder['record']['' !== $this->offset_attr]; |
|
115 | 3 | $root = $doc->createElement($this->root_name); |
|
116 | 3 | foreach ($records as $offset => $record) { |
|
117 | 3 | $node = $this->$record_encoder($doc, $record, $field_encoder, $offset); |
|
118 | 3 | $root->appendChild($node); |
|
119 | } |
||
120 | |||
121 | 3 | return $root; |
|
122 | } |
||
123 | |||
124 | /** |
||
125 | * Convert a CSV record into a DOMElement and |
||
126 | * adds its offset as DOMElement attribute. |
||
127 | */ |
||
128 | 6 | protected function recordToElementWithAttribute( |
|
139 | |||
140 | /** |
||
141 | * Convert a CSV record into a DOMElement. |
||
142 | */ |
||
143 | 6 | protected function recordToElement(DOMDocument $doc, array $record, string $field_encoder): DOMElement |
|
153 | |||
154 | /** |
||
155 | * Convert Cell to Item. |
||
156 | * |
||
157 | * Convert the CSV item into a DOMElement and adds the item offset |
||
158 | * as attribute to the returned DOMElement |
||
159 | * |
||
160 | * @param int|string $node_name |
||
161 | */ |
||
162 | 6 | protected function fieldToElementWithAttribute(DOMDocument $doc, string $value, $node_name): DOMElement |
|
169 | |||
170 | /** |
||
171 | * Convert Cell to Item. |
||
172 | * |
||
173 | * @param string $value Record item value |
||
174 | */ |
||
175 | 6 | protected function fieldToElement(DOMDocument $doc, string $value): DOMElement |
|
182 | |||
183 | /** |
||
184 | * XML root element setter. |
||
185 | */ |
||
186 | 9 | public function rootElement(string $node_name): self |
|
193 | |||
194 | /** |
||
195 | * Filter XML element name. |
||
196 | * |
||
197 | * @throws DOMException If the Element name is invalid |
||
198 | */ |
||
199 | 9 | protected function filterElementName(string $value): string |
|
203 | |||
204 | /** |
||
205 | * XML Record element setter. |
||
206 | */ |
||
207 | 6 | public function recordElement(string $node_name, string $record_offset_attribute_name = ''): self |
|
215 | |||
216 | /** |
||
217 | * Filter XML attribute name. |
||
218 | * |
||
219 | * @param string $value Element name |
||
220 | * |
||
221 | * @throws DOMException If the Element attribute name is invalid |
||
222 | */ |
||
223 | 9 | protected function filterAttributeName(string $value): string |
|
231 | |||
232 | /** |
||
233 | * XML Field element setter. |
||
234 | */ |
||
235 | 6 | public function fieldElement(string $node_name, string $fieldname_attribute_name = ''): self |
|
243 | } |
||
244 |