Skip to content

Commit

Permalink
Merge branch 'release/2.0.4'
Browse files Browse the repository at this point in the history
  • Loading branch information
mikaelcom committed Feb 3, 2021
2 parents 8c55631 + acfb459 commit 988a0b0
Show file tree
Hide file tree
Showing 14 changed files with 196 additions and 169 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
vendor
composer.lock
phpunit.xml
.idea
.phpunit.result.cache
coverage
7 changes: 1 addition & 6 deletions .php_cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ $finder = PhpCsFixer\Finder::create()
return PhpCsFixer\Config::create()
->setUsingCache(false)
->setRules(array(
'@PSR2' => true,
'binary_operator_spaces' => true,
'no_whitespace_in_blank_line' => true,
'ternary_operator_spaces' => true,
'cast_spaces' => true,
'trailing_comma_in_multiline_array' => true
'@PhpCsFixer' => true,
))
->setFinder($finder);
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 2.0.4 - 2021/02/03
- Review .php_cs settings, apply PHP CS Fixer
- Change tests classes to final classes

## 2.0.3 - 2021/02/01
- issue #3 - getAttributes returns an empty array

Expand All @@ -10,7 +14,7 @@
- Minor readme and Travis CI updates

## 2.0.0 - 2021/01/26
- use `splitbrain/phpfarm:jessie` as Docker image and fix docker image settings
- Use `splitbrain/phpfarm:jessie` as Docker image and fix docker image settings
- Code requires PHP >= 7.4
- Code cleaning
- Update README
Expand Down
60 changes: 32 additions & 28 deletions src/AbstractAttributeHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,42 @@

