Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Pollbundle Laravel Package

xlabs/pollbundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require xlabs/pollbundle
    

    Add to config/app.php under providers:

    Xlabs\PollBundle\PollBundle::class,
    

    Publish the migration and config:

    php artisan vendor:publish --provider="Xlabs\PollBundle\PollBundle" --tag="migrations"
    php artisan vendor:publish --provider="Xlabs\PollBundle\PollBundle" --tag="config"
    

    Run migrations:

    php artisan migrate
    
  2. First Use Case: Create a Poll Register the bundle’s service provider and use the Poll facade:

    use Xlabs\PollBundle\Facades\Poll;
    
    $poll = Poll::create([
        'title' => 'Favorite Framework?',
        'description' => 'Help us improve!',
        'expires_at' => now()->addDays(7),
    ]);
    
    $poll->addOption('Laravel');
    $poll->addOption('Symfony');
    $poll->addOption('Other');
    
    $poll->save();
    
  3. Where to Look First

    • Config: config/poll.php (poll settings, default options, etc.).
    • Migrations: database/migrations/[timestamp]_create_polls_table.php (schema details).
    • Facade/API: Xlabs\PollBundle\Facades\Poll (core methods).
    • Views: resources/views/vendor/poll/ (if the bundle includes Blade templates).

Implementation Patterns

Core Workflows

  1. Poll Creation & Management Use the Poll facade to create, update, and delete polls programmatically:

    // Create with options
    $poll = Poll::create(['title' => 'Test Poll'])->addOptions(['Yes', 'No'])->save();
    
    // Fetch all active polls
    $activePolls = Poll::where('expires_at', '>', now())->get();
    
    // Update poll metadata
    $poll->update(['description' => 'Updated description']);
    
  2. Voting System Handle votes via the Vote model or facade methods:

    // Cast a vote
    $poll->vote($userId, 'option_id');
    
    // Check if a user voted
    $hasVoted = $poll->hasVoted($userId);
    
    // Get results
    $results = $poll->getResults();
    
  3. Integration with Blade Render polls in views using the poll directive or helper:

    @poll('favorite-framework')
        @foreach($poll->options as $option)
            <label>{{ $option->text }}</label>
            <input type="radio" name="vote" value="{{ $option->id }}">
        @endforeach
    @endpoll
    
  4. API Endpoints Expose poll functionality via Laravel routes:

    Route::get('/polls/{poll}', [PollController::class, 'show']);
    Route::post('/polls/{poll}/vote', [VoteController::class, 'store']);
    

Advanced Patterns

  • Event Listeners: Extend poll behavior with events like PollCreated, VoteCast.
    // In EventServiceProvider
    protected $listen = [
        'Xlabs\PollBundle\Events\PollCreated' => [
            'App\Listeners\LogPollCreation',
        ],
    ];
    
  • Custom Validation: Override or extend validation rules in AppServiceProvider:
    Poll::extend(function ($poll) {
        $poll->validate(function ($attributes) {
            return Validator::make($attributes, [
                'title' => 'required|max:255|unique:polls',
            ]);
        });
    });
    
  • Caching Results: Cache poll results to reduce database load:
    $results = Cache::remember("poll:{$poll->id}:results", now()->addHours(1), function () use ($poll) {
        return $poll->getResults();
    });
    

Gotchas and Tips

Common Pitfalls

  1. Migration Conflicts

    • If you modify the polls or poll_options table, drop and re-run migrations to avoid schema conflicts.
    • Tip: Use php artisan migrate:fresh in development to reset the database.
  2. Vote Duplication

    • The bundle may not enforce unique votes per user by default. Add a unique constraint in the votes table:
      Schema::table('votes', function (Blueprint $table) {
          $table->unique(['poll_id', 'user_id']);
      });
      
    • Debug: Check for duplicate votes with:
      SELECT * FROM votes WHERE poll_id = ? AND user_id = ? GROUP BY user_id HAVING COUNT(*) > 1;
      
  3. Expired Polls

    • Polls with expires_at in the past may still be queryable. Use scopes to filter:
      $activePolls = Poll::active()->get(); // Assumes `active()` scope exists
      
    • Fix: Add a scope in PollBundle or override it:
      public function scopeActive($query) {
          return $query->where('expires_at', '>', now());
      }
      
  4. Option Management

    • Gotcha: Options are not soft-deleted by default. Use poll_options table directly to archive them.
    • Tip: Add a deleted_at column to poll_options and use Laravel’s soft deletes:
      $option->delete(); // Soft delete
      $option->forceDelete(); // Permanent delete
      

Debugging Tips

  1. Log Poll Events Enable debug logging for poll events in config/poll.php:

    'debug' => env('APP_DEBUG', false),
    

    Check logs for PollBundle events in storage/logs/laravel.log.

  2. Query Debugging Use Laravel’s query logging to inspect poll-related queries:

    DB::enableQueryLog();
    $poll->getResults();
    dd(DB::getQueryLog());
    
  3. Facade vs. Model Direct Usage

    • Prefer the Poll facade for simplicity, but use the Poll model directly for complex queries:
      // Facade
      $poll = Poll::find(1);
      
      // Model (for custom queries)
      $poll = \Xlabs\PollBundle\Models\Poll::with('options.votes')->find(1);
      

Extension Points

  1. Custom Poll Types Extend the Poll model to support multi-choice, ranking, or conditional polls:

    class CustomPoll extends \Xlabs\PollBundle\Models\Poll {
        protected $casts = [
            'is_ranked' => 'boolean',
        ];
    }
    
  2. Third-Party Integrations

    • Webhooks: Trigger webhooks on vote events:
      Poll::created(function ($poll) {
          Http::post('https://your-service.com/webhook', [
              'poll_id' => $poll->id,
          ]);
      });
      
    • Analytics: Integrate with tools like Google Analytics or Mixpanel:
      Poll::voted(function ($poll, $user) {
          Analytics::track('poll_voted', ['poll_id' => $poll->id]);
      });
      
  3. Localization

    • Override default option labels or poll messages in language files:
      // resources/lang/en/poll.php
      return [
          'vote' => 'Cast your vote',
          'results' => 'Results',
      ];
      
    • Use the trans helper in Blade:
      <button>{{ trans('poll.vote') }}</button>
      
  4. Testing

    • Use Laravel’s testing helpers to assert poll behavior:
      $response = $this->post('/polls/1/vote', ['option_id' => 1]);
      $response->assertRedirect('/polls/1');
      $this->assertDatabaseHas('votes', ['poll_id' => 1, 'user_id' => auth()->id()]);
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log