From 70d13589ac32a1330bd40bbc761b70955d36b4b3 Mon Sep 17 00:00:00 2001 From: Ryan Mitchell Date: Tue, 1 Oct 2024 08:02:04 +0100 Subject: [PATCH] Support rendering model attributes in Antlers --- .../Language/Runtime/PathDataManager.php | 17 +++++++ tests/Antlers/Runtime/ModelTest.php | 44 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 tests/Antlers/Runtime/ModelTest.php diff --git a/src/View/Antlers/Language/Runtime/PathDataManager.php b/src/View/Antlers/Language/Runtime/PathDataManager.php index 050083e87a..1d1eac1658 100644 --- a/src/View/Antlers/Language/Runtime/PathDataManager.php +++ b/src/View/Antlers/Language/Runtime/PathDataManager.php @@ -4,6 +4,8 @@ use Exception; use Illuminate\Contracts\Support\Arrayable; +use Illuminate\Database\Eloquent\Casts\Attribute; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log; @@ -1014,6 +1016,21 @@ public static function reduce($value, $isPair = true, $reduceBuildersAndAugmenta $reductionStack[] = $reductionValue->all(); GlobalRuntimeState::$isEvaluatingData = false; + continue; + } elseif ($reductionValue instanceof Model) { + GlobalRuntimeState::$isEvaluatingData = true; + $data = $reductionValue->toArray(); + + foreach (get_class_methods($reductionValue) as $method) { + if ((new \ReflectionMethod($reductionValue, $method))->getReturnType()?->getName() === Attribute::class) { + $method = Str::snake($method); + $data[$method] = $reductionValue->$method; + } + } + + $reductionStack[] = $data; + GlobalRuntimeState::$isEvaluatingData = false; + continue; } elseif ($reductionValue instanceof Arrayable) { GlobalRuntimeState::$isEvaluatingData = true; diff --git a/tests/Antlers/Runtime/ModelTest.php b/tests/Antlers/Runtime/ModelTest.php new file mode 100644 index 0000000000..9e992a692f --- /dev/null +++ b/tests/Antlers/Runtime/ModelTest.php @@ -0,0 +1,44 @@ +title = 'Title'; + + $data = [ + 'model' => $model, + ]; + + $template = <<<'EOT' +{{ model:title }}{{ model:foo_bar }} +EOT; + + $this->assertSame('TitleFooBar', $this->renderString($template, $data)); + } +} + +class FakeModel extends \Illuminate\Database\Eloquent\Model +{ + public function fooBar(): Attribute + { + return Attribute::make( + get: fn() => 'FooBar', + ); + } +}