diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 94cebab..5b90d64 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: php: ['8.2', '8.3', '8.4'] - laravel: ['10.0', '10.48', '11.0', '11.36'] + laravel: ['10.0', '10.48', '11.0', '11.37'] name: PHP ${{ matrix.php }} Laravel ${{ matrix.laravel }} steps: - name: Checkout diff --git a/Changelog.md b/Changelog.md index c70a016..e30422d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,10 @@ # AppShell Changelog +## Unreleased +##### 2025-XX-YY + +- Added the `url` option to the avatar widget + ## 4.6.0 ##### 2024-12-19 diff --git a/src/Widgets/Avatar.php b/src/Widgets/Avatar.php index 9d04c08..1c88982 100644 --- a/src/Widgets/Avatar.php +++ b/src/Widgets/Avatar.php @@ -28,6 +28,9 @@ class Avatar implements Widget private const DEFAULT_AVATAR_SIZE = 50; + /** @var null|callable */ + private $url; + /** @var callable */ private $model; @@ -36,15 +39,20 @@ class Avatar implements Widget private ?int $size = null; - public function __construct(Theme $theme, callable $model) + public function __construct(Theme $theme, callable $model, ?callable $url = null) { $this->theme = $theme; $this->model = $model; + $this->url = $url; } public static function create(Theme $theme, array $options = []): Widget { - $instance = new static($theme, self::makeCallable($options['model'] ?? '$model')); + $instance = new static( + $theme, + self::makeCallable($options['model'] ?? '$model'), + isset($options['url']) ? self::makeCallable($options['url']) : null, + ); $instance->processRenderingConditions($options); if (isset($options['tooltip'])) { $instance->tooltip = self::makeCallable($options['tooltip']); @@ -67,6 +75,7 @@ public function render($data = null): string 'data' => call_user_func($this->model, $data, $this), 'tooltip' => null !== $this->tooltip ? call_user_func($this->tooltip, $data, $this) : null, 'size' => $this->size ?? self::DEFAULT_AVATAR_SIZE, + 'url' => null !== $this->url ? call_user_func($this->url, $data, $this) : null, ]); } } diff --git a/src/resources/views/widgets/avatar.blade.php b/src/resources/views/widgets/avatar.blade.php index 958cdec..06b214c 100644 --- a/src/resources/views/widgets/avatar.blade.php +++ b/src/resources/views/widgets/avatar.blade.php @@ -1,2 +1 @@ - - +@if($url)@endif@if($url)@endif diff --git a/tests/AvatarWidgetTest.php b/tests/AvatarWidgetTest.php new file mode 100644 index 0000000..c96e995 --- /dev/null +++ b/tests/AvatarWidgetTest.php @@ -0,0 +1,110 @@ + 'test.user.show']); + } + + /** @test */ + public function it_renders_a_default_when_the_model_is_null() + { + $widget = Avatar::create(new AppShellTheme()); + + $html = trim($widget->render()); + $this->assertStringContainsString('assertStringContainsString('src="https://www.gravatar.com/avatar/00000000000000000000000000000000', $html); + } + + /** @test */ + public function it_renders_the_md5_of_the_models_email_when_given() + { + $user = new \stdClass(); + $user->email = 'test@example.com'; + $md5 = md5($user->email); + $widget = Avatar::create(new AppShellTheme()); + + $html = trim($widget->render($user)); + $this->assertStringContainsString('assertStringContainsString($md5, $html); + } + + /** @test */ + public function it_substitutes_placeholders_when_given() + { + $user = new \stdClass(); + $user->email = 'giovanni.gatto@catsville.com'; + $md5 = md5($user->email); + $order = new \stdClass(); + $order->user = $user; + $widget = Avatar::create(new AppShellTheme(), ['model' => '$model.user']); + + $html = trim($widget->render($order)); + $this->assertStringContainsString('assertStringContainsString($md5, $html); + } + + /** @test */ + public function it_does_not_render_a_link_if_such_parameter_was_not_passed() + { + $user = new \stdClass(); + $user->email = 'test@example.com'; + $widget = Avatar::create(new AppShellTheme()); + + $html = trim($widget->render($user)); + $this->assertStringNotContainsString('assertStringNotContainsString('href="', $html); + } + + /** @test */ + public function a_link_can_be_rendered_optionally() + { + $user = new \stdClass(); + $user->email = 'giovanni.gatto@catsville.com'; + $user->id = 35688; + $md5 = md5($user->email); + + $widget = Avatar::create(new AppShellTheme(), ['url' => 'https://penny.cz']); + + $html = trim($widget->render($user)); + $this->assertStringContainsString('assertStringContainsString($md5, $html); + $this->assertStringContainsString('', $html); + } + + /** @test */ + public function a_route_based_link_can_be_rendered_optionally() + { + $user = new \stdClass(); + $user->email = 'giovanni.gatto@catsville.com'; + $user->id = 35688; + $md5 = md5($user->email); + + $widget = Avatar::create(new AppShellTheme(), ['url' => ['route' => 'test.user.show', 'parameters' => ['$model.id']]]); + + $html = trim($widget->render($user)); + $this->assertStringContainsString('assertStringContainsString($md5, $html); + $this->assertStringContainsString('', $html); + } +}