From 702250d685b4913674dfc3cbc00115fc8d9b4c2e Mon Sep 17 00:00:00 2001 From: matheo Date: Wed, 27 Sep 2023 14:12:26 +0200 Subject: [PATCH] =?UTF-8?q?Fix=20Anonymous=20component=20props=20and=20Cla?= =?UTF-8?q?ss=20backed=20component=20properties=20d=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/TwigComponent/src/ComponentRenderer.php | 7 ++++--- src/TwigComponent/src/Twig/PropsNode.php | 2 +- ...us_component_with_variable_already_in_context.html.twig | 5 +++++ .../tests/Fixtures/templates/components/Message.html.twig | 5 +++++ .../tests/Integration/ComponentExtensionTest.php | 7 +++++++ 5 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 src/TwigComponent/tests/Fixtures/templates/anonymous_component_with_variable_already_in_context.html.twig create mode 100644 src/TwigComponent/tests/Fixtures/templates/components/Message.html.twig diff --git a/src/TwigComponent/src/ComponentRenderer.php b/src/TwigComponent/src/ComponentRenderer.php index 706efe3e093..d2d87ad4b90 100644 --- a/src/TwigComponent/src/ComponentRenderer.php +++ b/src/TwigComponent/src/ComponentRenderer.php @@ -120,6 +120,8 @@ private function preRender(MountedComponent $mounted, array $context = []): PreR $component = $mounted->getComponent(); $metadata = $this->factory->metadataFor($mounted->getName()); + // expose public properties and properties marked with ExposeInTemplate attribute + $props = iterator_to_array($this->exposedVariables($component, $metadata->isPublicPropsExposed())); $variables = array_merge( // first so values can be overridden $context, @@ -132,9 +134,8 @@ private function preRender(MountedComponent $mounted, array $context = []): PreR // add attributes [$metadata->getAttributesVar() => $mounted->getAttributes()], - - // expose public properties and properties marked with ExposeInTemplate attribute - iterator_to_array($this->exposedVariables($component, $metadata->isPublicPropsExposed())), + $props, + ['__props' => $props] ); $event = new PreRenderEvent($mounted, $metadata, $variables); diff --git a/src/TwigComponent/src/Twig/PropsNode.php b/src/TwigComponent/src/Twig/PropsNode.php index 92932a5d53f..26592854ce4 100644 --- a/src/TwigComponent/src/Twig/PropsNode.php +++ b/src/TwigComponent/src/Twig/PropsNode.php @@ -37,7 +37,7 @@ public function compile(Compiler $compiler): void $compiler ->write('$propsNames[] = \''.$name.'\';') ->write('$context[\'attributes\'] = $context[\'attributes\']->remove(\''.$name.'\');') - ->write('if (!isset($context[\''.$name.'\'])) {'); + ->write('if (!isset($context[\'__props\'][\''.$name.'\'])) {'); if (!$this->hasNode($name)) { $compiler diff --git a/src/TwigComponent/tests/Fixtures/templates/anonymous_component_with_variable_already_in_context.html.twig b/src/TwigComponent/tests/Fixtures/templates/anonymous_component_with_variable_already_in_context.html.twig new file mode 100644 index 00000000000..803e2c8572a --- /dev/null +++ b/src/TwigComponent/tests/Fixtures/templates/anonymous_component_with_variable_already_in_context.html.twig @@ -0,0 +1,5 @@ +{% set message = 'bar' %} + + +

Hey!

+
\ No newline at end of file diff --git a/src/TwigComponent/tests/Fixtures/templates/components/Message.html.twig b/src/TwigComponent/tests/Fixtures/templates/components/Message.html.twig new file mode 100644 index 00000000000..74d3279110a --- /dev/null +++ b/src/TwigComponent/tests/Fixtures/templates/components/Message.html.twig @@ -0,0 +1,5 @@ +{% props message = 'foo' %} + +

{{ message }}

+{% block content %} +{% endblock %} \ No newline at end of file diff --git a/src/TwigComponent/tests/Integration/ComponentExtensionTest.php b/src/TwigComponent/tests/Integration/ComponentExtensionTest.php index 1e238f8d694..1fd8a961ac2 100644 --- a/src/TwigComponent/tests/Integration/ComponentExtensionTest.php +++ b/src/TwigComponent/tests/Integration/ComponentExtensionTest.php @@ -195,6 +195,13 @@ public function testRenderAnonymousComponentWithNonScalarProps(): void $this->assertStringContainsString('class variable defined? no', $output); } + public function testComponentPropsOverwriteContextValue(): void + { + $output = self::getContainer()->get(Environment::class)->render('anonymous_component_with_variable_already_in_context.html.twig'); + + $this->assertStringContainsString('

foo

', $output); + } + private function renderComponent(string $name, array $data = []): string { return self::getContainer()->get(Environment::class)->render('render_component.html.twig', [