Skip to content

Commit 0472be8

Browse files
authored
Filament V3 Compatibility (#5)
* add filament v3 compatibility
1 parent c416804 commit 0472be8

File tree

18 files changed

+443
-120
lines changed

18 files changed

+443
-120
lines changed

.github/workflows/run-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
os: [ubuntu-latest, windows-latest]
1616
php: [8.2, 8.1]
1717
laravel: [10.*]
18-
stability: [prefer-lowest, prefer-stable]
18+
stability: [prefer-stable]
1919
include:
2020
- laravel: 10.*
2121
testbench: 8.*

README.md

Lines changed: 71 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,90 +11,116 @@
1111

1212
</br>
1313

14-
__Filament Turnstile__, is a plugin to help you implement the Cloudflare turnstile.
14+
**Filament Turnstile** is an essential plugin designed to seamlessly integrate Cloudflare's turnstile into your applications.
1515

16-
This plugin uses [Laravel Turnstile](https://github.com/coderflexx/laravel-turnstile) Behind the scene, you can head to the page __README__ to learn more.
16+
This plugin uses [Laravel Turnstile](https://github.com/coderflexx/laravel-turnstile) under the hood. For detailed information, explore the [Laravel Turnstile README](https://github.com/coderflexx/laravel-turnstile).
1717

1818
## Installation
19-
You can install the package via composer:
20-
19+
Install the package via Composer:
2120

2221
```bash
2322
composer require coderflex/filament-turnstile
2423
```
2524

25+
For users still on **Filament V2**, install the package using:
26+
27+
```bash
28+
composer require coderflex/filament-turnstil "^1.0"
29+
```
2630

2731
## Turnstile Keys
28-
To be able to use __Cloudflare Turnstile__, you need to get the `SiteKey`, and the `SecretKey` from your [Cloudflare dashboard](https://developers.cloudflare.com/turnstile/get-started/#get-a-sitekey-and-secret-key)
32+
To utilize **Cloudflare Turnstile**, obtain your `SiteKey` and `SecretKey` from your Cloudflare Dashboard.
2933

30-
After Generating the __keys__, use `TURNSTILE_SITE_KEY`, and `TURNSTILE_SECRET_KEY` in your `.env` file
34+
Refer to the [documentation](https://developers.cloudflare.com/turnstile/get-started/#get-a-sitekey-and-secret-key) for detailed instructions.
3135

32-
```.env
33-
TURNSTILE_SITE_KEY=2x00000000000000000000AB
34-
TURNSTILE_SECRET_KEY=2x0000000000000000000000000000000AA
36+
After generating the **keys**, include them in your `.env` file using the following format:
37+
38+
```env
39+
TURNSTILE_SITE_KEY=1x00000000000000000000AA
40+
TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AA
3541
```
3642

37-
If you want to test the widget, you can use the [Dummy site keys and secret keys](https://developers.cloudflare.com/turnstile/reference/testing/) that Cloudflare provides.
43+
For testing purposes, you can use [Dummy site keys and secret keys](https://developers.cloudflare.com/turnstile/reference/testing/) provided by Cloudflare.
3844

3945
## Usage
4046

41-
The usage of this plugin, is really straight - forward. In your form, use the following code:
47+
Utilizing this plugin is incredibly straightforward. In your form, incorporate the following code:
4248

4349
```php
44-
...
4550
use Coderflex\FilamentTurnstile\Forms\Components\Turnstile;
4651

47-
...
48-
Turnstile::make('captcha')
49-
->theme('auto')
50-
->language('fr')
51-
->size('normal'),
52+
Turnstile::make('captcha')
53+
->theme('auto') // accepts light, dark, auto
54+
->language('en-US') // see below
55+
->size('normal'), // accepts normal, compact
5256
```
5357

54-
The `Turnstile` field, has few options to use. You can learn more about them in [the Cloudflare configuration section](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#configurations)
58+
For a list of supported languages, refer to the [supported languages section](https://developers.cloudflare.com/turnstile/reference/supported-languages/).
59+
60+
The `Turnstile` field offers various options; you can learn more about them in [the Cloudflare configuration section](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#configurations).
61+
5562

56-
## Real Life Example:
57-
In order to use __Turnstile__ captcha with the `Login` page in filament, use the following steps:
63+
## Real-Life Example:
5864

59-
Create a new `App/Filament/Pages/Login.php` class
65+
To implement the **Turnstile** captcha with the `Login` page in Filament, follow these steps:
66+
67+
Create a new `App/Filament/Pages/Auth/Login.php` class:
6068

6169
```php
62-
<?php
6370

64-
namespace App\Filament\Pages;
71+
namespace App\Filament\Pages\Auth;
6572

6673
use Coderflex\FilamentTurnstile\Forms\Components\Turnstile;
74+
use Filament\Forms\Form;
75+
use Filament\Http\Responses\Auth\Contracts\LoginResponse;
76+
use Filament\Pages\Auth\Login as AuthLogin;
6777

68-
class Login extends \Filament\Http\Livewire\Auth\Login
78+
class Login extends AuthLogin
6979
{
70-
protected function getFormSchema(): array
80+
/**
81+
* @return array<int|string, string|Form>
82+
*/
83+
protected function getForms(): array
7184
{
72-
return array_merge(
73-
parent::getFormSchema(),
74-
[
75-
Turnstile::make('cf-captcha')
76-
->theme('auto')
77-
->language('en-US')
78-
->size('normal'),
79-
]
80-
);
85+
return [
86+
'form' => $this->form(
87+
$this->makeForm()
88+
->schema([
89+
$this->getEmailFormComponent(),
90+
$this->getPasswordFormComponent(),
91+
$this->getRememberFormComponent(),
92+
Turnstile::make('captcha')
93+
->label('Captcha')
94+
->theme('auto'),
95+
])
96+
->statePath('data'),
97+
),
98+
];
8199
}
82100
}
83101
```
84102

85-
Then override the `Login` class in the `filament.php` config file.
103+
Then, override the `login()` method in your `PanelProvider` (e.g., `AdminPanelProvider`):
86104

87105
```php
88-
return [
89-
....
90-
'auth' => [
91-
'guard' => env('FILAMENT_AUTH_GUARD', 'web'),
92-
'pages' => [
93-
'login' => \App\Filament\Pages\Login::class,
94-
],
95-
],
96-
...
97-
]
106+
namespace App\Providers\Filament;
107+
108+
use App\Filament\Auth\Login;
109+
use Filament\Panel;
110+
use Filament\PanelProvider;
111+
112+
class AdminPanelProvider extends PanelProvider
113+
{
114+
public function panel(Panel $panel): Panel
115+
{
116+
return $panel
117+
->default()
118+
->id('admin')
119+
->path('admin')
120+
->login(Login::class); // override the login page class.
121+
...
122+
}
123+
}
98124
```
99125
## Testing
100126

art/login_screen.png

-84 KB
Loading

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"spatie/laravel-package-tools": "^1.14.0"
2727
},
2828
"require-dev": {
29-
"filament/filament": "^2.17",
29+
"filament/filament": "^3.0",
3030
"laravel/pint": "^1.0",
3131
"nunomaduro/collision": "^7.9",
3232
"nunomaduro/larastan": "^2.0.1",
Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,44 @@
1-
<x-dynamic-component
2-
:component="$getFieldWrapperView()"
3-
:id="$getId()"
4-
:label="$getLabel()"
5-
:label-sr-only="$isLabelHidden()"
6-
:helper-text="$getHelperText()"
7-
:hint="$getHint()"
8-
:hint-action="$getHintAction()"
9-
:hint-color="$getHintColor()"
10-
:hint-icon="$getHintIcon()"
11-
:required="$isRequired()"
12-
:state-path="$getStatePath()"
13-
>
14-
<div x-data="{
15-
state: $wire.entangle('{{ $getStatePath() }}').defer
1+
@php
2+
$statePath = $getStatePath();
3+
$fieldWrapperView = $getFieldWrapperView();
4+
5+
$theme = $getTheme();
6+
$size = $getSize();
7+
$language = $getLanguage();
8+
@endphp
9+
10+
<x-dynamic-component :component="$fieldWrapperView" :field="$turnstile">
11+
12+
<div x-data="{
13+
state: $wire.entangle('{{ $statePath }}').defer
1614
}"
1715
wire:ignore
18-
>
19-
<div id="turnstile-widget"
20-
data-sitekey="{{config('turnstile.turnstile_site_key')}}"
21-
data-theme="{{$getTheme()}}"
22-
data-language="{{$getLanguage()}}"
23-
data-size="{{$getSize()}}">
24-
</div>
25-
</div>
26-
27-
@push('scripts')
28-
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback" defer></script>
29-
<script>
30-
let options = {
31-
callback: function(token) {
32-
window.Livewire
33-
.find('{{$this->id}}')
34-
.$set('{{$getStatePath()}}', token);
16+
x-init="(() => {
17+
let options= {
18+
callback: function (token) {
19+
$wire.set('{{ $statePath }}', token)
3520
},
21+
3622
errorCallback: function () {
37-
window.Livewire
38-
.find('{{$this->id}}')
39-
.$set('{{$getStatePath()}}', 'error');
40-
}
23+
$wire.set('{{ $statePath }}', null)
24+
},
4125
}
4226
4327
window.onloadTurnstileCallback = () => {
44-
turnstile.render('#turnstile-widget', options)
28+
turnstile.render($refs.turnstile, options)
4529
}
46-
</script>
30+
})()"
31+
>
32+
<div data-sitekey="{{config('turnstile.turnstile_site_key')}}"
33+
data-theme="{{ $theme }}"
34+
data-language="{{ $language }}"
35+
data-size="{{ $size }}"
36+
x-ref="turnstile"
37+
>
38+
</div>
39+
</div>
40+
41+
@push('scripts')
42+
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback" defer></script>
4743
@endpush
4844
</x-dynamic-component>

src/FilamentTurnstileServiceProvider.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
namespace Coderflex\FilamentTurnstile;
44

5-
use Filament\PluginServiceProvider;
65
use Spatie\LaravelPackageTools\Package;
6+
use Spatie\LaravelPackageTools\PackageServiceProvider;
77

8-
class FilamentTurnstileServiceProvider extends PluginServiceProvider
8+
class FilamentTurnstileServiceProvider extends PackageServiceProvider
99
{
1010
public function configurePackage(Package $package): void
1111
{

src/Forms/Components/Turnstile.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
class Turnstile extends Field
99
{
10+
protected string $viewIdentifier = 'turnstile';
11+
1012
protected string $view = 'turnstile::components.turnstile';
1113

1214
protected string $theme = 'auto';
@@ -21,7 +23,9 @@ protected function setUp(): void
2123

2224
$this->label('');
2325

24-
$this->rules(['required', new TurnstileCheck()]);
26+
$this->required();
27+
28+
$this->rule(new TurnstileCheck());
2529

2630
$this->dehydrated(false);
2731
}
@@ -47,17 +51,26 @@ public function language(string $language): static
4751
return $this;
4852
}
4953

50-
public function getTheme(): string
54+
/**
55+
* @return string
56+
*/
57+
public function getTheme()
5158
{
5259
return $this->evaluate($this->theme);
5360
}
5461

55-
public function getSize(): string
62+
/**
63+
* @return string
64+
*/
65+
public function getSize()
5666
{
5767
return $this->evaluate($this->size);
5868
}
5969

60-
public function getLanguage(): string
70+
/**
71+
* @return string
72+
*/
73+
public function getLanguage()
6174
{
6275
return $this->evaluate($this->language);
6376
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Coderflex\FilamentTurnstile\Tests\Database\Factories;
4+
5+
use Coderflex\FilamentTurnstile\Tests\Models\User;
6+
7+
class UserFactory extends \Orchestra\Testbench\Factories\UserFactory
8+
{
9+
protected $model = User::class;
10+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class() extends Migration
8+
{
9+
public function up()
10+
{
11+
Schema::create('contacts', function (Blueprint $table) {
12+
$table->id();
13+
$table->string('name');
14+
$table->string('email');
15+
$table->text('content');
16+
$table->timestamps();
17+
});
18+
}
19+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class() extends Migration
8+
{
9+
public function up()
10+
{
11+
Schema::create('users', function (Blueprint $table) {
12+
$table->id();
13+
$table->string('name');
14+
$table->string('email')->unique();
15+
$table->timestamp('email_verified_at')->nullable();
16+
$table->string('password');
17+
$table->rememberToken();
18+
$table->timestamps();
19+
});
20+
}
21+
};

0 commit comments

Comments
 (0)