prism/poll-bundle
Prism Poll Bundle brings simple polling to Laravel apps, letting you create polls, add options, collect votes, and display results through a lightweight API and Blade-friendly views. A practical choice for adding community polls or quick surveys.
composer require prism/poll-bundle. The package predates Symfony Flex, so expect Composer to resolve against symfony/symfony 2.x constraints; if it won't install on your stack, clone the repo and add it as a path/VCS repository instead of fighting Packagist.app/AppKernel.php:
new Prism\PollBundle\PrismPollBundle(),
app/config/routing.yml:
prism_poll:
resource: "@PrismPollBundle/Resources/config/routing.yml"
prefix: /poll
prism_poll: in config.yml — set your entity class overrides and template names here if the bundle exposes them (check DependencyInjection/Configuration.php first; most Symfony2 bundles of this vintage only expose a couple of keys).php app/console doctrine:schema:update --force (or generate a migration).Resources/config/routing.yml and routing/*.yml — the actual endpoints you can call.Controller/ — the vote handler and results action; this is where CSRF and duplicate-vote logic lives (or doesn't).Entity/ — Poll, PollOption/Choice, Vote. These define your data model and the fields you'll extend.Resources/views/ — the Twig templates you'll override.Poll with a handful of options (fixture, doctrine:fixtures:load, or a quick admin form), then render the widget in a template with the bundle's helper/render() call and click through a vote end-to-end before touching anything else.Embed the widget, don't own it. Render the poll via a sub-request so the poll's controller stays in charge of state:
{{ render(controller('PrismPollBundle:Poll:show', { 'id': poll.id })) }}
This keeps your page controllers free of vote logic and lets you cache the surrounding page independently.
Override entities with inheritance, not edits. Create AppBundle\Entity\Poll extends Prism\PollBundle\Entity\Poll and add your @ORM\Table, extra fields (createdBy, closedAt, category), and relations. Then point the bundle at your class (either the documented config key or by mapping the bundle's entity as a MappedSuperclass). Never modify vendor/ — you'll lose the changes on the next composer update.
Vote endpoint as an AJAX contract. Post to the bundle's vote route with the option id, return the updated tallies, and re-render the results partial client-side:
$.post('/poll/vote/' + optionId, { _token: token }, function (html) {
$('#poll-results').html(html);
});
Treat the action's response format as part of your API surface — if the bundle returns a redirect, wrap it in your own thin controller that returns JSON instead.
Enforce one-vote-per-user yourself. Most simple poll bundles either don't dedupe at all or only do it by session. Add a unique composite index (poll_id, voter_key) in a migration and compute voter_key from user id when authenticated, falling back to a hashed cookie/IP. Application-level "check then insert" loses races; the DB constraint wins.
Template overrides go in app/Resources/PrismPollBundle/views/ mirroring the bundle's path. Copy the original file, then edit — this survives updates and is the cheapest way to restyle the widget.
Fixtures and testing. Seed polls via Doctrine fixtures; write a functional test that POSTs a vote twice and asserts the second is rejected. This is the single highest-value test for this bundle, because duplicate-vote handling is exactly where thin poll bundles are weakest.
Admin integration. Since the bundle gives you entities but no management UI, wire Poll and its options into SonataAdmin or EasyAdmin (collection form type for options) rather than building CRUD from scratch.
EntityManagerInterface, AbstractController, autowiring).count() vs denormalized counters), which is where you'll find N+1 queries and stale tallies./poll prefix that clashes with an existing route silently shadows one of them. Run app/console router:debug | grep poll after wiring it up.PrismPollBundle); if labels render as raw keys, check Resources/translations/ and either copy the file into app/Resources/translations/ or set the domain in your override template.app/console doctrine:query:sql 'SELECT * FROM poll_vote' to confirm votes land, the profiler's Doctrine panel for query counts on the results page, and app/logs/dev.log for the swallowed exceptions typical of AJAX actions returning generic 500s.composer.json if you go the VCS route — no tagged releases means dev-master can move under you.How can I help you explore Laravel packages today?