Skip to content

Commit a386bda

Browse files
authored
Merge pull request #55 from simplesamlphp/feature/xsd-types
Create type-classes for all xsd-types
2 parents b4a32a9 + 7130d3b commit a386bda

File tree

229 files changed

+9133
-2217
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

229 files changed

+9133
-2217
lines changed

composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
},
2828
"require": {
2929
"php": "^8.1",
30+
31+
"ext-bcmath": "*",
3032
"ext-date": "*",
3133
"ext-dom": "*",
3234
"ext-filter": "*",

src/AbstractElement.php

Lines changed: 32 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,13 @@
77
use DOMElement;
88
use RuntimeException;
99
use SimpleSAML\XML\Assert\Assert;
10-
use SimpleSAML\XML\Exception\MissingAttributeException;
11-
use SimpleSAML\XML\Exception\SchemaViolationException;
10+
use SimpleSAML\XML\Exception\{MissingAttributeException, SchemaViolationException};
1211
use SimpleSAML\XML\SerializableElementTrait;
12+
use SimpleSAML\XML\Type\{QNameValue, StringValue, ValueTypeInterface};
1313

1414
use function array_slice;
1515
use function defined;
1616
use function explode;
17-
use function func_num_args;
18-
use function in_array;
19-
use function intval;
2017
use function join;
2118
use function strval;
2219

@@ -57,133 +54,59 @@ public function instantiateParentElement(?DOMElement $parent = null): DOMElement
5754

5855

5956
/**
60-
* Get the value of an attribute from a given element.
61-
*
62-
* @param \DOMElement $xml The element where we should search for the attribute.
63-
* @param string $name The name of the attribute.
64-
* @return string
57+
* @template T of \SimpleSAML\XML\Type\ValueTypeInterface
58+
* @param \DOMElement $xml The element where we should search for the attribute.
59+
* @param string $name The name of the attribute.
60+
* @param class-string<T> $type The type of the attribute value.
61+
* @return T
6562
*
6663
* @throws \SimpleSAML\XML\Exception\MissingAttributeException if the attribute is missing from the element
6764
*/
68-
public static function getAttribute(DOMElement $xml, string $name): string
69-
{
65+
public static function getAttribute(
66+
DOMElement $xml,
67+
string $name,
68+
string $type = StringValue::class,
69+
): ValueTypeInterface {
70+
Assert::isAOf($type, ValueTypeInterface::class);
71+
7072
$prefix = static::getNamespacePrefix();
7173
$localName = static::getLocalName();
7274
$qName = $prefix ? ($prefix . ':' . $localName) : $localName;
7375
Assert::true(
74-
$xml->hasAttribute($name) && func_num_args() === 2,
76+
$xml->hasAttribute($name),
7577
sprintf('Missing \'%s\' attribute on %s.', $name, $qName),
7678
MissingAttributeException::class,
7779
);
7880

79-
return $xml->getAttribute($name);
81+
$value = $xml->getAttribute($name);
82+
return ($type === QNameValue::class) ? QNameValue::fromDocument($value, $xml) : $type::fromString($value);
8083
}
8184

8285

8386
/**
8487
* Get the value of an attribute from a given element.
8588
*
86-
* @param \DOMElement $xml The element where we should search for the attribute.
87-
* @param string $name The name of the attribute.
88-
* @param string|null $default The default to return in case the attribute does not exist and it is optional.
89-
* @return ($default is string ? string : string|null)
90-
*/
91-
public static function getOptionalAttribute(DOMElement $xml, string $name, ?string $default = null): ?string
92-
{
93-
if (!$xml->hasAttribute($name)) {
94-
return $default;
95-
}
96-
97-
return self::getAttribute($xml, $name);
98-
}
99-
100-
101-
/**
102-
* @param \DOMElement $xml The element where we should search for the attribute.
103-
* @param string $name The name of the attribute.
104-
* @return bool
105-
*
106-
* @throws \SimpleSAML\XML\Exception\MissingAttributeException if the attribute is missing from the element
107-
* @throws \SimpleSAML\Assert\AssertionFailedException if the attribute is not a boolean
89+
* @template T of \SimpleSAML\XML\Type\ValueTypeInterface
90+
* @param \DOMElement $xml The element where we should search for the attribute.
91+
* @param string $name The name of the attribute.
92+
* @param class-string<T> $type The type of the attribute value.
93+
* @param \SimpleSAML\XML\Type\ValueTypeInterface|null $default
94+
* The default to return in case the attribute does not exist and it is optional.
95+
* @return ($default is \SimpleSAML\XML\Type\ValueTypeInterface ? T : T|null)
10896
*/
109-
public static function getBooleanAttribute(DOMElement $xml, string $name): bool
110-
{
111-
$value = self::getAttribute($xml, $name);
97+
public static function getOptionalAttribute(
98+
DOMElement $xml,
99+
string $name,
100+
string $type = StringValue::class,
101+
?ValueTypeInterface $default = null,
102+
): ?ValueTypeInterface {
103+
Assert::nullOrIsInstanceOf($default, $type);
112104

113-
$prefix = static::getNamespacePrefix();
114-
$localName = static::getLocalName();
115-
$qName = $prefix ? ($prefix . ':' . $localName) : $localName;
116-
Assert::oneOf(
117-
$value,
118-
['0', '1', 'false', 'true'],
119-
sprintf('The \'%s\' attribute of %s must be a boolean.', $name, $qName),
120-
);
121-
122-
return in_array($value, ['1', 'true'], true);
123-
}
124-
125-
126-
/**
127-
* @param \DOMElement $xml The element where we should search for the attribute.
128-
* @param string $name The name of the attribute.
129-
* @param bool|null $default The default to return in case the attribute does not exist and it is optional.
130-
* @return ($default is bool ? bool : bool|null)
131-
*
132-
* @throws \SimpleSAML\Assert\AssertionFailedException if the attribute is not a boolean
133-
*/
134-
public static function getOptionalBooleanAttribute(DOMElement $xml, string $name, ?bool $default = null): ?bool
135-
{
136105
if (!$xml->hasAttribute($name)) {
137106
return $default;
138107
}
139108

140-
return self::getBooleanAttribute($xml, $name);
141-
}
142-
143-
144-
/**
145-
* Get the integer value of an attribute from a given element.
146-
*
147-
* @param \DOMElement $xml The element where we should search for the attribute.
148-
* @param string $name The name of the attribute.
149-
* @return int
150-
*
151-
* @throws \SimpleSAML\XML\Exception\MissingAttributeException if the attribute is missing from the element
152-
* @throws \SimpleSAML\Assert\AssertionFailedException if the attribute is not an integer
153-
*/
154-
public static function getIntegerAttribute(DOMElement $xml, string $name): int
155-
{
156-
$value = self::getAttribute($xml, $name);
157-
158-
$prefix = static::getNamespacePrefix();
159-
$localName = static::getLocalName();
160-
$qName = $prefix ? ($prefix . ':' . $localName) : $localName;
161-
Assert::numeric(
162-
$value,
163-
sprintf('The \'%s\' attribute of %s must be numerical.', $name, $qName),
164-
);
165-
166-
return intval($value);
167-
}
168-
169-
170-
/**
171-
* Get the integer value of an attribute from a given element.
172-
*
173-
* @param \DOMElement $xml The element where we should search for the attribute.
174-
* @param string $name The name of the attribute.
175-
* @param int|null $default The default to return in case the attribute does not exist and it is optional.
176-
* @return ($default is int ? int : int|null)
177-
*
178-
* @throws \SimpleSAML\Assert\AssertionFailedException if the attribute is not an integer
179-
*/
180-
public static function getOptionalIntegerAttribute(DOMElement $xml, string $name, ?int $default = null): ?int
181-
{
182-
if (!$xml->hasAttribute($name)) {
183-
return $default;
184-
}
185-
186-
return self::getIntegerAttribute($xml, $name);
109+
return self::getAttribute($xml, $name, $type);
187110
}
188111

189112

@@ -230,11 +153,6 @@ public static function getChildrenOfClass(DOMElement $parent): array
230153
&& $node->namespaceURI === static::getNamespaceURI()
231154
&& $node->localName === static::getLocalName()
232155
) {
233-
// Normalize the DOMElement by importing it into a clean empty document
234-
$newDoc = DOMDocumentFactory::create();
235-
/** @var \DOMElement $node */
236-
$node = $newDoc->appendChild($newDoc->importNode($node, true));
237-
238156
$ret[] = static::fromXML($node);
239157
}
240158
}

src/Assert/AnyURITrait.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\XML\Assert;
6+
7+
use InvalidArgumentException;
8+
9+
/**
10+
* @package simplesamlphp/xml-common
11+
*/
12+
trait AnyURITrait
13+
{
14+
/**
15+
* @param string $value
16+
* @param string $message
17+
*/
18+
protected static function validAnyURI(string $value, string $message = ''): void
19+
{
20+
parent::validURI(
21+
$value,
22+
$message ?: '%s is not a valid xs:anyURI',
23+
InvalidArgumentException::class,
24+
);
25+
}
26+
}

0 commit comments

Comments
 (0)