Skip to content

Commit

Permalink
Filament V3 Compatibility (#5)
Browse files Browse the repository at this point in the history
* add filament v3 compatibility
  • Loading branch information
ousid authored Nov 8, 2023
1 parent c416804 commit 0472be8
Show file tree
Hide file tree
Showing 18 changed files with 443 additions and 120 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
os: [ubuntu-latest, windows-latest]
php: [8.2, 8.1]
laravel: [10.*]
stability: [prefer-lowest, prefer-stable]
stability: [prefer-stable]
include:
- laravel: 10.*
testbench: 8.*
Expand Down
116 changes: 71 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,90 +11,116 @@

</br>

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

This plugin uses [Laravel Turnstile](https://github.com/coderflexx/laravel-turnstile) Behind the scene, you can head to the page __README__ to learn more.
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).

## Installation
You can install the package via composer:

Install the package via Composer:

```bash
composer require coderflex/filament-turnstile
```

For users still on **Filament V2**, install the package using:

```bash
composer require coderflex/filament-turnstil "^1.0"
```

## Turnstile Keys
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)
To utilize **Cloudflare Turnstile**, obtain your `SiteKey` and `SecretKey` from your Cloudflare Dashboard.

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

```.env
TURNSTILE_SITE_KEY=2x00000000000000000000AB
TURNSTILE_SECRET_KEY=2x0000000000000000000000000000000AA
After generating the **keys**, include them in your `.env` file using the following format:

```env
TURNSTILE_SITE_KEY=1x00000000000000000000AA
TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AA
```

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.
For testing purposes, you can use [Dummy site keys and secret keys](https://developers.cloudflare.com/turnstile/reference/testing/) provided by Cloudflare.

## Usage

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

```php
...
use Coderflex\FilamentTurnstile\Forms\Components\Turnstile;

...
Turnstile::make('captcha')
->theme('auto')
->language('fr')
->size('normal'),
Turnstile::make('captcha')
->theme('auto') // accepts light, dark, auto
->language('en-US') // see below
->size('normal'), // accepts normal, compact
```

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)
For a list of supported languages, refer to the [supported languages section](https://developers.cloudflare.com/turnstile/reference/supported-languages/).

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).


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

Create a new `App/Filament/Pages/Login.php` class
To implement the **Turnstile** captcha with the `Login` page in Filament, follow these steps:

Create a new `App/Filament/Pages/Auth/Login.php` class:

```php
<?php

namespace App\Filament\Pages;
namespace App\Filament\Pages\Auth;

use Coderflex\FilamentTurnstile\Forms\Components\Turnstile;
use Filament\Forms\Form;
use Filament\Http\Responses\Auth\Contracts\LoginResponse;
use Filament\Pages\Auth\Login as AuthLogin;

class Login extends \Filament\Http\Livewire\Auth\Login
class Login extends AuthLogin
{
protected function getFormSchema(): array
/**
* @return array<int|string, string|Form>
*/
protected function getForms(): array
{
return array_merge(
parent::getFormSchema(),
[
Turnstile::make('cf-captcha')
->theme('auto')
->language('en-US')
->size('normal'),
]
);
return [
'form' => $this->form(
$this->makeForm()
->schema([
$this->getEmailFormComponent(),
$this->getPasswordFormComponent(),
$this->getRememberFormComponent(),
Turnstile::make('captcha')
->label('Captcha')
->theme('auto'),
])
->statePath('data'),
),
];
}
}
```

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

```php
return [
....
'auth' => [
'guard' => env('FILAMENT_AUTH_GUARD', 'web'),
'pages' => [
'login' => \App\Filament\Pages\Login::class,
],
],
...
]
namespace App\Providers\Filament;

use App\Filament\Auth\Login;
use Filament\Panel;
use Filament\PanelProvider;

