77
88trait DomDocumentBuilder
99{
10+ protected $ _doc ;
11+
12+ abstract public function getEncoding ();
13+ abstract public function getVersion ();
14+ abstract public function getFormatOutput ();
15+ abstract public function getCustomRootName ();
16+ abstract public function getCastBooleanValueTrue ();
17+ abstract public function getCastBooleanValueFalse ();
18+ abstract public function getCastNullValue ();
19+ abstract public function getCustomTagName ();
20+ abstract public function getDefaultTagName ();
21+ abstract public function getNumericTagSuffix ();
22+ abstract public function getSeparator ();
23+ abstract public function getDefaultRootName ();
24+ abstract public function getTransformTags ();
25+ abstract protected function getConstantUpperCase ();
26+ abstract protected function getConstantLowerCase ();
27+ abstract public static function isValidXmlTag ($ value );
28+ abstract public static function isValidXmlTagChar ($ value );
29+ abstract public static function hasValidXmlTagStartingChar ($ value );
30+
1031 /**
1132 * Creates a DOMDocument from an array
1233 *
@@ -21,7 +42,7 @@ protected function createDomDocument($array = [])
2142
2243 $ this ->_doc ->appendChild ($ root );
2344
24- $ this ->addArrayElements ($ root , $ array );
45+ $ this ->createElementsFromArray ($ root , $ array );
2546 }
2647
2748 /**
@@ -30,50 +51,61 @@ protected function createDomDocument($array = [])
3051 * @param DOMElement $parent
3152 * @param array $array
3253 */
33- protected function addArrayElements (DOMElement $ parent , $ array = [])
54+ protected function createElementsFromArray (DOMElement $ parent , $ array = [])
3455 {
35- if (is_array ($ array )) {
36- foreach ($ array as $ name => $ value ) {
37- if (!is_array ($ value )) {
38- // Create an XML element
39- $ node = $ this ->createXmlElement ($ name , $ value );
40- $ parent ->appendChild ($ node );
56+ foreach ($ array as $ name => $ value ) {
57+ if (!is_array ($ value )) {
58+ // Create an XML element
59+ $ node = $ this ->createXmlElement ($ name , $ value );
60+ $ parent ->appendChild ($ node );
61+ } else {
62+ if (array_key_exists ('@value ' , $ value )) {
63+ $ this ->createAdvancedXmlElement ($ parent , $ value , $ name );
4164 } else {
65+ // Create an empty XML element 'container'
66+ $ node = $ this ->createXmlElement ($ name , null );
67+ $ parent ->appendChild ($ node );
4268
43- if (array_key_exists ('@value ' , $ value )) {
44- $ cdata = array_key_exists ('@cdata ' , $ value ) && $ value ['@cdata ' ] === true ? true : false ;
45- $ attributes = array_key_exists ('@attr ' , $ value ) && is_array ($ value ['@attr ' ]) ? $ value ['@attr ' ] : [];
46-
47- if (!is_array ($ value ['@value ' ])) {
48- // Create an XML element
49- $ node = $ this ->createXmlElement ($ name , $ value ['@value ' ], $ cdata , $ attributes );
50- $ parent ->appendChild ($ node );
51- } else {
52- // Create an empty XML element 'container'
53- $ node = $ this ->createXmlElement ($ name , null );
54-
55- foreach ($ attributes as $ attribute_name => $ attribute_value ) {
56- $ node ->setAttribute ($ attribute_name , $ this ->normalizeAttributeValue ($ attribute_value ));
57- }
58-
59- $ parent ->appendChild ($ node );
60-
61- // Add all the elements within the array to the 'container'
62- $ this ->addArrayElements ($ node , $ value ['@value ' ]);
63- }
64- } else {
65- // Create an empty XML element 'container'
66- $ node = $ this ->createXmlElement ($ name , null );
67- $ parent ->appendChild ($ node );
68-
69- // Add all the elements within the array to the 'container'
70- $ this ->addArrayElements ($ node , $ value );
71- }
69+ // Add all the elements within the array to the 'container'
70+ $ this ->createElementsFromArray ($ node , $ value );
7271 }
7372 }
7473 }
7574 }
7675
76+ /**
77+ * Create an 'advanced' XML element, when the array has '@value' in it
78+ *
79+ * @param DOMElement $parent
80+ * @param $value
81+ * @param $name
82+ * @return DOMElement
83+ */
84+ protected function createAdvancedXmlElement (DOMElement $ parent , $ value , $ name ): DOMElement
85+ {
86+ $ cdata = array_key_exists ('@cdata ' , $ value ) && $ value ['@cdata ' ] === true ? true : false ;
87+ $ attributes = array_key_exists ('@attr ' , $ value ) && is_array ($ value ['@attr ' ]) ? $ value ['@attr ' ] : [];
88+
89+ if (!is_array ($ value ['@value ' ])) {
90+ // Create an XML element
91+ $ node = $ this ->createXmlElement ($ name , $ value ['@value ' ], $ cdata , $ attributes );
92+
93+ $ parent ->appendChild ($ node );
94+ } else {
95+ // Create an empty XML element 'container'
96+ $ node = $ this ->createXmlElement ($ name , null );
97+
98+ foreach ($ attributes as $ attribute_name => $ attribute_value ) {
99+ $ node ->setAttribute ($ attribute_name , $ this ->normalizeAttributeValue ($ attribute_value ));
100+ }
101+ $ parent ->appendChild ($ node );
102+
103+ // Add all the elements within the array to the 'container'
104+ $ this ->createElementsFromArray ($ node , $ value ['@value ' ]);
105+ }
106+ return $ node ;
107+ }
108+
77109 /**
78110 * Normalize a value (replace some characters)
79111 *
@@ -171,28 +203,51 @@ protected function createXmlElement($name, $value = null, $cdata = false, $attri
171203 protected function createValidTagName ($ name = null )
172204 {
173205 if (empty ($ name ) || $ this ->isNumericKey ($ name )) {
174- $ key = $ name ;
206+ return $ this ->createValidTagNameFromNumericValue ($ name );
207+ }
175208
176- if ($ this ->isValidXmlTag ($ this -> getCustomTagName () )) {
177- $ name = $ this ->getCustomTagName ( );
178- } else {
179- $ name = $ this ->transformTagName ($ this -> getDefaultTagName () );
180- }
209+ if (! $ this ->isValidXmlTag ($ name )) {
210+ $ name = $ this ->makeTagNameValid ( $ name );
211+ }
212+ return $ this ->transformTagName ($ name );
213+ }
181214
182- if ($ this ->getNumericTagSuffix () !== null ) {
183- $ name = $ name .(string ) $ this ->getNumericTagSuffix ().$ key ;
184- }
185- return $ name ;
215+ /**
216+ * Make a tag name valid (replace invalid characters including starting characters)
217+ *
218+ * @param $name
219+ * @return null|string|string[]
220+ */
221+ protected function makeTagNameValid ($ name )
222+ {
223+ $ name = $ this ->replaceInvalidTagChars ($ name );
224+
225+ if (!self ::hasValidXmlTagStartingChar ($ name )) {
226+ $ name = $ this ->prefixInvalidTagStartingChar ($ name );
186227 }
228+ return $ name ;
229+ }
187230
188- if (!$ this ->isValidXmlTag ($ name )) {
189- $ name = $ this ->replaceInvalidTagChars ($ name );
231+ /**
232+ * Create a valid tag name from a numeric value
233+ *
234+ * @param $name
235+ * @return null|string
236+ */
237+ protected function createValidTagNameFromNumericValue ($ name )
238+ {
239+ $ key = $ name ;
190240
191- if (!self ::hasValidXmlTagStartingChar ($ name )) {
192- $ name = $ this ->prefixInvalidTagStartingChar ($ name );
193- }
241+ if ($ this ->isValidXmlTag ($ this ->getCustomTagName ())) {
242+ $ name = $ this ->getCustomTagName ();
243+ } else {
244+ $ name = $ this ->transformTagName ($ this ->getDefaultTagName ());
194245 }
195- return $ this ->transformTagName ($ name );
246+
247+ if ($ this ->getNumericTagSuffix () !== null ) {
248+ $ name = $ name . (string )$ this ->getNumericTagSuffix () . $ key ;
249+ }
250+ return $ name ;
196251 }
197252
198253 /**
@@ -253,10 +308,10 @@ protected function createValidRootName($name = null)
253308 protected function transformTagName ($ name = null )
254309 {
255310 switch ($ this ->getTransformTags ()) {
256- case self :: LOWERCASE : {
311+ case $ this -> getConstantLowerCase () : {
257312 return strtolower ($ name );
258313 }
259- case self :: UPPERCASE : {
314+ case $ this -> getConstantUpperCase () : {
260315 return strtoupper ($ name );
261316 }
262317 default : {
0 commit comments