PHPackages                             e2d2-dev/betta-terms - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Admin Panels](/categories/admin)
4. /
5. e2d2-dev/betta-terms

ActiveLibrary[Admin Panels](/categories/admin)

e2d2-dev/betta-terms
====================

Comprehensive Terms Solution with panel/model and management solution

v1.0.3(5mo ago)42MITPHP

Since Jan 17Pushed 5mo agoCompare

[ Source](https://github.com/e2d2-dev/betta-terms)[ Packagist](https://packagist.org/packages/e2d2-dev/betta-terms)[ Docs](https://github.com/e2d2-dev/betta-terms)[ RSS](/packages/e2d2-dev-betta-terms/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (1)Versions (4)Used By (0)

 [![Banner](https://repository-images.githubusercontent.com/1136087779/249f084b-4c55-491e-81d4-c875adccb96c)](https://repository-images.githubusercontent.com/1136087779/249f084b-4c55-491e-81d4-c875adccb96c)

\# Terms &amp; Conditions Management ### For Filament 4.x / 5.0

[](#for-filament-4x--50)

Features
========

[](#features)

- 📦 Panel Guard
- 📄 Model Guard
- 🔍 **Entity discovery** (panel &amp; models)
- 🌐 **Localized**
- 🎨 **Intuitive &amp; Responsive UI**
- [Installation](#installation)

    - [1. Install Package](#1-install-package)
    - [2. Run Setup Command](#2-run-setup-command)
    - [3. Setup User Model](#3-setup-user-model)
    - [4. Manage Terms Plugin](#4-manage-terms-plugin)
    - [5. Terms Guard Plugin](#5-terms-guard-plugin)
    - [6. Panel Registration Form](#6-panel-registration-form)
- [Guards](#guards)

    - [Guard Features](#guard-features)
- [Panel Guard](#panel-guard)

    - [Panel Guard Usage](#panel-guard-usage)
    - [Modify Panel Slug Generation](#modify-panel-slug-generation)
- [Model Guard](#model-guard)

    - [Model Guard Setup](#model-guard-setup)
        - [HasGuardConditions Trait](#add-the-hasguardconditions-trait-to-your-order-model)
        - [ConsentComponent](#add-the-consentcomponent-to-your-form-schema)
        - [Creating A Model Guard](#add-a-model-guard-in-the-guardresource)
        - [Register Models](#register-models)
        - [Slug Creation](#hook-into-model-slug-creation)
- [Conditions](#conditions)

    - [Guards](#condition-guards)
    - [Name](#condition-name)
    - [Description](#condition-description)
    - [Slug](#condition-slug)
    - [Source](#condition-source)
    - [Source Options](#condition-source-options)
    - [Replacement](#condition-replacement)
    - [Remove Conditions](#remove-conditions)
    - [Consents](#condition-consents)
- [ConsentComponent](#consentcomponent)

    - [Visual Modes](#visual-modes)
        - [Regular](#regular-mode)
        - [Compact](#compact-mode)
    - [Layouts](#consent-component-layouts)
    - [Guards](#guards-1)
- [Consent Conditions Page Component](#consent-conditions-page-component)

    - [Slug](#slug)
    - [Filament Menu Components](#filament-menu-components)
    - [Generate Headings](#generate-headings)
    - [Component](#component)
- [Commands](#commands)

    - [Setup](#setup-command)
    - [Make Condition](#make-condition-command)
    - [Make Guard](#make-guard-command)
    - [Make Terms Model](#make-terms-model-migration)
- [Events](#events)

    - [Consent Complete](#consent-complete)
    - [Condition Consent](#condition-consent)
    - [Successor Activated](#successor-activated)
- [Disabling the Guard](#disabling-the-guard)
- [Restricting Access](#restricting-access)
- [Translations](#translations)
- [Publish Views](#publish-views)
- [TODO](#todo)
- [Credits](#credits)
- [License](#license)

Installation
============

[](#installation)

1. Install Package
------------------

[](#1-install-package)

```
composer require e2d2-dev/betta-terms
```

2. Run Setup Command
--------------------

[](#2-run-setup-command)

Run the setup command

```
php artisan terms:setup
```

This will publish migrations, ask to publish the config file and translations

3. Setup User Model
-------------------

[](#3-setup-user-model)

To perform consent on conditions add the `HasConsents` trait &amp; the `CanConsent` interface to your auth provider model:

```
use Betta\Terms\Traits\User\HasConsents;
use \Betta\Terms\Contracts\CanConsent;

class User extends Authenticatable implements CanConsent
{
    use HasConsents;
}
```

4. Manage Terms Plugin
----------------------

[](#4-manage-terms-plugin)

Add the `ManageTermsPlugin` to your panel:

```
use Betta\Terms\ManageTermsPlugin;

public static function register(Panel $panel): Panel
 {
     $panel->plugins([
         ManageTermsPlugin::make(),
     ]);
}
```

5. Terms Guard Plugin
---------------------

[](#5-terms-guard-plugin)

Add the `TermsGuardPlugin` plugin to the panel you want to guard:

```
use Betta\Terms\TermsGuardPlugin;

 public static function register(Panel $panel): Panel
 {
     $panel->plugins([
         TermsGuardPlugin::make(),
     ]);
}
```

6. Panel Registration Form
--------------------------

[](#6-panel-registration-form)

If you want to have the conditions on your registrations form, add the Register component to your panel.

```
 use Betta\Terms\Filament\Auth\Register;

 public static function register(Panel $panel): Panel
 {
     $panel->registration(Register::class);
 }
```

Guards
======

[](#guards)

Guard Features
--------------

[](#guard-features)

#### Every guard can have multiple conditions

[](#every-guard-can-have-multiple-conditions)

Conditions can be:

- skippable -&gt; not required
- persistent -&gt; will need consent every time / multiple times
- orderable

[![Reorder](docs/reorder.png)](docs/reorder.png)

Panel Guard
===========

[](#panel-guard)

Terms comes with a multi-panel guard. Each can have an own. The panel guard will be checked for new conditions every login, if there are any new users need to apply to them if not skippable. This includes replaced conditions.

Panel Guard Usage
-----------------

[](#panel-guard-usage)

- Make sure to add the ManageTermsPlugin to your panel
- Create at least one condition
- Create a guard with the `panel` option
- Link them together

Modify Panel Slug Generation
----------------------------

[](#modify-panel-slug-generation)

Hook into the Panel slug creation using:

```
use Betta\Terms\Terms;

 public function boot(): void
 {
     Terms::generatePanelSlugUsing(fn(string $panel) => generate_slug($panel))
 }
```

You can also just change the panel slug prefix in the config.

```
'config/betta-terms.php'

 'slug' => [
     'panel' => [
         'prefix' => 'panel//',
     ],
 ],
```

Model Guard
===========

[](#model-guard)

Some records may need conditions (e.g. invoices &amp; registrations). The model guard provides a solution for that. Consents will be stored in the record and only committed when `commitConsent()` is called (e.g. after successful process).

Model Guard Setup
-----------------

[](#model-guard-setup)

### Add the `HasGuardConditions` trait to your order model:

[](#add-the-hasguardconditions-trait-to-your-order-model)

```
use Betta\Terms\Traits\Model\HasGuardConditions;
use Betta\Terms\Contracts\ModelConditions;

class YourModel implements ModelConditions
{
    use HasGuardConditions;
}
```

### Add the `ConsentComponent` to your form schema:

[](#add-the-consentcomponent-to-your-form-schema)

```
 use Betta\Terms\Filament\Forms\ConsentComponent;

 public function form(Schema $schema): Schema
 {
     return $schema
         ->components([
             ConsentComponent::make()
                 ->compact(),
         ]);
 }
```

### Add A Model Guard in the GuardResource

[](#add-a-model-guard-in-the-guardresource)

Add a guard in the GuardResource by selecting the type `model`. Models from App\\Models namespace will be auto listed. Add conditions to that model.

### Register Models

[](#register-models)

You can add more models to the select by registering them

```
use Betta\Terms\ManageTermsPlugin;

public static function register(Panel $panel): Panel
 {
     $panel->plugins([
         ManageTermsPlugin::make()
             ->registerModel(string $model, ?string $name),
     ]);
}
```

### Hook into Model Slug Creation

[](#hook-into-model-slug-creation)

You can change how the slug is generated by providing a closure to Terms in a service provider:

```
use Betta\Terms\Terms;

 public function boot(): void
 {
     Terms::generateModelSlugUsing(fn(string $class) => generate_slug($class))
 }
```

You can also just change the model slug prefix in the config.

```
'config/betta-terms.php'

 'slug' => [
     'model' => [
         'prefix' => 'model//',
     ],
 ],
```

Conditions
==========

[](#conditions)

Condition Guards
----------------

[](#condition-guards)

- Every Condition can be added to any guard.
- Conditions can be marked active or skippable in each guard separately
- Conditions can be activated as soon as they have data filled in

Condition Name
--------------

[](#condition-name)

The name is required. It will show up to the client. It is visible as the checkbox label in the compact mode and as section heading in the full mode

Condition Description
---------------------

[](#condition-description)

Description is not required but can be a useful info for clients for further context. It will show up in compact mode below the `accepted` checkbox and as description in full mode.

Condition Slug
--------------

[](#condition-slug)

The slug is autogenerated with timestamp as prefix and with revision suffix.

Condition Source
----------------

[](#condition-source)

Every condition has its own content which can be supplied as

- text (url+markdown)
- file (with upload)
- as url or just the name for small consents.

Condition Source Options
------------------------

[](#condition-source-options)

- PDF
- Link
- Text
- Markdown
- Iframe
- Simple
- Image

Condition Replacement
---------------------

[](#condition-replacement)

When a condition needs improvement, you can't just edit the file, because it is an official document. Hit the replace action in the ConditionResource to replace it. As soon as all required data is filled in, you will be asked to replace the predecessor (previous version). The Predecessor will be removed from all guards and replaced by the successor.

Remove Conditions
-----------------

[](#remove-conditions)

A Condition can only be deleted when they have any consents yet.

Condition Consents
------------------

[](#condition-consents)

Every user's consent will be stored. On which guard or component it was signed will also be stored in the `signed_on` column of the consent table

ConsentComponent
================

[](#consentcomponent)

Visual Modes
------------

[](#visual-modes)

The consent component has two visual modes: regular and compact. Regular mode is of bigger size for full-page usage. Compact mode for in-form usage.

### Regular Mode

[](#regular-mode)

### Compact Mode

[](#compact-mode)

Every condition is presented with the `AcceptedCheckbox` which has the condition name as label, description as hint and a view action to display the content if applicable.

```
 use Betta\Terms\Filament\Forms\ConsentComponent;

     ConsentComponent::make()
         ->compact(),
```

### Consent Component Layouts

[](#consent-component-layouts)

The component does support further layouts:

```
 use Betta\Terms\Filament\Forms\ConsentComponent;

     ConsentComponent::make()
         ->aside()
         ->asSection(),
```

Guards
------

[](#guards-1)

The consent component will find its guards automagically, but you can also specify the guard by slug or by model

```
 use Betta\Terms\Filament\Forms\ConsentComponent;

     ConsentComponent::make()
         ->guard($model)
         ->guard('guard-slug'),
```

Consent Conditions Page Component
=================================

[](#consent-conditions-page-component)

This page will be shown when there are open conditions a user needs to consent.

Slug
----

[](#slug)

The slug can be customized through the config

```
'page' => [
     'consent_conditions' => [
         'slug' => 'consent-conditions',
     ],
 ]
```

Filament Menu Components
------------------------

[](#filament-menu-components)

Can be individually enabled/disabled

```
'page' => [
     'consent_conditions' => [
         'topbar' => true,
         'global_search' => false,
         'navigation' => false,
      ],
 ]
```

Generate Headings
-----------------

[](#generate-headings)

You can define the heading by adding a closure `TermsGuardPlugin::generateConsentConditionsHeadingUsing()`The parameters $livewire, $guard, $user &amp; $panel will be provided;

```
use Betta\Terms\TermsGuardPlugin;

 public static function register(Panel $panel): Panel
 {
     $panel->plugins([
         TermsGuardPlugin::make()->generateConsentConditionsHeadingUsing(fn($livewire, $guard, $user, $panel) => 'Your Heading'),
     ]);
}
```

Component
---------

[](#component)

The component can be swapped.

```
'page' => [
     'consent_conditions' => [
         'component' => YourPageComponent::class,
      ],
 ]
```

Commands
========

[](#commands)

Setup Command
-------------

[](#setup-command)

Will check if

- the filament plugins are registered to any panel and provide information how to add them
- tables are migrated and will ask to publish&amp;run the migrations
- config is published and ask to publish
- translation is published and ask to publish
-

```
php artisan terms:setup
```

Make Condition Command
----------------------

[](#make-condition-command)

Create a condition and attach it to a guard. You will still need to visit the condition management resource. Link will be provided by the command after creation.

```
php artisan make:terms-condition
```

Make Guard Command
------------------

[](#make-guard-command)

Create a guard. You will still need to visit the guard management resource. Link will be provided by the command after creation.

```
php artisan make:terms-guard
```

Make Terms Model Migration
--------------------------

[](#make-terms-model-migration)

Events
======

[](#events)

Terms supplies events if you want to attach further actions after something happened.

Consent Complete
----------------

[](#consent-complete)

Will dispatch after ConsentConsentConditions is completed

```
 use Betta\Terms\Events\ConsentComplete;

 public function __construct(
     User $user,
     ?string $signedOn = null,
     ?Guard $guard = null
 )
```

Condition Consent
-----------------

[](#condition-consent)

After a condition was accepted.

```
    use Betta\Terms\Events\ConditionConsent;
    use Betta\Terms\Models\Consent;
    use Betta\Terms\Models\Condition;

    public function __construct(Consent $consent)
    {
        /** @var User $user */
        $user = $consent->user;

        /** @var Condition $condition */
        $condition = $consent->condition;

        /** @var string $signedOn */
        $signedOn = $consent->signed_on;

        /** @var \Carbon\CarbonInterface $createdAt */
        $createdAt = $consent->created_at;
    }
```

Successor Activated
-------------------

[](#successor-activated)

When a new condition was activated and the predecessor got obsolete

```
    use Betta\Terms\Events\Condition\SuccessorActivated;
    use Betta\Terms\Models\Condition;

    /** @param Condition $condition */
    public function __construct($condition)
    {
        $predecessor = $condition->predecessor;
    }
```

Disabling the guard
===================

[](#disabling-the-guard)

If you need to disable the panel guard for some reason or for some user, provide a closure or a just bool to:

```
use Betta\Terms\TermsManager;
use Betta\Terms\Models\Guard;
use Filament\Panel;

     Terms::disableGuard(
         fn(
             TermsManager $manager,
             User $user,
             Guard $panelGuard,
             Panel $panel
         ) : bool => $user->isSuperAdmin(),
     )
```

Restricting Access
==================

[](#restricting-access)

Terms does not come with permission configuration on purpose. You can enable/disable every Filament Resource/Action through policies as permissions are handled different in every app. Example:

```
class ConditionPolicy
{
 public function viewAny(User $user): Response | bool
 {
     return ! $user->isSuperAdmin(); // will disable the ConditionResource for everyone except "superAdmins"
 }
}
```

There is one custom Action: Condition "ReplaceAction" which will forward to the model action:

```
class Condition extends Model
{
 public function replace(): Condition
 {
     return Replace::run($this);
 }
}

// corresponding policy function
class ConditionPolicy
{
 public function replace(User $user, Condition $record): Response | bool
 {
     return $user->can('replace'); // e.g.
 }
}
```

Translations
============

[](#translations)

Localization is available in: \[ en, de, es, fr &amp; pt \] at the moment.

Publish the translations using:

```
php artisan terms:setup
```

or via the service provider:

```
    php artisan vendor:publish --provider="Betta\Terms\ServiceProvider" --tag=translations
```

Publish Views
=============

[](#publish-views)

```
    php artisan vendor:publish --provider="Betta\Terms\ServiceProvider" --tag=views
```

Screenshots
===========

[](#screenshots)

Edit Condition
--------------

[](#edit-condition)

[![Condition Edit](docs/condition-edit.png)](docs/condition-edit.png)

Consent Conditions Page
-----------------------

[](#consent-conditions-page)

[![Consent Conditions Page](docs/consent-conditions.png)](docs/consent-conditions.png)

Consents Table
--------------

[](#consents-table)

[![Consents Table](docs/consents-list.png)](docs/consents-list.png)

Guards Table
------------

[](#guards-table)

[![Guards Table](docs/guards-list.png)](docs/guards-list.png)

Edit Guard
----------

[](#edit-guard)

[![Guard Edit](docs/guard-edit.png)](docs/guard-edit.png)

Consent Component Compact Mode
------------------------------

[](#consent-component-compact-mode)

[![Preview Compact](docs/preview-compact.png)](docs/preview-compact.png)

Consent Component Regular Mode
------------------------------

[](#consent-component-regular-mode)

[![Preview Regular](docs/preview-regular.png)](docs/preview-regular.png)

TODO
====

[](#todo)

- Disabling Sources &amp; Components
- Conditions with language / country separation

Credits
=======

[](#credits)

- [Filament Team](https://www.filamentphp.com)

License
=======

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

31

—

LowBetter than 66% of packages

Maintenance70

Regular maintenance activity

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

167d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/66956867?v=4)[ed](/maintainers/e2d2-dev)[@e2d2-dev](https://github.com/e2d2-dev)

---

Top Contributors

[![e2d2-dev](https://avatars.githubusercontent.com/u/66956867?v=4)](https://github.com/e2d2-dev "e2d2-dev (19 commits)")

---

Tags

conditionsfilamentguardlaraveltermslaravelfilamentphpconditionstermsconsentsmodel guarde2d2-dev

### Embed Badge

![Health badge](/badges/e2d2-dev-betta-terms/health.svg)

```
[![Health](https://phpackages.com/badges/e2d2-dev-betta-terms/health.svg)](https://phpackages.com/packages/e2d2-dev-betta-terms)
```

###  Alternatives

[mradder/filament-logger

Audit logging, activity tracking, exports, alerts, and dashboards for Filament admin panels.

2317.4k](/packages/mradder-filament-logger)[codewithdennis/larament

Larament is a time-saving starter kit to quickly launch Laravel 13.x projects. It includes FilamentPHP 5.x pre-installed and configured, along with additional tools and features to streamline your development workflow.

3891.8k](/packages/codewithdennis-larament)[marcelweidum/filament-passkeys

Use passkeys in your filamentphp app

6649.5k1](/packages/marcelweidum-filament-passkeys)[harvirsidhu/filament-cards

A Filament-native cards plugin for organizing pages and resources into a card-based navigation hub.

117.1k](/packages/harvirsidhu-filament-cards)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
