|
19 | 19 | use function array_shift; |
20 | 20 | use function array_walk; |
21 | 21 | use function count; |
| 22 | +use function get_debug_type; |
22 | 23 | use function gettype; |
23 | 24 | use function in_array; |
24 | 25 | use function is_array; |
@@ -47,32 +48,46 @@ class HalResource implements EvolvableLinkProviderInterface, JsonSerializable |
47 | 48 | * @param LinkInterface[] $links |
48 | 49 | * @param HalResource[][] $embedded |
49 | 50 | */ |
50 | | - public function __construct(array $data = [], array $links = [], array $embedded = []) |
51 | | - { |
| 51 | + public function __construct( |
| 52 | + array $data = [], |
| 53 | + array $links = [], |
| 54 | + array $embedded = [], |
| 55 | + private bool $embedEmptyCollections = false |
| 56 | + ) { |
| 57 | + $this->embedEmptyCollections = $embedEmptyCollections; |
| 58 | + |
52 | 59 | $context = self::class; |
| 60 | + |
53 | 61 | array_walk($data, function ($value, $name) use ($context) { |
54 | 62 | $this->validateElementName($name, $context); |
55 | | - if ( |
56 | | - ! empty($value) |
57 | | - && ($value instanceof self || $this->isResourceCollection($value)) |
58 | | - ) { |
| 63 | + |
| 64 | + if ($value instanceof self || $this->isResourceCollection($value)) { |
59 | 65 | $this->embedded[$name] = $value; |
60 | 66 | return; |
61 | 67 | } |
| 68 | + |
62 | 69 | $this->data[$name] = $value; |
63 | 70 | }); |
64 | 71 |
|
65 | 72 | array_walk($embedded, function ($resource, $name) use ($context) { |
66 | 73 | $this->validateElementName($name, $context); |
67 | 74 | $this->detectCollisionWithData($name, $context); |
68 | | - if (! ($resource instanceof self || $this->isResourceCollection($resource))) { |
69 | | - throw new InvalidArgumentException(sprintf( |
70 | | - 'Invalid embedded resource provided to %s constructor with name "%s"', |
71 | | - $context, |
72 | | - $name |
73 | | - )); |
| 75 | + |
| 76 | + if ( |
| 77 | + $resource instanceof self || |
| 78 | + $resource === [] || |
| 79 | + $this->isResourceCollection($resource) |
| 80 | + ) { |
| 81 | + $this->embedded[$name] = $resource; |
| 82 | + return; |
74 | 83 | } |
75 | | - $this->embedded[$name] = $resource; |
| 84 | + |
| 85 | + throw new InvalidArgumentException(sprintf( |
| 86 | + 'Invalid embedded resource provided to %s constructor with name "%s":"%s"', |
| 87 | + $context, |
| 88 | + $name, |
| 89 | + get_debug_type($resource) |
| 90 | + )); |
76 | 91 | }); |
77 | 92 |
|
78 | 93 | if ( |
@@ -142,8 +157,7 @@ public function withElement(string $name, $value): HalResource |
142 | 157 | $this->validateElementName($name, __METHOD__); |
143 | 158 |
|
144 | 159 | if ( |
145 | | - ! empty($value) |
146 | | - && ($value instanceof self || $this->isResourceCollection($value)) |
| 160 | + $value instanceof self || $this->isResourceCollection($value) |
147 | 161 | ) { |
148 | 162 | return $this->embed($name, $value); |
149 | 163 | } |
@@ -395,6 +409,10 @@ private function isResourceCollection($value): bool |
395 | 409 | return false; |
396 | 410 | } |
397 | 411 |
|
| 412 | + if ($value === []) { |
| 413 | + return $this->embedEmptyCollections; |
| 414 | + } |
| 415 | + |
398 | 416 | return array_reduce($value, static function ($isResource, $item) { |
399 | 417 | return $isResource && $item instanceof self; |
400 | 418 | }, true); |
|
0 commit comments