Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
55.56% |
10 / 18 |
CRAP | |
85.59% |
95 / 111 |
DomElement | |
0.00% |
0 / 1 |
|
55.56% |
10 / 18 |
57.49 | |
85.59% |
95 / 111 |
__toString() | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getName() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
getValue() | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getIterator() | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getChildNodes() | |
0.00% |
0 / 1 |
2.06 | |
75.00% |
3 / 4 |
|||
getAttributeValue($name, $default_value = null) | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
getAttributes() | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
get($name) | |
0.00% |
0 / 1 |
2.15 | |
66.67% |
2 / 3 |
|||
has($name) | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
hasChild($name) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
getChild($name) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 5 |
|||
hasChildren($name) | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
countChildren($name) | |
0.00% |
0 / 1 |
5.27 | |
77.78% |
14 / 18 |
|||
getChildren($name) | |
100.00% |
1 / 1 |
4 | |
100.00% |
16 / 16 |
|||
hasParameters() | |
0.00% |
0 / 1 |
2.15 | |
66.67% |
2 / 3 |
|||
getParameters(array $default = array(), $literalize = true) | |
100.00% |
1 / 1 |
7 | |
100.00% |
18 / 18 |
|||
getLiteralValue($element) | |
0.00% |
0 / 1 |
7.10 | |
87.50% |
14 / 16 |
|||
literalize($value) | |
100.00% |
1 / 1 |
9 | |
100.00% |
11 / 11 |
<?php | |
namespace Environaut\Config\Reader\Dom; | |
/** | |
* Custom \DOMElement implementation for Environaut to have some | |
* convenience methods to get child nodes etc. Please be aware, that | |
* by default these methods use the Environaut default namespace URI. | |
* | |
* @todo make namespace URI configurable for convenience methods | |
*/ | |
class DomElement extends \DOMElement implements \IteratorAggregate | |
{ | |
/** | |
* @var DomDocument | |
*/ | |
protected $ownerDocument; | |
/** | |
* Returns the nodeValue of the element. | |
* | |
* @return string nodeValue of the element | |
*/ | |
public function __toString() | |
{ | |
return $this->getValue(); | |
} | |
/** | |
* Returns the nodeName of the element. | |
* | |
* @return string nodeName of the element | |
*/ | |
public function getName() | |
{ | |
return $this->nodeName; | |
} | |
/** | |
* Returns the nodeValue of the element. | |
* | |
* @return string nodeValue of the element | |
*/ | |
public function getValue() | |
{ | |
return $this->nodeValue; | |
} | |
/** | |
* Returns a \DOMNodeList of all child elements of the element. | |
* | |
* @return \DOMNodeList (Traversable) of all child elements | |
*/ | |
public function getIterator() | |
{ | |
return $this->getChildNodes(); | |
} | |
/** | |
* Returns a \DOMNodeList of all child elements of the element. | |
* | |
* @return \DOMNodeList of all child elements | |
*/ | |
public function getChildNodes() | |
{ | |
$prefix = $this->ownerDocument->getDefaultNamespacePrefix(); | |
if ($prefix) { | |
return $this->ownerDocument->getXpath()->query(sprintf('child::%s:*', $prefix), $this); | |
} else { | |
return $this->ownerDocument->getXpath()->query('child::*', $this); | |
} | |
} | |
/** | |
* Returns the value of the given attribute or returns the given | |
* default value if the attribute is missing. | |
* | |
* @param string $name name of attribute | |
* @param mixed $default_value value to return if attribute is missing | |
* | |
* @return mixed string value of attribute or default_value if attribute is not found or empty | |
*/ | |
public function getAttributeValue($name, $default_value = null) | |
{ | |
$value = parent::getAttribute($name); | |
if ($value === '') { | |
$value = $default_value; | |
} | |
return $value; | |
} | |
/** | |
* Returns all attributes including their values for the element. | |
* | |
* @return array of attributes (name => value pairs) | |
*/ | |
public function getAttributes() | |
{ | |
$attributes = array(); | |
foreach ($this->ownerDocument->getXpath()->query('@*', $this) as $attribute) { | |
$attributes[$attribute->localName] = $attribute->nodeValue; | |
} | |
return $attributes; | |
} | |
/** | |
* Returns all child elements of the given name or all children | |
* of the element if name is not specified. | |
* | |
* @param string $name name of child elements to get | |
* | |
* @return \DOMNodeList of all children | |
*/ | |
public function get($name) | |
{ | |
if (!$name) { | |
return $this->getChildNodes(); | |
} | |
return $this->getChildren($name); | |
} | |
/** | |
* Determines whether there are children of the element | |
* with the given name. | |
* | |
* @param string $name name of child element to check | |
* | |
* @return bool true if children of that name exist on the element | |
*/ | |
public function has($name) | |
{ | |
return $this->hasChildren($name); | |
} | |
/** | |
* Determines whether there's at least one child node with the given name. | |
* | |
* @param string $name name of child node | |
* | |
* @return bool true, if a first child with that name exists | |
*/ | |
public function hasChild($name) | |
{ | |
return $this->getChild($name) !== null; | |
} | |
/** | |
* Returns first child of the element with the given name. | |
* | |
* @param string $name name of element to get | |
* | |
* @return \DOMNode first child node with the given name | |
*/ | |
public function getChild($name) | |
{ | |
$query = 'self::node()[count(child::*[local-name() = "%1$s" and namespace-uri() = "%2$s"]) = 1]/*' . | |
'[local-name() = "%1$s" and namespace-uri() = "%2$s"]'; | |
$node = $this->ownerDocument->getXpath()->query( | |
sprintf($query, $name, $this->ownerDocument->getDefaultNamespaceUri()), | |
$this | |
)->item(0); | |
return $node; | |
} | |
/** | |
* Determines whether there are children of the element | |
* with the given name. | |
* | |
* @param string $name name of child element to check | |
* | |
* @return bool true if children of that name exist on the element | |
*/ | |
public function hasChildren($name) | |
{ | |
return $this->countChildren($name) !== 0; | |
} | |
/** | |
* Returns the count of the children with the given name. | |
* Special handling for the following names is implemented: | |
* - 'paramaters' returns count of all direct 'parameters' OR all 'parameters/parameter' child nodes | |
* - 'formatters' returns count of all direct 'formatters' OR all 'formatters/formatter' child nodes | |
* | |
* @param string $name element name | |
* | |
* @return int number of child elements of the given name | |
*/ | |
public function countChildren($name) | |
{ | |
$query = ''; | |
$singular_name = null; | |
// special nodes of environaut config files where the surrounding plural node | |
// may be omitted and the singular nodes be used directly (for less verbose xml) | |
if (in_array($name, array('parameters', 'formatters'))) { | |
if ($name === 'parameters') { | |
$singular_name = 'parameter'; | |
} elseif ($name === 'formatters') { | |
$singular_name = 'formatter'; | |
} | |
$query = 'count(child::*[local-name() = "%2$s" and namespace-uri() = "%3$s"]) + ' . | |
'count(child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"]/*' . | |
'[local-name() = "%2$s" and namespace-uri() = "%3$s"])'; | |
} elseif (empty($name)) { | |
$query = 'count(child::*[namespace-uri() = "%3$s"])'; | |
} else { | |
$query = 'count(child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"])'; | |
} | |
$count = (int) $this->ownerDocument->getXpath()->evaluate( | |
sprintf($query, $name, $singular_name, $this->ownerDocument->getDefaultNamespaceUri()), | |
$this | |
); | |
return $count; | |
} | |
/** | |
* Returns all child elements of the given name. Special handling for the following names is implemented: | |
* - 'paramaters' returns all direct 'parameters' OR all 'parameters/parameter' child nodes | |
* - 'formatters' returns all direct 'formatters' OR all 'formatters/formatter' child nodes | |
* | |
* @param string $name name of child element | |
* | |
* @return \DOMNodeList of all child elements with the given name in the default namespace | |
*/ | |
public function getChildren($name) | |
{ | |
$query = ''; | |
$singular_name = null; | |
// special nodes of environaut config files where the surrounding plural node | |
// may be omitted and the singular nodes be used directly (for less verbose xml) | |
if (in_array($name, array('parameters', 'formatters'))) { | |
if ($name === 'parameters') { | |
$singular_name = 'parameter'; | |
} elseif ($name === 'formatters') { | |
$singular_name = 'formatter'; | |
} | |
$query = 'child::*[local-name() = "%2$s" and namespace-uri() = "%3$s"] | ' . | |
'child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"]/*' . | |
'[local-name() = "%2$s" and namespace-uri() = "%3$s"]'; | |
} else { | |
$query = 'child::*[local-name() = "%1$s" and namespace-uri() = "%3$s"]'; | |
} | |
$nodes = $this->ownerDocument->getXpath()->query( | |
sprintf($query, $name, $singular_name, $this->ownerDocument->getDefaultNamespaceUri()), | |
$this | |
); | |
return $nodes; | |
} | |
/** | |
* Determine whether there's a 'parameters' element as child of the element. | |
* | |
* @return boolean true if there is a 'parameters' element | |
*/ | |
public function hasParameters() | |
{ | |
if ($this->ownerDocument->isEnvironautDocument()) { | |
return $this->has('parameters'); | |
} | |
return false; | |
} | |
/** | |
* Returns all (nested) parameters of the element as an associative array. | |
* | |
* @param array $default array to be used as default | |
* @param boolean $literalize whether or not to literalize values like 'true'/'false' by default | |
* | |
* @return array of associative nested parameters (numerical keys where a 'name' attribute is missing) | |
*/ | |
public function getParameters(array $default = array(), $literalize = true) | |
{ | |
$offset = 0; | |
if ($this->ownerDocument->isEnvironautDocument()) { | |
$elements = $this->get('parameters'); | |
foreach ($elements as $element) { | |
$name = null; | |
if (!$element->hasAttribute('name')) { | |
$name = $offset++; | |
$default[$name] = null; | |
} else { | |
$name = $element->getAttributeValue('name'); | |
} | |
if ($element->hasParameters()) { | |
$default[$name] = isset($default[$name]) && is_array($default[$name]) ? $default[$name] : array(); | |
$default[$name] = $element->getParameters($default[$name], $literalize); | |
} else { | |
$default[$name] = $this->getLiteralValue($element); | |
} | |
} | |
} | |
return $default; | |
} | |
/** | |
* Depending on the values of the 'literalize' and 'space' attributes of the element | |
* the transformed or literal value of the value is returned | |
* | |
* @param \DOMNode $element element to get a value for | |
* | |
* @return mixed literalized and/or whitespace preserved value or null if value is empty | |
*/ | |
protected function getLiteralValue($element) | |
{ | |
$value = $element->getValue(); | |
$trimmed_value = trim($value); | |
$preserve_whitespace = $element->getAttributeValue('space', 'default') === 'preserve'; | |
$literalize_value = self::literalize($element->getAttributeValue('literalize')) !== false; | |
if ($literalize_value) { | |
if ($preserve_whitespace && ($trimmed_value === '' || $value !== $trimmed_value)) { | |
$value = $value; | |
} else { | |
$value = self::literalize($trimmed_value); | |
} | |
} elseif (!$preserve_whitespace) { | |
$value = $trimmed_value; | |
if ($value === '') { | |
$value = null; | |
} | |
} | |
return $value; | |
} | |
/** | |
* Returns the literalized value, that is: | |
* - 'on|yes|true' will be boolean TRUE | |
* - 'off|no|false' will be boolean FALSE | |
* - '' will be NULL | |
* | |
* All other non-string values will be returned as is. | |
* | |
* @param mixed $value value to literalize | |
* | |
* @return mixed null or boolean value or the original value of it's not a string | |
*/ | |
public static function literalize($value) | |
{ | |
if (!is_string($value)) { | |
return $value; | |
} | |
$value = trim($value); | |
if ($value == '') { | |
return null; | |
} | |
$lc_value = strtolower($value); | |
if ($lc_value === 'on' || $lc_value === 'yes' || $lc_value === 'true') { | |
return true; | |
} elseif ($lc_value === 'off' || $lc_value === 'no' || $lc_value === 'false') { | |
return false; | |
} | |
return $value; | |
} | |
} |