diff --git a/flight/template/View.php b/flight/template/View.php index 8983db5..453f533 100644 --- a/flight/template/View.php +++ b/flight/template/View.php @@ -4,7 +4,9 @@ declare(strict_types=1); namespace flight\template; +use Closure; use Exception; +use ReflectionFunction; /** * The View class represents output to be displayed. It provides @@ -153,7 +155,8 @@ class View switch (true) { case is_callable($component): - $view = $component(); + $arguments = $this->getCallableArguments($component, $data); + $view = $component(...$arguments); ob_end_clean(); break; @@ -290,4 +293,39 @@ class View ): string { return str_replace(['\\', '/'], $separator, $path); } + + /** + * @param callable $component + * @param ?array $data + * @return array + */ + private function getCallableArguments(callable $component, ?array $data): array + { + if (!is_array($data) || !$data) { + return []; + } + + $arguments = []; + $remainingData = $data; + $reflection = new ReflectionFunction(Closure::fromCallable($component)); + + foreach ($reflection->getParameters() as $parameter) { + if ($parameter->isVariadic()) { + foreach ($remainingData as $value) { + $arguments[] = $value; + } + + break; + } + + $name = $parameter->getName(); + + if (array_key_exists($name, $remainingData)) { + $arguments[] = $remainingData[$name]; + unset($remainingData[$name]); + } + } + + return $arguments; + } } diff --git a/tests/ViewTest.php b/tests/ViewTest.php index ce37cd6..78c5d2d 100644 --- a/tests/ViewTest.php +++ b/tests/ViewTest.php @@ -308,6 +308,27 @@ class ViewTest extends TestCase my-class-component html, ], + [ + 'page-with-functional-component-with-props', + <<<'html' + functional-component-with-props: Astronaut Victoria + html, + ['name' => 'Victoria', 'occupation' => 'Astronaut'], + ], + [ + 'page-with-functional-component-with-individual-props', + <<<'html' + functional-component-with-individual-props: Astronaut Victoria + html, + ['name' => 'Victoria', 'occupation' => 'Astronaut'], + ], + [ + 'page-with-class-component-with-props', + <<<'html' + class-component-with-props: Astronaut Victoria + html, + ['name' => 'Victoria', 'occupation' => 'Astronaut'], + ], [ 'page-with-class-component-with-styles', <<<'html' diff --git a/tests/views/components/my-class-component-with-props.php b/tests/views/components/my-class-component-with-props.php new file mode 100644 index 0000000..66abcad --- /dev/null +++ b/tests/views/components/my-class-component-with-props.php @@ -0,0 +1,22 @@ +name = $name; + $this->occupation = $occupation; + } + + public function html(): string + { + return "class-component-with-props: $this->occupation $this->name"; + } +}; diff --git a/tests/views/components/my-functional-component-with-individual-props.php b/tests/views/components/my-functional-component-with-individual-props.php new file mode 100644 index 0000000..9f3bdb9 --- /dev/null +++ b/tests/views/components/my-functional-component-with-individual-props.php @@ -0,0 +1,6 @@ + + "functional-component-with-individual-props: $occupation $name"; diff --git a/tests/views/components/my-functional-component-with-props.php b/tests/views/components/my-functional-component-with-props.php new file mode 100644 index 0000000..ef8856e --- /dev/null +++ b/tests/views/components/my-functional-component-with-props.php @@ -0,0 +1,9 @@ + sprintf( + 'functional-component-with-props: %s %s', + $props[1] ?? '', + $props[0] ?? '' +); diff --git a/tests/views/pages/page-with-class-component-with-props.php b/tests/views/pages/page-with-class-component-with-props.php new file mode 100644 index 0000000..a2bd6d9 --- /dev/null +++ b/tests/views/pages/page-with-class-component-with-props.php @@ -0,0 +1 @@ + diff --git a/tests/views/pages/page-with-functional-component-with-individual-props.php b/tests/views/pages/page-with-functional-component-with-individual-props.php new file mode 100644 index 0000000..f77480a --- /dev/null +++ b/tests/views/pages/page-with-functional-component-with-individual-props.php @@ -0,0 +1 @@ + diff --git a/tests/views/pages/page-with-functional-component-with-props.php b/tests/views/pages/page-with-functional-component-with-props.php new file mode 100644 index 0000000..dddef9f --- /dev/null +++ b/tests/views/pages/page-with-functional-component-with-props.php @@ -0,0 +1 @@ +