vlados / laravel-legal-documents
Track legal document versions and user acceptances in Laravel applications
Installs: 2
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/vlados/laravel-legal-documents
Requires
- php: ^8.2
- illuminate/contracts: ^11.0|^12.0
- illuminate/support: ^11.0|^12.0
- spatie/laravel-translatable: ^6.0
Requires (Dev)
- orchestra/testbench: ^9.0|^10.0
- pestphp/pest: ^3.0
Suggests
- filament/filament: Required for Filament admin panel integration (^3.0|^4.0)
- lara-zeus/spatie-translatable: Required for Filament translatable support (^1.0)
README
A Laravel package for managing legal documents (Privacy Policy, Terms of Service, etc.) with version tracking, user acceptance management, and optional Filament admin panel integration.
Features
- Document Types Management - Create and manage different types of legal documents (Privacy Policy, Terms of Service, Cookie Policy, etc.)
- Version Control - Track document versions with full history and publish workflow
- User Acceptance Tracking - Record when users accept documents with audit metadata (IP address, user agent)
- Re-acceptance on Updates - Optionally require users to re-accept documents when they are updated
- Role-Based Requirements - Require specific documents for specific user roles (e.g., Terms of Service only for sellers)
- Middleware Protection - Block access to your application until required documents are accepted
- Email Notifications - Notify users when legal documents are updated
- Filament Integration - Optional admin panel with WordPress-style document editor
- Formal Document Control - Professional legal document layout with revision history
- Frontend Routes - Public pages to view legal documents with version history
- Internationalization - Full i18n support (English and Bulgarian included)
Screenshots
Document Types Management
Manage document types with role-based requirements
Documents List
Track document versions, status, and user acceptances
Document Editor
Rich text editor with publishing controls and version management
Requirements
- PHP 8.2+
- Laravel 11.x or 12.x
- Livewire 3.x
Installation
Install the package via Composer:
composer require vlados/laravel-legal-documents
Publish the configuration file:
php artisan vendor:publish --tag=legal-documents-config
Publish and run the migrations:
php artisan vendor:publish --tag=legal-documents-migrations php artisan migrate
Configuration
After publishing, you can configure the package in config/legal-documents.php:
return [ // Your User model 'user_model' => App\Models\User::class, // Route where users accept pending documents 'acceptance_route' => 'legal.accept', // Routes accessible even with pending documents 'excluded_routes' => [ 'logout', 'legal.*', 'filament.*', 'livewire.*', ], // Notification settings 'notifications' => [ 'channels' => ['mail', 'database'], 'queue' => true, ], // Filament admin panel integration 'filament' => [ 'enabled' => true, 'navigation_group' => 'Settings', ], // Frontend routes configuration 'frontend' => [ 'enabled' => true, 'prefix' => 'legal', 'middleware' => ['web'], 'layout' => 'layouts.app', ], // Role-based document requirements (optional) 'roles' => [ 'enabled' => false, // Set to true to enable role-based requirements 'available' => [], // Leave empty to auto-detect from Spatie Permission 'user_roles_method' => 'getRoleNames', // Method on User model to get roles ], ];
Setup
1. Add the Trait to Your User Model
Add the HasLegalAcceptances trait to your User model:
<?php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Vlados\LegalDocuments\Traits\HasLegalAcceptances; class User extends Authenticatable { use HasLegalAcceptances; // ... }
2. Register the Middleware
Add the middleware alias in bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) { $middleware->alias([ 'legal-documents' => \Vlados\LegalDocuments\Http\Middleware\EnsureLegalDocumentsAccepted::class, ]); })
3. Apply Middleware to Routes
Apply the middleware to routes that require document acceptance:
// Apply to specific routes Route::middleware(['auth', 'legal-documents'])->group(function () { Route::get('/dashboard', DashboardController::class); }); // Or apply globally in bootstrap/app.php ->withMiddleware(function (Middleware $middleware) { $middleware->appendToGroup('web', [ \Vlados\LegalDocuments\Http\Middleware\EnsureLegalDocumentsAccepted::class, ]); })
4. Filament Integration (Optional)
If you're using Filament, register the plugin in your Panel provider:
use Vlados\LegalDocuments\Filament\LegalDocumentsPlugin; public function panel(Panel $panel): Panel { return $panel // ... ->plugins([ LegalDocumentsPlugin::make(), ]); }
Usage
Creating Document Types
Using Filament admin panel or programmatically:
use Vlados\LegalDocuments\Models\LegalDocumentType; LegalDocumentType::create([ 'name' => 'Privacy Policy', 'slug' => 'privacy-policy', 'description' => 'Our privacy policy document', 'is_required' => true, 'sort_order' => 1, ]);
Creating Documents
use Vlados\LegalDocuments\Models\LegalDocument; $document = LegalDocument::create([ 'legal_document_type_id' => $type->id, 'title' => 'Privacy Policy', 'version' => '1.0', 'content' => '<p>Your privacy policy content...</p>', 'summary_of_changes' => null, 'requires_re_acceptance' => true, 'notify_users' => true, ]); // Publish the document $document->publish();
Publishing a Document
When you publish a document, it becomes the current version and optionally notifies users:
$document->publish();
This will:
- Set
published_atto now - Mark as
is_current - Unmark any previous current document
- Send notifications to users (if
notify_usersis true)
Checking User Acceptance
// Check if user needs to accept any documents if ($user->needsToAcceptDocuments()) { // Redirect to acceptance page } // Check if user has accepted a specific document type if ($user->hasAcceptedLatest('privacy-policy')) { // User has accepted the latest privacy policy } // Get all pending documents for a user $pendingDocuments = $user->getPendingDocuments(); // Get user's acceptance history $history = $user->getAcceptanceHistory();
Accepting Documents
// Accept a single document $user->acceptDocument($document, request()->ip(), request()->userAgent()); // Accept multiple documents $user->acceptDocuments($documentIds, request()->ip(), request()->userAgent());
Role-Based Document Requirements
When roles.enabled is set to true, you can require specific documents for specific user roles:
use Vlados\LegalDocuments\Models\LegalDocumentType; // Create a document type required only for sellers LegalDocumentType::create([ 'name' => 'Seller Agreement', 'slug' => 'seller-agreement', 'is_required' => false, // Not required for everyone 'required_for_roles' => ['seller', 'merchant'], // Only required for these roles ]); // Check pending documents for a user based on their roles $pendingDocuments = $user->getPendingDocumentsForRoles(); // Check if user needs to accept documents based on their roles if ($user->needsToAcceptDocumentsForRoles()) { // Redirect to acceptance page } // Get documents required for specific roles $sellerDocs = LegalDocumentType::requiredForRoles(['seller'])->get(); // Check if a document type is required for a specific user if ($documentType->isRequiredForUser($user)) { // This document is required for this user }
The package automatically detects Spatie Permission roles. If you use a different role system, configure the user_roles_method in the config to point to a method on your User model that returns role names.
Frontend Routes
The package provides these public routes (configurable via frontend.prefix):
| Route | Description |
|---|---|
/legal/accept |
Page for authenticated users to accept pending documents |
/legal/{slug} |
View the current version of a document |
/legal/{slug}/version/{version} |
View a specific version of a document |
Customization
Publishing Views
php artisan vendor:publish --tag=legal-documents-views
Views will be published to resources/views/vendor/legal-documents/.
Publishing Translations
php artisan vendor:publish --tag=legal-documents-lang
Translations will be published to lang/vendor/legal-documents/.
Custom Notification
Create your own notification class and configure it:
// config/legal-documents.php 'notifications' => [ 'class' => App\Notifications\CustomLegalDocumentUpdated::class, ],
Custom Layout
Configure the layout used for the document view page:
// config/legal-documents.php 'frontend' => [ 'layout' => 'layouts.app', // Your layout file ],
API Reference
HasLegalAcceptances Trait
| Method | Description |
|---|---|
legalAcceptances() |
HasMany relationship to acceptances |
hasAcceptedDocument(LegalDocument $document) |
Check if user accepted a specific document |
hasAcceptedLatest(string $typeSlug) |
Check if user accepted latest version of a document type |
getPendingDocuments() |
Get all documents pending acceptance |
needsToAcceptDocuments() |
Check if user has pending documents |
acceptDocument($document, $ip, $userAgent) |
Accept a single document |
acceptDocuments($ids, $ip, $userAgent) |
Accept multiple documents |
getAcceptanceHistory() |
Get user's acceptance history |
getDocumentAcceptance(LegalDocument $document) |
Get acceptance record for a specific document |
getPendingDocumentsForRoles() |
Get pending documents filtered by user's roles |
getRequiredDocumentsForRoles(array $roles) |
Get required documents for specific roles |
needsToAcceptDocumentsForRoles() |
Check if user needs to accept documents based on roles |
LegalDocument Model
| Method | Description |
|---|---|
publish() |
Publish the document and notify users |
scopeCurrent($query) |
Query scope for current documents |
scopePublished($query) |
Query scope for published documents |
scopeRequiresAcceptance($query) |
Query scope for documents requiring acceptance |
LegalDocumentType Model
| Method | Description |
|---|---|
currentDocument |
Relationship to current document |
documents |
Relationship to all documents |
scopeRequired($query) |
Query scope for required document types |
scopeOrdered($query) |
Query scope for ordered by sort_order |
scopeRequiredForRoles($query, array $roles) |
Query scope for documents required for specific roles |
scopeRequiredForUser($query, $user) |
Query scope for documents required for a specific user |
isRequiredForUser($user) |
Check if document type is required for a specific user |
isRequiredForRoles(array $roles) |
Check if document type is required for specific roles |
rolesEnabled() |
Check if role-based requirements are enabled |
getAvailableRoles() |
Get available roles (auto-detects Spatie Permission) |
Events
The package dispatches the following events:
- Document published → Sends
LegalDocumentUpdatednotification to users
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
The MIT License (MIT). Please see License File for more information.