class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->default()
->id('admin')
->path('admin')
->login(Login::class); // override the login page class.
...
}
}
```
## Testing

Expand Down
Binary file modified art/login_screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"spatie/laravel-package-tools": "^1.14.0"
},
"require-dev": {
"filament/filament": "^2.17",
"filament/filament": "^3.0",
"laravel/pint": "^1.0",
"nunomaduro/collision": "^7.9",
"nunomaduro/larastan": "^2.0.1",
Expand Down
72 changes: 34 additions & 38 deletions resources/views/components/turnstile.blade.php
Original file line number Diff line number Diff line change
@@ -1,48 +1,44 @@
<x-dynamic-component
:component="$getFieldWrapperView()"
:id="$getId()"
:label="$getLabel()"
:label-sr-only="$isLabelHidden()"
:helper-text="$getHelperText()"
:hint="$getHint()"
:hint-action="$getHintAction()"
:hint-color="$getHintColor()"
:hint-icon="$getHintIcon()"
:required="$isRequired()"
:state-path="$getStatePath()"
>
<div x-data="{
state: $wire.entangle('{{ $getStatePath() }}').defer
@php
$statePath = $getStatePath();
$fieldWrapperView = $getFieldWrapperView();
$theme = $getTheme();
$size = $getSize();
$language = $getLanguage();
@endphp

<x-dynamic-component :component="$fieldWrapperView" :field="$turnstile">

<div x-data="{
state: $wire.entangle('{{ $statePath }}').defer
}"
wire:ignore
>
<div id="turnstile-widget"
data-sitekey="{{config('turnstile.turnstile_site_key')}}"
data-theme="{{$getTheme()}}"
data-language="{{$getLanguage()}}"
data-size="{{$getSize()}}">
</div>
</div>

@push('scripts')
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback" defer></script>
<script>
let options = {
callback: function(token) {
window.Livewire
.find('{{$this->id}}')
.$set('{{$getStatePath()}}', token);
x-init="(() => {
let options= {
callback: function (token) {
$wire.set('{{ $statePath }}', token)
},
errorCallback: function () {
window.Livewire
.find('{{$this->id}}')
.$set('{{$getStatePath()}}', 'error');
}
$wire.set('{{ $statePath }}', null)
},
}
window.onloadTurnstileCallback = () => {
turnstile.render('#turnstile-widget', options)
turnstile.render($refs.turnstile, options)
}
</script>
})()"
>
<div data-sitekey="{{config('turnstile.turnstile_site_key')}}"
data-theme="{{ $theme }}"
data-language="{{ $language }}"
data-size="{{ $size }}"
x-ref="turnstile"
>
</div>
</div>

@push('scripts')
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback" defer></script>
@endpush
</x-dynamic-component>
4 changes: 2 additions & 2 deletions src/FilamentTurnstileServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace Coderflex\FilamentTurnstile;

use Filament\PluginServiceProvider;
use Spatie\LaravelPackageTools\Package;
use Spatie\LaravelPackageTools\PackageServiceProvider;

class FilamentTurnstileServiceProvider extends PluginServiceProvider
class FilamentTurnstileServiceProvider extends PackageServiceProvider
{
public function configurePackage(Package $package): void
{
Expand Down
21 changes: 17 additions & 4 deletions src/Forms/Components/Turnstile.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

class Turnstile extends Field
{
protected string $viewIdentifier = 'turnstile';

protected string $view = 'turnstile::components.turnstile';

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

$this->label('');

$this->rules(['required', new TurnstileCheck()]);
$this->required();

$this->rule(new TurnstileCheck());

$this->dehydrated(false);
}
Expand All @@ -47,17 +51,26 @@ public function language(string $language): static
return $this;
}

public function getTheme(): string
/**
* @return string
*/
public function getTheme()
{
return $this->evaluate($this->theme);
}

public function getSize(): string
/**
* @return string
*/
public function getSize()
{
return $this->evaluate($this->size);
}

public function getLanguage(): string
/**
* @return string
*/
public function getLanguage()
{
return $this->evaluate($this->language);
}
Expand Down
10 changes: 10 additions & 0 deletions tests/Database/Factories/UserFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Coderflex\FilamentTurnstile\Tests\Database\Factories;

use Coderflex\FilamentTurnstile\Tests\Models\User;

class UserFactory extends \Orchestra\Testbench\Factories\UserFactory
{
protected $model = User::class;
}
19 changes: 19 additions & 0 deletions tests/Database/Migrations/create_contacts_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class() extends Migration
{
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email');
$table->text('content');
$table->timestamps();
});
}
};
21 changes: 21 additions & 0 deletions tests/Database/Migrations/create_users_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class() extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
};
Loading

0 comments on commit 0472be8

Please sign in to comment.