appsco/assertion-voter-bundle
composer require appsco/assertion-voter-bundle
AppKernel.php:
new Appsco\AssertionVoterBundle\AppscoAssertionVoterBundle(),
app/config/config.yml:
appsco_assertion_voter:
voter_record_provider: appsco.assertion.voter_record_provider.orm
voter_factory: appsco.assertion.voter_factory.simple
// src/Acme/YourBundle/Entity/VoterRecord.php
namespace Acme\YourBundle\Entity;
use Appsco\AssertionVoterBundle\Entity\VoterRecord as BaseVoterRecord;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class VoterRecord extends BaseVoterRecord { ... }
config.yml:
appsco_assertion_voter:
voter_record_class: Acme\YourBundle\Entity\VoterRecord
public function fooAction()
{
$info = $this->get('your_info_provider')->getInfo();
$roles = $this->get('appsco.assertion.role_resolver')->resolve($info);
return $this->render('template.html.twig', ['roles' => $roles]);
}
$info = $this->get('your.assertion_data_service')->getAssertions();
role_resolver service.
$roles = $this->get('appsco.assertion.role_resolver')->resolve($info);
BaseVoterRecord and map it to your database schema.
/**
* @ORM\Column(type="string")
*/
private $issuer;
VoterRecord table with issuer/attribute/value/role mappings.
Example:
| issuer | attribute | value | role |
|----------|-----------|--------|---------------|
| "acme" | "status" | "active" | ROLE_ACTIVE |
BWC\Component\AssertionVoter\DecisionMakerInterface and tag it.
# services.yml
my.custom_decision_maker:
class: My\Bundle\Service\CustomDecisionMaker
tags:
- { name: appsco.assertion.decision_maker, alias: custom }
$roles = $this->get('appsco.assertion.role_resolver')->resolve($info, 'custom');
config.yml:
appsco_assertion_voter:
voter_record_provider: appsco.assertion.voter_record_provider.dbal
Customize columns:
parameters:
appsco.assertion.voter_record_provider.dbal.table_name: custom_voter_records
appsco.assertion.voter_record_provider.dbal.role_column: user_role
VoterRecordProviderInterface for non-Doctrine setups (e.g., MongoDB, Redis).Deprecated Symfony 2.1 Dependency: The bundle requires Symfony 2.1, which may cause compatibility issues with modern Laravel/Lumen (though this is a Symfony bundle; clarify if Laravel is the target framework—adjust accordingly). Workaround: Use in a Symfony 2.1+ project or fork/modernize the bundle.
Missing VoterRecord Configuration:
Forgetting to set voter_record_class (for ORM) or table_name (for DBAL) will throw ServiceNotFoundException.
Fix: Always validate config.yml after setup.
Role Resolution Edge Cases:
$info) returns no roles. Handle gracefully:
$roles = $this->get('appsco.assertion.role_resolver')->resolve($info ?? []);
Database Schema Mismatches:
Ensure VoterRecord columns (issuer, attribute, value, role) match your provider’s expectations. DBAL defaults to VoterRecord table; override if needed.
$this->get('logger')->debug('Resolved roles:', ['roles' => $roles]);
VoterRecord table directly to verify mappings:
SELECT * FROM voter_record WHERE issuer = 'acme';
DecisionMakerInterface::makeDecision() with debug logs:
public function makeDecision($info, $context) {
$this->logger->debug('Decision context:', $context);
return $this->evaluate($info);
}
Custom Voter Factories:
Extend appsco.assertion.voter_factory.simple for complex role logic:
services:
custom.voter_factory:
class: My\Bundle\Service\CustomVoterFactory
arguments: ['@service_container']
Update config.yml:
appsco_assertion_voter:
voter_factory: custom.voter_factory
Dynamic Role Resolution:
Use event listeners to modify roles at runtime (e.g., add ROLE_TEMPORARY based on time):
$roleResolver->addPostResolver(function($roles) {
return array_merge($roles, ['ROLE_TEMPORARY']);
});
Caching: Cache resolved roles to avoid repeated database lookups:
$cache = $this->get('cache');
$cachedRoles = $cache->get('assertion_roles_' . md5(serialize($info)));
if (!$cachedRoles) {
$cachedRoles = $this->get('appsco.assertion.role_resolver')->resolve($info);
$cache->set('assertion_roles_' . md5(serialize($info)), $cachedRoles, 3600);
}
How can I help you explore Laravel packages today?