Skip to content

Commit 6fd0ce9

Browse files
committed
Improved XML support with own GetValue method wrappings
1 parent b756f82 commit 6fd0ce9

32 files changed

+719
-82
lines changed

docs/content/en/index.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,55 @@ missing.
309309
$value = $data->getRequiredArrayGetter('key');
310310
```
311311

312+
### Get SimpleXMLElement
313+
314+
Return SimpleXMLElement for given key. Uses `xml` transformer strategy.
315+
316+
```php
317+
$xml = $data->getNullableXML('child');
318+
```
319+
320+
### GetValue with XMLData
321+
322+
> Throws always `NotXMLException` exception if value is not a SimpleXMLElement. XML transformer strategy is applied.
323+
324+
Get always `GetValue` instance even if provided data is missing or if null.
325+
326+
```php
327+
$value = $data->getXMLGetter('key');
328+
```
329+
330+
Try to get nullable array from data and wrap it in `GetValue` instance.
331+
332+
```php
333+
$value = $data->getNullableXMLGetter('key');
334+
```
335+
336+
Try to get non-empty array from data and wrap it in `GetValue` instance. Throws `ArrayIsEmptyException` exception if
337+
missing.
338+
339+
```php
340+
$value = $data->getRequiredXMLGetter('key');
341+
```
342+
343+
### GetValue XML attributes
344+
345+
> Throws always `NotXMLException` exception if value is not a SimpleXMLElement. XML transformer strategy is applied.
346+
347+
Wraps XML element attributes in GetValue instance (even if attributes are not set in element).
348+
349+
Key contains `@attributes` like `title.@attributes.test`.
350+
351+
```php
352+
// Access attributes from root data
353+
$rootAttributes = $data->getXMLAttributesGetter();
354+
$rootAttributes->getString('attributeName');
355+
356+
// Access attributes from given element
357+
$attributes = $data->getXMLAttributesGetter('node');
358+
$attributes->getString('attributeName');
359+
```
360+
312361
## Exceptions
313362

314363
> All exceptions receive full key that was used for getting data. You can receive it by using `$exception->getKey()`

docs/content/en/transformers.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,32 @@ $transformer = new ArrayItemTransformer(function (mixed $value, string $key): ?a
221221
$values = $data->getArray('names', transformers: [$transformer]);
222222
// Result: [['Marco', 'Polo'], ['Way', 'Point'], null]
223223
```
224+
### GetterTransformer (since v0.6.0)
225+
226+
Transforms an **array/xml value** in a closure that receives wrapped GetValue instance.
227+
228+
```php
229+
use Wrkflow\GetValue\GetValue;
230+
use Wrkflow\GetValue\DataHolders\ArrayData;
231+
use Wrkflow\GetValue\Transformers\GetterTransformer;
232+
233+
$data = new GetValue(new ArrayData([
234+
'person' => ['name' => 'Marco', 'surname' => 'Polo'],
235+
]));
236+
237+
$transformer = new GetterTransformer(function (GetValue $value, string $key): string {
238+
return $value->getRequiredString('name') . ' '.$value->getRequiredString('surname');
239+
}, beforeValidation: true);
240+
241+
$value = $data->getString('person', transformers: [$transformer]);
242+
// Result: 'Marco Polo'
243+
```
224244

225245
### ArrayItemGetterTransformer
226246

227247
> Can be used only with get\*Array\* methods. Throws NotAnArrayException if array value is not an array.
228248
229-
Transforms an **array that contains array values** in a closure that receives wrapped array in GetValue.
249+
Transforms an **array/xml that contains array/xml values** in a closure that receives wrapped GetValue instance.
230250

