From 1a5285f3ba9474669a252a435cf6068167e10ab5 Mon Sep 17 00:00:00 2001 From: Chris Morrell Date: Wed, 20 Jan 2021 14:01:27 -0500 Subject: [PATCH] Make public component methods available in view (#2352) * Make public component methods available in view * Remove unnecessary import --- src/Component.php | 14 +++++- ...PublicMethodsAreAvailableInTheViewTest.php | 49 +++++++++++++++++++ .../Unit/views/call-name-with-this.blade.php | 1 + tests/Unit/views/call-name.blade.php | 1 + 4 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 tests/Unit/PublicMethodsAreAvailableInTheViewTest.php create mode 100644 tests/Unit/views/call-name-with-this.blade.php create mode 100644 tests/Unit/views/call-name.blade.php diff --git a/src/Component.php b/src/Component.php index 377d0a80d..d3044a71a 100644 --- a/src/Component.php +++ b/src/Component.php @@ -165,7 +165,7 @@ public function output($errors = null) $view->with([ 'errors' => $errors, '_instance' => $this, - ] + $this->getPublicPropertiesDefinedBySubClass()); + ] + $this->getPublicPropertiesDefinedBySubClass() + $this->mapPublicMethodsToClosures()); app('view')->share('errors', $errors); app('view')->share('_instance', $this); @@ -182,6 +182,18 @@ public function output($errors = null) return $output; } + public function mapPublicMethodsToClosures() + { + return collect((new \ReflectionClass($this))->getMethods(\ReflectionMethod::IS_PUBLIC)) + ->reject(function($method) { + return $method->getDeclaringClass() === self::class || Str::startsWith($method->getName(), '__'); + }) + ->mapWithKeys(function($method) { + return [$method->getName() => $method->getClosure($this)]; + }) + ->all(); + } + public function normalizePublicPropertiesForJavaScript() { foreach ($this->getPublicPropertiesDefinedBySubClass() as $key => $value) { diff --git a/tests/Unit/PublicMethodsAreAvailableInTheViewTest.php b/tests/Unit/PublicMethodsAreAvailableInTheViewTest.php new file mode 100644 index 000000000..42c24ef80 --- /dev/null +++ b/tests/Unit/PublicMethodsAreAvailableInTheViewTest.php @@ -0,0 +1,49 @@ +assertSee('Your Name is Chris'); + } + + /** @test */ + public function public_methods_are_accessible_in_view_without_this() + { + Livewire::test(PublicMethodsInViewWithoutThisStub::class) + ->assertSee('Your Name is Chris'); + } +} + +class PublicMethodsInViewWithThisStub extends Component +{ + public function render() + { + return app('view')->make('call-name-with-this'); + } + + public function name($name) + { + return 'Your Name is '.$name; + } +} + +class PublicMethodsInViewWithoutThisStub extends Component +{ + public function render() + { + return app('view')->make('call-name'); + } + + public function name($name) + { + return 'Your Name is '.$name; + } +} diff --git a/tests/Unit/views/call-name-with-this.blade.php b/tests/Unit/views/call-name-with-this.blade.php new file mode 100644 index 000000000..8651c400c --- /dev/null +++ b/tests/Unit/views/call-name-with-this.blade.php @@ -0,0 +1 @@ +{{ $this->name('Chris') }} diff --git a/tests/Unit/views/call-name.blade.php b/tests/Unit/views/call-name.blade.php new file mode 100644 index 000000000..7f6942e8a --- /dev/null +++ b/tests/Unit/views/call-name.blade.php @@ -0,0 +1 @@ +{{ $name('Chris') }}