Skip to content

Commit 2ff95f1

Browse files
committed
RecorsTrait::with() use clone with and polyfill for 8.4 #1236
1 parent 0a7d2e8 commit 2ff95f1

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

src/ReadonlyCloneableTrait.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Windwalker\Data;
6+
7+
trait ReadonlyCloneableTrait
8+
{
9+
public function cloneWith(array $data): static
10+
{
11+
$ref = new \ReflectionClass($this);
12+
$new = $ref->newInstanceWithoutConstructor();
13+
14+
foreach ($ref->getProperties() as $property) {
15+
if (array_key_exists($property->getName(), $data)) {
16+
$property->setValue($new, $data[$property->getName()]);
17+
} else {
18+
$property->setValue($new, $property->getValue($this));
19+
}
20+
}
21+
22+
return $new;
23+
}
24+
}

src/RecordTrait.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,16 @@ public function withDefaults(mixed $values, bool $recursive = false): static
124124

125125
public function with(...$data): static
126126
{
127+
if (PHP_VERSION_ID >= 80500) {
128+
include_once __DIR__ . '/clone_with.php';
129+
130+
return cloneWithPolyfill($this, $data);
131+
}
132+
133+
if (method_exists($this, 'cloneWith')) {
134+
return $this->cloneWith($data);
135+
}
136+
127137
$new = clone $this;
128138

129139
return $new->fill($data);

src/clone_with.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Windwalker\Data {
6+
function cloneWithPolyfill(object $object, array $data): object
7+
{
8+
$fun = fn (array $data) => clone($object, $data);
9+
$fun = $fun->bindTo($object, $object);
10+
11+
return $fun($data);
12+
}
13+
}

0 commit comments

Comments
 (0)