Skip to content

Commit 4284e8b

Browse files
authored
refactor(view): improve slot importing to prevent view compiler failures (#1431)
1 parent b81b9ed commit 4284e8b

File tree

4 files changed

+88
-10
lines changed

4 files changed

+88
-10
lines changed

packages/view/src/Elements/ViewComponentElement.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Tempest\Support\Str\ImmutableString;
1010
use Tempest\Support\Str\MutableString;
1111
use Tempest\View\Element;
12+
use Tempest\View\Export\ViewObjectExporter;
1213
use Tempest\View\Parser\TempestViewCompiler;
1314
use Tempest\View\Parser\TempestViewParser;
1415
use Tempest\View\Parser\Token;
@@ -112,7 +113,7 @@ public function compile(): string
112113
);
113114

114115
// Add scoped variables
115-
$slots = $this->getSlots()->toArray();
116+
$slots = $this->getSlots();
116117

117118
$compiled = $compiled
118119
->prepend(
@@ -122,7 +123,7 @@ public function compile(): string
122123

123124
// Add dynamic slots to the current scope
124125
'<?php $_previousSlots = $slots ?? null; ?>', // Store previous slots in temporary variable to keep scope
125-
sprintf('<?php $slots = \Tempest\Support\arr(%s); ?>', var_export($slots, true)), // @mago-expect best-practices/no-debug-symbols Set the new value of $slots for this view component
126+
sprintf('<?php $slots = %s; ?>', ViewObjectExporter::export($slots)),
126127
)
127128
->append(
128129
// Restore previous slots
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Tempest\View\Export;
4+
5+
use Tempest\Support\Arr\ImmutableArray;
6+
7+
interface ExportableViewObject
8+
{
9+
public ImmutableArray $exportData {
10+
get;
11+
}
12+
13+
public static function restore(mixed ...$data): self;
14+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace Tempest\View\Export;
4+
5+
use Tempest\Support\Arr\ImmutableArray;
6+
7+
final class ViewObjectExporter
8+
{
9+
public static function export(ExportableViewObject|ImmutableArray $object): string
10+
{
11+
if ($object instanceof ImmutableArray) {
12+
return sprintf(
13+
'new \%s([%s])',
14+
ImmutableArray::class,
15+
$object->map(function (mixed $value, string|int $key) {
16+
$key = is_int($key) ? $key : "'{$key}'";
17+
18+
return $key . ' => ' . rtrim(self::export($value), ';');
19+
})->implode(', '),
20+
);
21+
}
22+
23+
return sprintf(
24+
'\%s::restore(%s);',
25+
$object::class,
26+
$object
27+
->exportData
28+
->map(function (mixed $value, string $key) {
29+
$value = match (true) {
30+
$value instanceof ExportableViewObject => self::export($value),
31+
is_string($value) => "<<<'STRING'" . PHP_EOL . $value . PHP_EOL . 'STRING',
32+
default => var_export($value, true), // @mago-expect best-practices/no-debug-symbols
33+
};
34+
35+
return "{$key} : {$value}";
36+
})
37+
->implode(','),
38+
);
39+
}
40+
}

packages/view/src/Slot.php

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,45 @@
44

55
namespace Tempest\View;
66

7+
use Tempest\Reflection\ClassReflector;
8+
use Tempest\Support\Arr\ImmutableArray;
9+
use Tempest\View\Export\ExportableViewObject;
710
use Tempest\View\Parser\Token;
811

9-
final class Slot
12+
final class Slot implements ExportableViewObject
1013
{
1114
public const string DEFAULT = 'default';
1215

1316
public function __construct(
1417
public string $name,
1518
public array $attributes,
16-
public string $content,
17-
) {}
19+
string $content,
20+
) {
21+
$this->content = base64_encode($content);
22+
}
23+
24+
public string $content {
25+
get => base64_decode($this->content);
26+
}
27+
28+
public ImmutableArray $exportData {
29+
get => new ImmutableArray([
30+
'name' => $this->name,
31+
'attributes' => $this->attributes,
32+
'content' => base64_encode($this->content),
33+
]);
34+
}
35+
36+
public static function restore(mixed ...$data): ExportableViewObject
37+
{
38+
$self = new ClassReflector(self::class)->newInstanceWithoutConstructor();
39+
40+
$self->name = $data['name'];
41+
$self->attributes = $data['attributes'];
42+
$self->content = $data['content'];
43+
44+
return $self;
45+
}
1846

1947
public function __get(string $name): mixed
2048
{
@@ -50,9 +78,4 @@ public static function default(Token ...$tokens): self
5078
content: $content,
5179
);
5280
}
53-
54-
public static function __set_state(array $array): object
55-
{
56-
return new self(...$array);
57-
}
5881
}

0 commit comments

Comments
 (0)