class AbstractAttributeHandler extends AbstractNodeHandler
{
const DEFAULT_VALUE_TYPE = 'string';
public const DEFAULT_VALUE_TYPE = 'string';

const ATTRIBUTE_NAMESPACE = 'namespace';
public const ATTRIBUTE_NAMESPACE = 'namespace';

const ATTRIBUTE_NAME = 'name';
public const ATTRIBUTE_NAME = 'name';

const ATTRIBUTE_REF = 'ref';
public const ATTRIBUTE_REF = 'ref';

const ATTRIBUTE_VALUE = 'value';
public const ATTRIBUTE_VALUE = 'value';

const ATTRIBUTE_TYPE = 'type';
public const ATTRIBUTE_TYPE = 'type';

const ATTRIBUTE_ABSTRACT = 'abstract';
public const ATTRIBUTE_ABSTRACT = 'abstract';

const ATTRIBUTE_MAX_OCCURS = 'maxOccurs';
public const ATTRIBUTE_MAX_OCCURS = 'maxOccurs';

const ATTRIBUTE_MIN_OCCURS = 'minOccurs';
public const ATTRIBUTE_MIN_OCCURS = 'minOccurs';

const ATTRIBUTE_NILLABLE = 'nillable';
public const ATTRIBUTE_NILLABLE = 'nillable';

const VALUE_UNBOUNDED = 'unbounded';
public const VALUE_UNBOUNDED = 'unbounded';

/**
* @deprecated
*/
const DEFAULT_OCCURENCE_VALUE = 1;
public const DEFAULT_OCCURENCE_VALUE = 1;

const DEFAULT_OCCURRENCE_VALUE = 1;
public const DEFAULT_OCCURRENCE_VALUE = 1;

public function getAttribute(): DOMAttr
{
return $this->getNode();
}

/**
* Tries to get attribute type on the same node in order to return the value of the attribute in its type
* @return string|null
* Tries to get attribute type on the same node in order to return the value of the attribute in its type.
*/
public function getType(): ?string
{
Expand All @@ -58,10 +58,10 @@ public function getType(): ?string
public function getValue(bool $withNamespace = false, bool $withinItsType = true, ?string $asType = self::DEFAULT_VALUE_TYPE)
{
$value = $this->getAttribute()->value;
if ($withNamespace === false && !empty($value)) {
if (false === $withNamespace && !empty($value)) {
$value = implode('', array_slice(explode(':', $value), -1, 1));
}
if ($value !== null && $withinItsType === true) {
if (null !== $value && true === $withinItsType) {
$value = self::getValueWithinItsType($value, empty($asType) ? $this->getType() : $asType);
}

Expand All @@ -72,22 +72,24 @@ public function getValueNamespace(): ?string
{
$value = $this->getAttribute()->value;
$namespace = null;
if (strpos($value, ':') !== false) {
if (false !== strpos($value, ':')) {
$namespace = implode('', array_slice(explode(':', $value), 0, -1));
}

return $namespace;
}

/**
* Returns the value with good type
* @param mixed $value the value
* @param string|null $knownType the value
* Returns the value with good type.
*
* @param mixed $value the value
* @param null|string $knownType the value
*
* @return mixed
*/
public static function getValueWithinItsType($value, ?string $knownType = null)
{
if (is_int($value) || (!is_null($value) && in_array($knownType, array(
if (is_int($value) || (!is_null($value) && in_array($knownType, [
'time',
'positiveInteger',
'unsignedLong',
Expand All @@ -96,19 +98,21 @@ public static function getValueWithinItsType($value, ?string $knownType = null)
'long',
'int',
'integer',
), true))) {
], true))) {
return intval($value);
} elseif (is_float($value) || (!is_null($value) && in_array($knownType, array(
}
if (is_float($value) || (!is_null($value) && in_array($knownType, [
'float',
'double',
'decimal',
), true))) {
], true))) {
return floatval($value);
} elseif (is_bool($value) || (!is_null($value) && in_array($knownType, array(
}
if (is_bool($value) || (!is_null($value) && in_array($knownType, [
'bool',
'boolean',
), true))) {
return ($value === 'true' || $value === true || $value === 1 || $value === '1');
], true))) {
return 'true' === $value || true === $value || 1 === $value || '1' === $value;
}

return $value;
Expand Down
64 changes: 34 additions & 30 deletions src/AbstractDomDocumentHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,43 +23,21 @@ public function __construct(DOMDocument $domDocument)
$this->initRootElement();
}

/**
* Find valid root node (not a comment, at least a DOMElement node)
* @throws InvalidArgumentException
*/
protected function initRootElement()
{
if ($this->domDocument->hasChildNodes()) {
foreach ($this->domDocument->childNodes as $node) {
if ($node instanceof DOMElement) {
$this->rootElement = $this->getElementHandler($node, $this);
break;
}
}
} else {
throw new InvalidArgumentException('Document seems to be invalid', __LINE__);
}
}

public function getHandler($node, int $index = -1): AbstractNodeHandler
{
if ($node instanceof DOMElement) {
return $this->getElementHandler($node, $this, $index);
} elseif ($node instanceof DOMAttr) {
}
if ($node instanceof DOMAttr) {
return $this->getAttributeHandler($node, $this, $index);
} elseif ($node instanceof DOMNameSpaceNode) {
}
if ($node instanceof DOMNameSpaceNode) {
return new NameSpaceHandler($node, $this, $index);
}

return $this->getNodeHandler($node, $this, $index);
}

abstract protected function getNodeHandler(DOMNode $node, AbstractDomDocumentHandler $domDocument, int $index = -1): NodeHandler;

abstract protected function getElementHandler(DOMElement $element, AbstractDomDocumentHandler $domDocument, int $index = -1): ElementHandler;

abstract protected function getAttributeHandler(DOMAttr $attribute, AbstractDomDocumentHandler $domDocument, int $index = -1): AttributeHandler;

public function getNodeByName(string $name): ?NodeHandler
{
return $this->domDocument->getElementsByTagName($name)->length > 0 ? $this->getNodeHandler($this->domDocument->getElementsByTagName($name)->item(0), $this) : null;
Expand All @@ -77,7 +55,7 @@ public function getElementByName(string $name): ?ElementHandler

public function getNodesByName(string $name, ?string $checkInstance = null): array
{
$nodes = array();
$nodes = [];
if ($this->domDocument->getElementsByTagName($name)->length > 0) {
foreach ($this->domDocument->getElementsByTagName($name) as $node) {
if (is_null($checkInstance) || $node instanceof $checkInstance) {
Expand Down Expand Up @@ -110,13 +88,13 @@ public function getElementsByNameAndAttributes(string $name, array $attributes,

public function getElementsHandlers(DOMNodeList $nodeList): array
{
$nodes = array();
$nodes = [];
if (!empty($nodeList)) {
$index = 0;
foreach ($nodeList as $node) {
if ($node instanceof DOMElement) {
$nodes[] = $this->getElementHandler($node, $this, $index);
$index++;
++$index;
}
}
}
Expand All @@ -129,7 +107,7 @@ public function searchTagsByXpath(string $name, array $attributes, ?DOMNode $nod
$xpath = new DOMXPath($node ? $node->ownerDocument : $this->domDocument);
$xQuery = sprintf("%s//*[local-name()='%s']", $node instanceof DOMNode ? '.' : '', $name);
foreach ($attributes as $attributeName => $attributeValue) {
if (strpos($attributeValue, '*') !== false) {
if (false !== strpos($attributeValue, '*')) {
$xQuery .= sprintf("[contains(@%s, '%s')]", $attributeName, str_replace('*', '', $attributeValue));
} else {
$xQuery .= sprintf("[@%s='%s']", $attributeName, $attributeValue);
Expand All @@ -145,4 +123,30 @@ public function getElementByNameAndAttributes(string $name, array $attributes):

return array_shift($elements);
}

/**
* Find valid root node (not a comment, at least a DOMElement node).
*
* @throws InvalidArgumentException
*/
protected function initRootElement()
{
if ($this->domDocument->hasChildNodes()) {
foreach ($this->domDocument->childNodes as $node) {
if ($node instanceof DOMElement) {
$this->rootElement = $this->getElementHandler($node, $this);

break;
}
}
} else {
throw new InvalidArgumentException('Document seems to be invalid', __LINE__);
}
}

abstract protected function getNodeHandler(DOMNode $node, AbstractDomDocumentHandler $domDocument, int $index = -1): NodeHandler;

abstract protected function getElementHandler(DOMElement $element, AbstractDomDocumentHandler $domDocument, int $index = -1): ElementHandler;

abstract protected function getAttributeHandler(DOMAttr $attribute, AbstractDomDocumentHandler $domDocument, int $index = -1): AttributeHandler;
}
28 changes: 11 additions & 17 deletions src/AbstractElementHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function getAttributeValue(string $name, bool $withNamespace = false, boo

public function getChildrenByName(string $name): array
{
$children = array();
$children = [];
if ($this->hasChildren()) {
foreach ($this->getElement()->getElementsByTagName($name) as $index => $node) {
$children[] = $this->getDomDocumentHandler()->getHandler($node, $index);
Expand All @@ -53,7 +53,7 @@ public function getChildrenByName(string $name): array

public function getElementChildren(): array
{
$children = array();
$children = [];
if ($this->hasChildren()) {
$children = $this->getDomDocumentHandler()->getElementsHandlers($this->getChildNodes());
}
Expand All @@ -74,7 +74,8 @@ public function getChildByNameAndAttributes(string $name, array $attributes): ?E
}

/**
* Info at {@link https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints}
* Info at {@link https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints}.
*
* @return mixed
*/
public function getMaxOccurs()
Expand All @@ -91,7 +92,8 @@ public function getMaxOccurs()
}

/**
* Info at {@link https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints}
* Info at {@link https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints}.
*
* @return int
*/
public function getMinOccurs()
Expand All @@ -105,53 +107,45 @@ public function getMinOccurs()
}

/**
* Info at {@link http://www.w3schools.com/xml/el_element.asp}
* @return bool
* Info at {@link http://www.w3schools.com/xml/el_element.asp}.
*/
public function getNillable(): bool
{
return (bool) $this->getAttributeValue(AbstractAttributeHandler::ATTRIBUTE_NILLABLE, false, true, 'bool');
}

/**
* Info at {@link https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints}
* @return bool
* Info at {@link https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints}.
*/
public function canOccurSeveralTimes(): bool
{
return (1 < $this->getMinOccurs()) || (1 < $this->getMaxOccurs()) || (AbstractAttributeHandler::VALUE_UNBOUNDED === $this->getMaxOccurs());
}

/**
* Info at {@link https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints}
* @return bool
* Info at {@link https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints}.
*/
public function canOccurOnlyOnce(): bool
{
return 1 === $this->getMaxOccurs();
}

/**
* Info at {@link https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints}
* @return bool
* Info at {@link https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints}.
*/
public function isOptional(): bool
{
return 0 === $this->getMinOccurs();
}

/**
* Info at {@link https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints}
* @return bool
* Info at {@link https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints}.
*/
public function isRequired(): bool
{
return 1 <= $this->getMinOccurs();
}

/**
* @return bool
*/
public function isRemovable(): bool
{
return $this->isOptional() && $this->getNillable();
Expand Down
Loading

0 comments on commit 988a0b0

Please sign in to comment.