231251
```php
232252
use Wrkflow\GetValue\GetValue;

src/Actions/GetValidatedValueAction.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Wrkflow\GetValue\Contracts\RuleContract;
88
use Wrkflow\GetValue\Contracts\TransformerContract;
9+
use Wrkflow\GetValue\Enums\ValueType;
910
use Wrkflow\GetValue\GetValue;
1011

1112
class GetValidatedValueAction
@@ -19,10 +20,15 @@ public function __construct(
1920
* @param array<RuleContract> $rules
2021
* @param array<TransformerContract> $transforms
2122
*/
22-
public function execute(GetValue $getValue, string|array $key, array $rules, array $transforms): mixed
23-
{
24-
$value = $getValue->data->getValue($key);
23+
public function execute(
24+
GetValue $getValue,
25+
ValueType $valueType,
26+
string|array $key,
27+
array $rules,
28+
array $transforms,
29+
): mixed {
2530
$fullKey = $getValue->data->getKey($key);
31+
$value = $getValue->data->getValue($key, $valueType);
2632

2733
$afterValidationTransforms = [];
2834

src/Builders/ExceptionBuilder.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
use Wrkflow\GetValue\Contracts\ExceptionBuilderContract;
99
use Wrkflow\GetValue\Exceptions\ArrayIsEmptyException;
1010
use Wrkflow\GetValue\Exceptions\MissingValueForKeyException;
11-
use Wrkflow\GetValue\Exceptions\NotAnArrayException;
11+
use Wrkflow\GetValue\Exceptions\NotSupportedDataException;
12+
use Wrkflow\GetValue\Exceptions\NotXMLException;
1213
use Wrkflow\GetValue\Exceptions\ValidationFailedException;
1314

1415
class ExceptionBuilder implements ExceptionBuilderContract
@@ -25,7 +26,7 @@ public function arrayIsEmpty(string $key): Exception
2526

2627
public function notAnArray(string $key): Exception
2728
{
28-
return new NotAnArrayException($key);
29+
return new NotSupportedDataException($key);
2930
}
3031

3132
public function validationFailed(string $key, string $ruleClassName): Exception
@@ -35,4 +36,9 @@ public function validationFailed(string $key, string $ruleClassName): Exception
3536

3637
return new ValidationFailedException($key, $shortClassName . ' failed');
3738
}
39+
40+
public function notXML(string $key): Exception
41+
{
42+
return new NotXMLException($key);
43+
}
3844
}

src/Contracts/ExceptionBuilderContract.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@ public function notAnArray(string $key): Exception;
1818
* @param class-string<RuleContract> $ruleClassName
1919
*/
2020
public function validationFailed(string $key, string $ruleClassName): Exception;
21+
22+
public function notXML(string $key): Exception;
2123
}

src/Contracts/TransformerStrategy.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,9 @@ public function float(): array;
3535
* @return array<TransformerContract>
3636
*/
3737
public function array(): array;
38+
39+
/**
40+
* @return array<TransformerContract>
41+
*/
42+
public function xml(): array;
3843
}

src/DataHolders/AbstractData.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44

55
namespace Wrkflow\GetValue\DataHolders;
66

7+
use Wrkflow\GetValue\Enums\ValueType;
8+
79
abstract class AbstractData
810
{
911
public function __construct(private readonly string $parentKey = '')
1012
{
1113
}
1214

13-
abstract public function getValue(string|array $key): mixed;
15+
abstract public function getValue(string|array $key, ValueType $expectedValueType): mixed;
1416

1517
abstract public function get(): mixed;
1618

src/DataHolders/ArrayData.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace Wrkflow\GetValue\DataHolders;
66

7+
use Wrkflow\GetValue\Enums\ValueType;
8+
79
class ArrayData extends AbstractData
810
{
911
public function __construct(
@@ -13,7 +15,7 @@ public function __construct(
1315
parent::__construct($parentKey);
1416
}
1517

16-
public function getValue(string|array $key): mixed
18+
public function getValue(string|array $key, ValueType $expectedValueType): mixed
1719
{
1820
if (is_string($key) && str_contains($key, '.')) {
1921
$key = explode('.', $key);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Wrkflow\GetValue\DataHolders;
6+
7+
use SimpleXMLElement;
8+
use Wrkflow\GetValue\Enums\ValueType;
9+
use Wrkflow\GetValue\Exceptions\AttributesDotNotationException;
10+
11+
class XMLAttributesData extends AbstractData
12+
{
13+
public function __construct(
14+
private readonly SimpleXMLElement $data,
15+
string $parentKey = ''
16+
) {
17+
parent::__construct($parentKey);
18+
}
19+
20+
public function getValue(string|array $key, ValueType $expectedValueType): ?string
21+
{
22+
if (is_array($key)) {
23+
throw new AttributesDotNotationException(implode('.', $key));
24+
} elseif (str_contains($key, '.')) {
25+
throw new AttributesDotNotationException($key);
26+
}
27+
28+
$value = $this->data->{$key};
29+
30+
if ($value instanceof SimpleXMLElement === false) {
31+
return null;
32+
}
33+
34+
return (string) $value;
35+
}
36+
37+
public function get(): SimpleXMLElement
38+
{
39+
return $this->data;
40+
}
41+
}

src/DataHolders/XMLData.php

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Wrkflow\GetValue\DataHolders;
66

77
use SimpleXMLElement;
8+
use Wrkflow\GetValue\Enums\ValueType;
89

910
class XMLData extends AbstractData
1011
{
@@ -15,18 +16,14 @@ public function __construct(
1516
parent::__construct($parentKey);
1617
}
1718

18-
public function getValue(string|array $key): ?string
19+
public function getValue(string|array $key, ValueType $expectedValueType): SimpleXMLElement|array|string|null
1920
{
2021
if (is_string($key) && str_contains($key, '.')) {
2122
$key = explode('.', $key);
2223
} elseif (is_string($key)) {
2324
$value = $this->data->{$key};
2425

25-
if ($value->count() !== 0) {
26-
return (string) $value;
27-
}
28-
29-
return null;
26+
return $this->normalizeValue($expectedValueType, $value);
3027
}
3128

3229
$element = $this->data;
@@ -41,11 +38,36 @@ public function getValue(string|array $key): ?string
4138
$element = $value;
4239
}
4340

44-
return (string) $element;
41+
return $this->normalizeValue($expectedValueType, $element);
4542
}
4643

4744
public function get(): SimpleXMLElement
4845
{
4946
return $this->data;
5047
}
48+
49+
protected function normalizeValue(ValueType $valueType, SimpleXMLElement $value): string|array|null|SimpleXMLElement
50+
{
51+
if ($valueType === ValueType::XML) {
52+
if ($value->count() === 0) {
53+
return null;
54+
}
55+
56+
return $value;
57+
} elseif ($valueType === ValueType::XMLAttributes) {
58+
return $value;
59+
} elseif ($valueType === ValueType::Array) {
60+
$return = [];
61+
62+
foreach ($value as $val) {
63+
$return[] = $val;
64+
}
65+
66+
return $return;
67+
} elseif ($value->count() !== 0) {
68+
return (string) $value;
69+
}
70+
71+
return null;
72+
}
5173
}

0 commit comments

Comments
 (0)