Skip to content

Improve code quality #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 21, 2018
25 changes: 22 additions & 3 deletions src/PhpArrayToXml.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class PhpArrayToXml
const LOWERCASE = 'lowercase';
const UPPERCASE = 'uppercase';

protected $_doc;
protected $_version = '1.0';
protected $_encoding = 'UTF-8';
protected $_default_root_name = 'root';
Expand Down Expand Up @@ -248,14 +247,14 @@ public function getTransformTags()
/**
* Set the numeric tag suffix
*
* @param null|string $value
* @param null|boolean|string $value
* @return PhpArrayToXml
*/
public function setNumericTagSuffix($value = null)
{
$this->_numeric_tag_suffix = $value;

if ($value === true || $value === false) {
if (is_bool($value) === true) {
$this->_numeric_tag_suffix = '';
}
return $this;
Expand Down Expand Up @@ -380,6 +379,26 @@ public static function isValidXmlTag($value = null)
return false;
}

/**
* Get the UPPERCASE constant
*
* @return string
*/
protected function getConstantUpperCase()
{
return self::UPPERCASE;
}

/**
* Get the LOWERCASE constant
*
* @return string
*/
protected function getConstantLowerCase()
{
return self::LOWERCASE;
}

/**
* Convert an array to XML
*
Expand Down
165 changes: 110 additions & 55 deletions src/Traits/DomDocumentBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@

trait DomDocumentBuilder
{
protected $_doc;

abstract public function getEncoding();
abstract public function getVersion();
abstract public function getFormatOutput();
abstract public function getCustomRootName();
abstract public function getCastBooleanValueTrue();
abstract public function getCastBooleanValueFalse();
abstract public function getCastNullValue();
abstract public function getCustomTagName();
abstract public function getDefaultTagName();
abstract public function getNumericTagSuffix();
abstract public function getSeparator();
abstract public function getDefaultRootName();
abstract public function getTransformTags();
abstract protected function getConstantUpperCase();
abstract protected function getConstantLowerCase();
abstract public static function isValidXmlTag($value);
abstract public static function isValidXmlTagChar($value);
abstract public static function hasValidXmlTagStartingChar($value);

/**
* Creates a DOMDocument from an array
*
Expand All @@ -21,7 +42,7 @@ protected function createDomDocument($array = [])

$this->_doc->appendChild($root);

$this->addArrayElements($root, $array);
$this->createElementsFromArray($root, $array);
}

/**
Expand All @@ -30,50 +51,61 @@ protected function createDomDocument($array = [])
* @param DOMElement $parent
* @param array $array
*/
protected function addArrayElements(DOMElement $parent, $array = [])
protected function createElementsFromArray(DOMElement $parent, $array = [])
{
if (is_array($array)) {
foreach ($array as $name => $value) {
if (!is_array($value)) {
// Create an XML element
$node = $this->createXmlElement($name, $value);
$parent->appendChild($node);
foreach ($array as $name => $value) {
if (!is_array($value)) {
// Create an XML element
$node = $this->createXmlElement($name, $value);
$parent->appendChild($node);
} else {
if (array_key_exists('@value', $value)) {
$this->createAdvancedXmlElement($parent, $value, $name);
} else {
// Create an empty XML element 'container'
$node = $this->createXmlElement($name, null);
$parent->appendChild($node);

if (array_key_exists('@value', $value)) {
$cdata = array_key_exists('@cdata', $value) && $value['@cdata'] === true ? true : false;
$attributes = array_key_exists('@attr', $value) && is_array($value['@attr']) ? $value['@attr'] : [];

if (!is_array($value['@value'])) {
// Create an XML element
$node = $this->createXmlElement($name, $value['@value'], $cdata, $attributes);
$parent->appendChild($node);
} else {
// Create an empty XML element 'container'
$node = $this->createXmlElement($name, null);

foreach ($attributes as $attribute_name => $attribute_value) {
$node->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value));
}

$parent->appendChild($node);

// Add all the elements within the array to the 'container'
$this->addArrayElements($node, $value['@value']);
}
} else {
// Create an empty XML element 'container'
$node = $this->createXmlElement($name, null);
$parent->appendChild($node);

// Add all the elements within the array to the 'container'
$this->addArrayElements($node, $value);
}
// Add all the elements within the array to the 'container'
$this->createElementsFromArray($node, $value);
}
}
}
}

/**
* Create an 'advanced' XML element, when the array has '@value' in it
*
* @param DOMElement $parent
* @param $value
* @param $name
* @return DOMElement
*/
protected function createAdvancedXmlElement(DOMElement $parent, $value, $name): DOMElement
{
$cdata = array_key_exists('@cdata', $value) && $value['@cdata'] === true ? true : false;
$attributes = array_key_exists('@attr', $value) && is_array($value['@attr']) ? $value['@attr'] : [];

if (!is_array($value['@value'])) {
// Create an XML element
$node = $this->createXmlElement($name, $value['@value'], $cdata, $attributes);

$parent->appendChild($node);
} else {
// Create an empty XML element 'container'
$node = $this->createXmlElement($name, null);

foreach ($attributes as $attribute_name => $attribute_value) {
$node->setAttribute($attribute_name, $this->normalizeAttributeValue($attribute_value));
}
$parent->appendChild($node);

// Add all the elements within the array to the 'container'
$this->createElementsFromArray($node, $value['@value']);
}
return $node;
}

/**
* Normalize a value (replace some characters)
*
Expand Down Expand Up @@ -171,28 +203,51 @@ protected function createXmlElement($name, $value = null, $cdata = false, $attri
protected function createValidTagName($name = null)
{
if (empty($name) || $this->isNumericKey($name)) {
$key = $name;
return $this->createValidTagNameFromNumericValue($name);
}

if ($this->isValidXmlTag($this->getCustomTagName())) {
$name = $this->getCustomTagName();
} else {
$name = $this->transformTagName($this->getDefaultTagName());
}
if (!$this->isValidXmlTag($name)) {
$name = $this->makeTagNameValid($name);
}
return $this->transformTagName($name);
}

if ($this->getNumericTagSuffix() !== null) {
$name = $name.(string) $this->getNumericTagSuffix().$key;
}
return $name;
/**
* Make a tag name valid (replace invalid characters including starting characters)
*
* @param $name
* @return null|string|string[]
*/
protected function makeTagNameValid($name)
{
$name = $this->replaceInvalidTagChars($name);

if (!self::hasValidXmlTagStartingChar($name)) {
$name = $this->prefixInvalidTagStartingChar($name);
}
return $name;
}

if (!$this->isValidXmlTag($name)) {
$name = $this->replaceInvalidTagChars($name);
/**
* Create a valid tag name from a numeric value
*
* @param $name
* @return null|string
*/
protected function createValidTagNameFromNumericValue($name)
{
$key = $name;

if (!self::hasValidXmlTagStartingChar($name)) {
$name = $this->prefixInvalidTagStartingChar($name);
}
if ($this->isValidXmlTag($this->getCustomTagName())) {
$name = $this->getCustomTagName();
} else {
$name = $this->transformTagName($this->getDefaultTagName());
}
return $this->transformTagName($name);

if ($this->getNumericTagSuffix() !== null) {
$name = $name . (string)$this->getNumericTagSuffix() . $key;
}
return $name;
}

/**
Expand Down Expand Up @@ -253,10 +308,10 @@ protected function createValidRootName($name = null)
protected function transformTagName($name = null)
{
switch ($this->getTransformTags()) {
case self::LOWERCASE: {
case $this->getConstantLowerCase(): {
return strtolower($name);
}
case self::UPPERCASE: {
case $this->getConstantUpperCase(): {
return strtoupper($name);
}
default: {
Expand Down