caresome / filament-poll
A FilamentPHP plugin for creating and managing polls
Installs: 36
Dependents: 0
Suggesters: 0
Security: 0
Stars: 7
Watchers: 0
Forks: 2
Open Issues: 0
pkg:composer/caresome/filament-poll
Requires
- php: ^8.2|^8.3|^8.4
- filament/filament: ^4.0
- illuminate/contracts: ^11.0||^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^10.0.0||^9.0.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- spatie/laravel-ray: ^1.35
This package is not auto-updated.
Last update: 2025-12-06 23:46:14 UTC
README
A FilamentPHP v4 plugin for creating and managing interactive polls with Livewire-powered components.
Table of Contents
- Features
- Requirements
- Quick Start
- Installation
- Configuration
- Usage
- Events
- Testing
- Security
- Accessibility
- License
Features
- Easy Management - Create and manage polls through Filament admin panel
- Flexible Voting - Single or multiple choice polls
- Guest Support - Optional guest voting with session tracking
- Real-time Updates - Live vote counting with configurable polling intervals
- Rich Display - Results with percentages and progress bars
- Scheduled Closing - Set poll closing dates
- Interactive UI - Livewire-powered voting experience
- Simple Integration - Blade component for easy frontend use
- Event System - Listen to poll lifecycle events
- Accessible - WCAG 2.1 AA compliant
Requirements
- PHP 8.1 or higher
- Laravel 10.x or 11.x
- FilamentPHP 4.x
Quick Start
composer require caresome/filament-poll
php artisan vendor:publish --tag="filament-poll-migrations"
php artisan migrate
Register the plugin in your panel provider:
use Caresome\FilamentPoll\PollPlugin; public function panel(Panel $panel): Panel { return $panel ->plugins([ PollPlugin::make(), ]); }
Display a poll on your frontend:
<x-caresome::filament-poll :poll-id="1" />
Installation
Step 1: Install Package
composer require caresome/filament-poll
Step 2: Publish and Run Migrations
php artisan vendor:publish --tag="filament-poll-migrations"
php artisan migrate
Step 3: Optional Publishing
Publish config file (for customizing table names):
php artisan vendor:publish --tag="filament-poll-config"
Publish views (for customization):
php artisan vendor:publish --tag="filament-poll-views"
Configuration
Basic Setup
Add the plugin to your Filament panel provider:
use Caresome\FilamentPoll\PollPlugin; public function panel(Panel $panel): Panel { return $panel ->plugins([ PollPlugin::make(), ]); }
Configuration Options
The plugin provides chainable methods to customize behavior:
Navigation
PollPlugin::make() ->navigationIcon('heroicon-o-chart-bar') ->navigationSort(10)
| Method | Description | Default |
|---|---|---|
navigationIcon() |
Set navigation icon | heroicon-o-chart-bar |
navigationSort() |
Set navigation sort order | - |
Poll Defaults
PollPlugin::make() ->isActiveByDefault(true) ->allowGuestVotingByDefault(false) ->multipleChoiceByDefault(false) ->showResultsBeforeVotingByDefault(false) ->showVoteCountByDefault(true)
| Method | Description | Default |
|---|---|---|
isActiveByDefault() |
Polls are active by default | true |
allowGuestVotingByDefault() |
Allow guest voting | false |
multipleChoiceByDefault() |
Enable multiple choice | false |
showResultsBeforeVotingByDefault() |
Show results before voting | false |
showVoteCountByDefault() |
Display vote counts | true |
Limits & Performance
PollPlugin::make() ->maxPollOptions(20) ->maxOptionTextLength(255) ->pollingInterval('5s')
| Method | Description | Default |
|---|---|---|
maxPollOptions() |
Maximum poll options | 20 |
maxOptionTextLength() |
Max characters per option | 255 |
pollingInterval() |
Live update interval (null to disable) | 5s |
Authentication
PollPlugin::make() ->authGuard('admin')
| Method | Description | Default |
|---|---|---|
authGuard() |
Set authentication guard | Auto-detect from panel |
useDefaultAuthGuard() |
Use Laravel's default guard | - |
How it works:
- Auto-detects the Filament panel's guard
- Falls back to Laravel's default guard
- Supports multi-guard applications
Example:
PollPlugin::make() ->authGuard('admin')
Complete Example
use Caresome\FilamentPoll\PollPlugin; public function panel(Panel $panel): Panel { return $panel ->plugins([ PollPlugin::make() ->navigationIcon('heroicon-o-chart-bar') ->navigationSort(10) ->isActiveByDefault(true) ->allowGuestVotingByDefault(false) ->multipleChoiceByDefault(false) ->showResultsBeforeVotingByDefault(false) ->showVoteCountByDefault(true) ->maxPollOptions(20) ->maxOptionTextLength(255) ->pollingInterval('5s') ->authGuard('admin'), ]); }
Custom Table Names
Publish the config file and modify table names:
php artisan vendor:publish --tag="filament-poll-config"
return [ 'table_names' => [ 'polls' => 'custom_polls', 'poll_options' => 'custom_poll_options', 'poll_votes' => 'custom_poll_votes', ], ];
Usage
1. Create Polls
Navigate to the Polls resource in your Filament admin panel:
- Click "New Poll"
- Enter poll question and options
- Configure settings (guest voting, multiple choice, etc.)
- Set closing date (optional)
- Save and publish
2. Display Polls on Frontend
Using Blade Component (Recommended)
By Poll ID:
<x-caresome::filament-poll :poll-id="1" />
By Poll Model:
<x-caresome::filament-poll :poll="$poll" />
Using Livewire Component
@livewire('caresome::filament-poll', ['poll' => $poll])
3. Passing Polls to Views
In your controller:
use Caresome\FilamentPoll\Models\Poll; public function index() { $poll = Poll::where('is_active', true)->first(); return view('welcome', compact('poll')); }
In your view:
@if($poll) <x-caresome::filament-poll :poll="$poll" /> @endif
Events
The package dispatches lifecycle events for custom integrations.
Available Events
| Event | When Fired | Properties |
|---|---|---|
PollCreated |
New poll created | $event->poll |
PollVoted |
Vote is cast | $event->poll, $event->vote |
PollClosed |
Poll closes | $event->poll |
Listening to Events
In EventServiceProvider:
use Caresome\FilamentPoll\Events\{PollCreated, PollVoted, PollClosed}; protected $listen = [ PollCreated::class => [ SendPollNotification::class, ], PollVoted::class => [ TrackAnalytics::class, ], PollClosed::class => [ SendResultsSummary::class, ], ];
Using Event::listen():
use Illuminate\Support\Facades\Event; use Caresome\FilamentPoll\Events\PollVoted; Event::listen(PollVoted::class, function (PollVoted $event) { $poll = $event->poll; $vote = $event->vote; });
Example Use Cases
- Send notifications when polls are created
- Track voting analytics
- Trigger webhooks on vote events
- Archive closed polls
- Send result summaries to stakeholders
Security Considerations
Overview
The package implements multiple security layers for vote tracking and prevention of abuse.
Vote Tracking Methods
| User Type | Tracking Method | Duplicate Prevention |
|---|---|---|
| Authenticated | User ID | Database unique constraint |
| Guest | Session ID + IP Address | Database unique constraint |
Security Notes
Authenticated Users:
- ✅ One vote per user per poll
- ✅ Database-level enforcement
- ✅ High security
Guest Voting:
- ⚠️ Session + IP tracking (reasonable protection)
- ⚠️ Can vote again if cookies cleared
- ⚠️ VPN users share IPs (but unique sessions prevent conflicts)
- 🔒 Disable for high-security polls:
allowGuestVotingByDefault(false)
Performance
The package includes built-in optimizations:
- ✅ Eager loading prevents N+1 queries
- ✅ Database indexes on frequently queried fields
- ✅ Cached vote counting
- ✅ Efficient query constraints
Testing
Run Tests
composer test
composer test-coverage
Using Factories
The package provides factories for testing:
use Caresome\FilamentPoll\Models\{Poll, PollOption, PollVote}; $poll = Poll::factory()->active()->multipleChoice()->create(); $option = PollOption::factory()->forPoll($poll)->create(); $vote = PollVote::factory()->forOption($option)->authenticated(1)->create(); $vote = PollVote::factory()->forOption($option)->guest()->create();
Available Factory States
| Model | States |
|---|---|
| Poll | active(), inactive(), closed(), open(), neverCloses(), multipleChoice(), singleChoice(), allowGuestVoting(), requireAuth() |
| PollOption | forPoll($poll) |
| PollVote | forOption($option), authenticated($userId), guest() |
Accessibility
WCAG 2.1 AA compliant with full accessibility support:
| Feature | Implementation |
|---|---|
| ARIA Labels | All interactive elements labeled |
| Keyboard Navigation | Full keyboard support |
| Screen Readers | Comprehensive announcements |
| Focus Management | Visible indicators, logical tab order |
| Live Regions | Real-time updates announced |
| Semantic HTML | Proper use of fieldset, legend, etc. |
| Progress Bars | Accessible with ARIA attributes |
License
The MIT License (MIT). See LICENSE.md for details.