Skip to content

Commit 3e22298

Browse files
committed
Check for attributes overlapping with the reserved ones (action, targets), use the same rendering for the reserved and user-defined attributes.
1 parent 69fcf9f commit 3e22298

File tree

2 files changed

+43
-8
lines changed

2 files changed

+43
-8
lines changed

src/Turbo/src/Helper/TurboStream.php

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ public static function prepend(string $target, string $html): string
3737
*/
3838
public static function replace(string $target, string $html, bool $morph = false): string
3939
{
40-
return self::custom('replace', $target, $html, $morph ? ['method="morph"'] : []);
40+
return self::custom('replace', $target, $html, $morph ? ['method' => 'morph'] : []);
4141
}
4242

4343
/**
4444
* Updates the content of the element(s) designated by the target CSS selector.
4545
*/
4646
public static function update(string $target, string $html, bool $morph = false): string
4747
{
48-
return self::custom('update', $target, $html, $morph ? ['method="morph"'] : []);
48+
return self::custom('update', $target, $html, $morph ? ['method' => 'morph'] : []);
4949
}
5050

5151
/**
@@ -87,17 +87,33 @@ public static function refresh(?string $requestId = null): string
8787
}
8888

8989
/**
90-
* @param array<string> $attr
90+
* Custom action and attributes.
91+
*
92+
* @param array<string, string|int|null> $attr
9193
*/
9294
public static function custom(string $action, string $target, string $html, array $attr = []): string
9395
{
94-
// Join array elements with a space and prepend a leading space
95-
$atrrString = empty($attr) ? '' : ' '.implode(' ', $attr);
96+
if (\array_key_exists('action', $attr) || \array_key_exists('targets', $attr)) {
97+
throw new \InvalidArgumentException('The "action" and "targets" attributes are reserved and cannot be used.');
98+
}
99+
100+
$attr['action'] = $action;
101+
$attr['targets'] = $target;
102+
$attr = array_merge(['action' => $action, 'targets' => $target], $attr);
103+
104+
$attrString = '';
105+
foreach ($attr as $key => $value) {
106+
if ($value === null) {
107+
$attrString .= sprintf(' %s', $key);
108+
}else{
109+
$attrString .= sprintf(' %s="%s"', $key, is_string($value) ? htmlspecialchars($value) : $value);
110+
}
111+
}
96112

97113
return \sprintf(<<<EOHTML
98-
<turbo-stream action="%s" targets="%s"%s>
114+
<turbo-stream%s>
99115
<template>%s</template>
100116
</turbo-stream>
101-
EOHTML, $action, htmlspecialchars($target), $atrrString, $html);
117+
EOHTML, $attrString, $html);
102118
}
103119
}

src/Turbo/tests/Helper/TurboStreamTest.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\UX\Turbo\Tests\Helper;
1313

14+
use PHPUnit\Framework\Attributes\DataProvider;
15+
use PHPUnit\Framework\Attributes\TestWith;
1416
use PHPUnit\Framework\TestCase;
1517
use Symfony\UX\Turbo\Helper\TurboStream;
1618

@@ -84,7 +86,24 @@ public function testCustom(): void
8486
<template><div>content</div></template>
8587
</turbo-stream>
8688
EOHTML,
87-
TurboStream::custom('customAction', 'some["selector"]', '<div>content</div>', ['someAttr="someValue"', 'boolAttr'])
89+
TurboStream::custom('customAction', 'some["selector"]', '<div>content</div>', ['someAttr' => 'someValue', 'boolAttr' => null])
8890
);
8991
}
92+
93+
/**
94+
* @dataProvider customThrowsExceptionDataProvider
95+
*
96+
* @param array<string, string|int|null> $attr
97+
*/
98+
public function testCustomThrowsException(string $action, string $target, string $html, array $attr): void
99+
{
100+
$this->expectException(\InvalidArgumentException::class);
101+
TurboStream::custom($action, $target, $html, $attr);
102+
}
103+
104+
public static function customThrowsExceptionDataProvider(): \Generator
105+
{
106+
yield ['customAction', 'some["selector"]', '<div>content</div>', ['action' => 'someAction']];
107+
yield ['customAction', 'some["selector"]', '<div>content</div>', ['targets' => 'someTargets']];
108+
}
90109
}

0 commit comments

Comments
 (0)