Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/view/src/Elements/ViewComponentElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Tempest\Support\Str\ImmutableString;
use Tempest\Support\Str\MutableString;
use Tempest\View\Element;
use Tempest\View\Export\ViewObjectExporter;
use Tempest\View\Parser\TempestViewCompiler;
use Tempest\View\Parser\TempestViewParser;
use Tempest\View\Parser\Token;
Expand Down Expand Up @@ -112,7 +113,7 @@ public function compile(): string
);

// Add scoped variables
$slots = $this->getSlots()->toArray();
$slots = $this->getSlots();

$compiled = $compiled
->prepend(
Expand All @@ -122,7 +123,7 @@ public function compile(): string

// Add dynamic slots to the current scope
'<?php $_previousSlots = $slots ?? null; ?>', // Store previous slots in temporary variable to keep scope
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
sprintf('<?php $slots = %s; ?>', ViewObjectExporter::export($slots)),
)
->append(
// Restore previous slots
Expand Down
14 changes: 14 additions & 0 deletions packages/view/src/Export/ExportableViewObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Tempest\View\Export;

use Tempest\Support\Arr\ImmutableArray;

interface ExportableViewObject
{
public ImmutableArray $exportData {
get;
}

public static function restore(mixed ...$data): self;
}
40 changes: 40 additions & 0 deletions packages/view/src/Export/ViewObjectExporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Tempest\View\Export;

use Tempest\Support\Arr\ImmutableArray;

final class ViewObjectExporter
{
public static function export(ExportableViewObject|ImmutableArray $object): string
{
if ($object instanceof ImmutableArray) {
return sprintf(
'new \%s([%s])',
ImmutableArray::class,
$object->map(function (mixed $value, string|int $key) {
$key = is_int($key) ? $key : "'{$key}'";

return $key . ' => ' . rtrim(self::export($value), ';');
})->implode(', '),
);
}

return sprintf(
'\%s::restore(%s);',
$object::class,
$object
->exportData
->map(function (mixed $value, string $key) {
$value = match (true) {
$value instanceof ExportableViewObject => self::export($value),
is_string($value) => "<<<'STRING'" . PHP_EOL . $value . PHP_EOL . 'STRING',
default => var_export($value, true), // @mago-expect best-practices/no-debug-symbols
};

return "{$key} : {$value}";
})
->implode(','),
);
}
}
39 changes: 31 additions & 8 deletions packages/view/src/Slot.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,45 @@

namespace Tempest\View;

use Tempest\Reflection\ClassReflector;
use Tempest\Support\Arr\ImmutableArray;
use Tempest\View\Export\ExportableViewObject;
use Tempest\View\Parser\Token;

final class Slot
final class Slot implements ExportableViewObject
{
public const string DEFAULT = 'default';

public function __construct(
public string $name,
public array $attributes,
public string $content,
) {}
string $content,
) {
$this->content = base64_encode($content);
}

public string $content {
get => base64_decode($this->content);

Check warning on line 25 in packages/view/src/Slot.php

View workflow job for this annotation

GitHub Actions / Run style check

strictness/require-strict-behavior

Call to `base64_decode` must enforce strict comparison. Help: Call the function `base64_decode` with the `$strict` parameter set to `true`.
}

public ImmutableArray $exportData {
get => new ImmutableArray([
'name' => $this->name,
'attributes' => $this->attributes,
'content' => base64_encode($this->content),
]);
}

public static function restore(mixed ...$data): ExportableViewObject
{
$self = new ClassReflector(self::class)->newInstanceWithoutConstructor();

$self->name = $data['name'];
$self->attributes = $data['attributes'];
$self->content = $data['content'];

return $self;
}

public function __get(string $name): mixed
{
Expand Down Expand Up @@ -50,9 +78,4 @@
content: $content,
);
}

public static function __set_state(array $array): object
{
return new self(...$array);
}
}