digitalstate/platform-user-persona-bundle
Installation:
composer require digitalstate/platform-user-persona-bundle
Add to config/bundles.php:
return [
// ...
DigitalState\PlatformUserPersonaBundle\DigitalStatePlatformUserPersonaBundle::class => ['all' => true],
];
Database Migration:
Run the bundle’s migrations (check src/Resources/migrations/ for schema):
php bin/console doctrine:migrations:migrate
First Use Case: Attach a persona to a user in a controller:
use DigitalState\PlatformUserPersonaBundle\Entity\Persona;
use DigitalState\PlatformUserPersonaBundle\Entity\PersonaRepository;
$persona = new Persona();
$persona->setUser($this->getUser());
$persona->setType('admin'); // Customize based on your needs
$em->persist($persona);
$em->flush();
Key Classes:
Persona (main entity)PersonaRepository (for queries)PersonaType (DQL extensions, if used)Persona Assignment:
PersonaManager (if provided) or manually persist Persona entities.$user = $this->getUser();
$personas = ['admin', 'editor', 'guest'];
foreach ($personas as $type) {
$persona = new Persona();
$persona->setUser($user);
$persona->setType($type);
$em->persist($persona);
}
$em->flush();
Querying Personas:
$personas = $this->getDoctrine()
->getRepository(Persona::class)
->findBy(['user' => $this->getUser()]);
$hasAdmin = $this->getDoctrine()
->getRepository(Persona::class)
->existsBy(['user' => $user, 'type' => 'admin']);
Integration with Security:
Voter or AccessControl to restrict routes based on persona:
# config/security.yaml
access_control:
- { path: ^/admin, roles: ROLE_ADMIN_PERSONA }
use DigitalState\PlatformUserPersonaBundle\Entity\Persona;
class PersonaVoter extends AbstractVoter {
public function supports($attribute, $subject) {
return $attribute === 'ROLE_ADMIN_PERSONA' && $subject instanceof User;
}
protected function voteOnAttribute($attribute, $user, TokenInterface $token) {
return $this->getPersonaRepository()
->existsBy(['user' => $user, 'type' => 'admin']);
}
}
Dynamic Profile Switching:
$currentPersona = $this->getCurrentPersona(); // Custom service
$newPersona = $this->getDoctrine()
->getRepository(Persona::class)
->findOneBy(['user' => $user, 'type' => 'editor']);
$this->setCurrentPersona($newPersona); // Store in session/token
Persona-Specific Data:
Persona to store additional fields (e.g., settings, metadata):
// src/Entity/PersonaExtension.php
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class PersonaExtension {
#[ORM\OneToOne(targetEntity: Persona::class, inversedBy: 'extension')]
private $persona;
#[ORM\Column(type: 'json')]
private $settings = [];
// Getters/setters...
}
Event-Driven Workflows:
// src/EventListener/PersonaListener.php
use DigitalState\PlatformUserPersonaBundle\Entity\Persona;
use Doctrine\ORM\Event\LifecycleEventArgs;
class PersonaListener {
public function postPersist(Persona $persona, LifecycleEventArgs $args) {
// Trigger logic (e.g., send welcome email, log activity)
}
}
Register in services.yaml:
services:
App\EventListener\PersonaListener:
tags:
- { name: doctrine.event_listener, event: postPersist, entity: DigitalState\PlatformUserPersonaBundle\Entity\Persona }
API Integration:
# config/api_platform/resources.yaml
resources:
DigitalState\PlatformUserPersonaBundle\Entity\Persona:
collectionOperations:
get:
security: "is_granted('ROLE_USER')"
itemOperations:
get:
security: "is_granted('ROLE_USER')"
Missing Migrations:
persona exist.php bin/console make:migration
Circular References:
// Persona.php
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'personas')]
private $user;
Ensure User has personas defined as OneToMany with mappedBy.Type Collisions:
type is a string. Validate uniqueness if needed:
// PersonaRepository.php
public function findByTypeAndUser(string $type, User $user) {
return $this->createQueryBuilder('p')
->andWhere('p.type = :type')
->andWhere('p.user = :user')
->setParameter('type', $type)
->setParameter('user', $user)
->getQuery()
->getOneOrNullResult();
}
Performance with Large Datasets:
$personas = $this->createQueryBuilder('p')
->where('p.user = :user')
->andWhere('p.type IN (:types)')
->setParameter('user', $user)
->setParameter('types', ['admin', 'editor'])
->getQuery()
->getResult();
Entity Not Found:
Persona entity is properly mapped and the DigitalStatePlatformUserPersonaBundle is enabled in bundles.php.Query Issues:
config/packages/dev/doctrine.yaml:
doctrine:
dbal:
logging: true
profiling: true
type values (case-sensitive).Permission Denied:
php bin/console debug:container persona_voter
Custom Persona Types:
Persona or create a trait for reusable logic:
// src/Entity/Trait/PersonaTrait.php
trait PersonaTrait {
public function hasRole(string $role): bool {
return $this->getType() === $role;
}
}
Validation:
Persona:
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
#[UniqueEntity(fields: ['user', 'type'], message: 'This persona already exists.')]
class Persona {}
Serialization:
Persona serialization (e.g., for API responses):
use Symfony\Component\Serializer\Annotation\Groups;
class Persona {
#[Groups(['persona:read'])]
public function getType(): string { ... }
}
Testing:
PersonaRepository in unit tests:
$personaRepo = $this->createMock(PersonaRepository::class);
$personaRepo->method('findBy')->willReturn([$mockPersona]);
$container->set(PersonaRepository::class, $personaRepo);
How can I help you explore Laravel packages today?