Skip to content

Commit 776bd73

Browse files
authored
Improve code quality (#9)
* Extract regex patterns to its own class * temp * Add file again ( src/Lib/ ) * Extract DomDocumentBuilder to its own class
1 parent 4a21e8e commit 776bd73

File tree

2 files changed

+271
-251
lines changed

2 files changed

+271
-251
lines changed

src/PhpArrayToXml.php

Lines changed: 4 additions & 251 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
namespace RefactorStudio\PhpArrayToXml;
44

5-
use DOMDocument;
6-
use DOMElement;
75
use RefactorStudio\PhpArrayToXml\Lib\XmlPatterns;
6+
use RefactorStudio\PhpArrayToXml\Traits\DomDocumentBuilder;
87

98
class PhpArrayToXml
109
{
10+
use DomDocumentBuilder;
11+
1112
const LOWERCASE = 'lowercase';
1213
const UPPERCASE = 'uppercase';
1314

@@ -387,256 +388,8 @@ public static function isValidXmlTag($value = null)
387388
*/
388389
public function toXmlString($array = [])
389390
{
390-
$this->_doc = new DOMDocument($this->getVersion(), $this->getEncoding());
391-
$this->_doc->formatOutput = $this->getFormatOutput();
392-
393-
$root = $this->_doc->createElement($this->createValidRootName($this->getCustomRootName()));
394-
395-
$this->_doc->appendChild($root);
396-
397-
$this->addArrayElements($root, $array);
391+
$this->createDomDocument($array);
398392

399393
return $this->_doc->saveXML();
400394
}
401-
402-
/**
403-
* Converts arrays to DOMDocument elements
404-
*
405-
* @param DOMElement $parent
406-
* @param array $array
407-
*/
408-
protected function addArrayElements(DOMElement $parent, $array = [])
409-
{
410-
if (is_array($array)) {
411-
foreach ($array as $name => $value) {
412-
if (!is_array($value)) {
413-
// Create an XML element
414-
$node = $this->createElement($name, $value);
415-
$parent->appendChild($node);
416-
} else {
417-
418-
if (array_key_exists('@value', $value)) {
419-
$cdata = array_key_exists('@cdata', $value) && $value['@cdata'] === true ? true : false;
420-
$attributes = array_key_exists('@attr', $value) && is_array($value['@attr']) ? $value['@attr'] : [];
421-
422-
if (!is_array($value['@value'])) {
423-
// Create an XML element
424-
$node = $this->createElement($name, $value['@value'], $cdata, $attributes);
425-
$parent->appendChild($node);
426-
} else {
427-
// Create an empty XML element 'container'
428-
$node = $this->createElement($name, null);
429-
430-
foreach ($attributes as $attribute_name => $attribute_value) {
431-
$node->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value));
432-
}
433-
434-
$parent->appendChild($node);
435-
436-
// Add all the elements within the array to the 'container'
437-
$this->addArrayElements($node, $value['@value']);
438-
}
439-
} else {
440-
// Create an empty XML element 'container'
441-
$node = $this->createElement($name, null);
442-
$parent->appendChild($node);
443-
444-
// Add all the elements within the array to the 'container'
445-
$this->addArrayElements($node, $value);
446-
}
447-
}
448-
}
449-
}
450-
}
451-
452-
/**
453-
* Normalize a value (replace some characters)
454-
*
455-
* @param $value
456-
* @return null|string
457-
*/
458-
protected function normalizeValue($value)
459-
{
460-
if ($value === true) {
461-
return $this->getCastBooleanValueTrue();
462-
}
463-
464-
if ($value === false) {
465-
return $this->getCastBooleanValueFalse();
466-
}
467-
468-
if ($value === null) {
469-
return $this->getCastNullValue();
470-
}
471-
472-
return $value;
473-
}
474-
475-
/**
476-
* Normalize an attribute value (replace some characters)
477-
*
478-
* @param $value
479-
* @return string
480-
*/
481-
protected function normalizeAttributeValue($value)
482-
{
483-
if ($value === true) {
484-
return 'true';
485-
}
486-
487-
if ($value === false) {
488-
return 'false';
489-
}
490-
491-
return $value;
492-
}
493-
494-
/**
495-
* See if a value matches an integer (could be a integer within a string)
496-
*
497-
* @param $value
498-
* @return bool
499-
*/
500-
protected function isNumericKey($value)
501-
{
502-
$pattern = '~^(0|[1-9][0-9]*)$~ux';
503-
504-
return preg_match($pattern, $value) === 1;
505-
}
506-
507-
/**
508-
* Creates an element for DOMDocument
509-
*
510-
* @param $name
511-
* @param null|string $value
512-
* @param bool $cdata
513-
* @param array $attributes
514-
* @return DOMElement
515-
*/
516-
protected function createElement($name, $value = null, $cdata = false, $attributes = [])
517-
{
518-
$name = $this->createValidTagName($name);
519-
520-
if ($cdata === true) {
521-
$element = $this->_doc->createElement($name);
522-
$element->appendChild($this->_doc->createCDATASection($value));
523-
524-
foreach ($attributes as $attribute_name => $attribute_value) {
525-
$element->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value));
526-
}
527-
528-
return $element;
529-
}
530-
531-
$element = $this->_doc->createElement($name, $this->normalizeValue($value));
532-
533-
foreach ($attributes as $attribute_name => $attribute_value) {
534-
$element->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value));
535-
}
536-
537-
return $element;
538-
}
539-
540-
/**
541-
* Creates a valid tag name
542-
*
543-
* @param null|string $name
544-
* @return string
545-
*/
546-
protected function createValidTagName($name = null)
547-
{
548-
if (empty($name) || $this->isNumericKey($name)) {
549-
$key = $name;
550-
551-
if ($this->isValidXmlTag($this->getCustomTagName())) {
552-
$name = $this->getCustomTagName();
553-
} else {
554-
$name = $this->transformTagName($this->getDefaultTagName());
555-
}
556-
557-
if ($this->getNumericTagSuffix() !== null) {
558-
$name = $name.(string) $this->getNumericTagSuffix().$key;
559-
}
560-
return $name;
561-
}
562-
563-
if (!$this->isValidXmlTag($name)) {
564-
$name = $this->replaceInvalidTagChars($name);
565-
566-
if (!self::hasValidXmlTagStartingChar($name)) {
567-
$name = $this->prefixInvalidTagStartingChar($name);
568-
}
569-
}
570-
return $this->transformTagName($name);
571-
}
572-
573-
/**
574-
* If a tag has an invalid starting character, use an underscore as prefix
575-
*
576-
* @param $value
577-
* @return string
578-
*/
579-
protected function prefixInvalidTagStartingChar($value)
580-
{
581-
return '_'.substr($value, 1);
582-
}
583-
584-
/**
585-
* Replace invalid tag characters
586-
*
587-
* @param $value
588-
* @return null|string|string[]
589-
*/
590-
protected function replaceInvalidTagChars($value)
591-
{
592-
$pattern = '';
593-
for ($i = 0; $i < strlen($value); $i++) {
594-
if (!self::isValidXmlTagChar($value[$i])) {
595-
$pattern .= "\\$value[$i]";
596-
}
597-
}
598-
599-
if (!empty($pattern)) {
600-
$value = preg_replace("/[{$pattern}]/", $this->getSeparator(), $value);
601-
}
602-
return $value;
603-
}
604-
605-
/**
606-
* Creates a valid root name
607-
*
608-
* @param null|string $name
609-
* @return string
610-
*/
611-
protected function createValidRootName($name = null)
612-
{
613-
if (is_string($name)) {
614-
$name = preg_replace("/[^_a-zA-Z0-9]/", $this->getSeparator(), $name);
615-
}
616-
if ($this->isValidXmlTag($name)) {
617-
return $name;
618-
}
619-
return $this->transformTagName($this->getDefaultRootName());
620-
}
621-
622-
/**
623-
* Transforms a tag name (only when specified)
624-
*
625-
* @param null|string $name
626-
* @return null|string
627-
*/
628-
protected function transformTagName($name = null)
629-
{
630-
switch ($this->getTransformTags()) {
631-
case self::LOWERCASE: {
632-
return strtolower($name);
633-
}
634-
case self::UPPERCASE: {
635-
return strtoupper($name);
636-
}
637-
default: {
638-
return $name;
639-
}
640-
}
641-
}
642395
}

0 commit comments

Comments
 (0)