Weave Code
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

Platform User Persona Bundle Laravel Package

digitalstate/platform-user-persona-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require digitalstate/platform-user-persona-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        DigitalState\PlatformUserPersonaBundle\DigitalStatePlatformUserPersonaBundle::class => ['all' => true],
    ];
    
  2. Database Migration: Run the bundle’s migrations (check src/Resources/migrations/ for schema):

    php bin/console doctrine:migrations:migrate
    
  3. 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();
    
  4. Key Classes:

    • Persona (main entity)
    • PersonaRepository (for queries)
    • PersonaType (DQL extensions, if used)

Implementation Patterns

Core Workflows

  1. Persona Assignment:

    • Use PersonaManager (if provided) or manually persist Persona entities.
    • Example: Assign multiple personas to a user:
      $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();
      
  2. Querying Personas:

    • Fetch all personas for a user:
      $personas = $this->getDoctrine()
          ->getRepository(Persona::class)
          ->findBy(['user' => $this->getUser()]);
      
    • Check if a user has a specific persona:
      $hasAdmin = $this->getDoctrine()
          ->getRepository(Persona::class)
          ->existsBy(['user' => $user, 'type' => 'admin']);
      
  3. Integration with Security:

    • Use Voter or AccessControl to restrict routes based on persona:
      # config/security.yaml
      access_control:
          - { path: ^/admin, roles: ROLE_ADMIN_PERSONA }
      
    • Create a custom voter:
      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']);
          }
      }
      
  4. Dynamic Profile Switching:

    • Allow users to "switch" personas (e.g., for multi-role workflows):
      $currentPersona = $this->getCurrentPersona(); // Custom service
      $newPersona = $this->getDoctrine()
          ->getRepository(Persona::class)
          ->findOneBy(['user' => $user, 'type' => 'editor']);
      $this->setCurrentPersona($newPersona); // Store in session/token
      

Advanced Patterns

  1. Persona-Specific Data:

    • Extend 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...
      }
      
  2. Event-Driven Workflows:

    • Listen for persona creation/updates:
      // 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 }
      
  3. API Integration:

    • Expose personas via API (e.g., with API Platform):
      # config/api_platform/resources.yaml
      resources:
          DigitalState\PlatformUserPersonaBundle\Entity\Persona:
              collectionOperations:
                  get:
                      security: "is_granted('ROLE_USER')"
              itemOperations:
                  get:
                      security: "is_granted('ROLE_USER')"
      

Gotchas and Tips

Common Pitfalls

  1. Missing Migrations:

    • Always run migrations after installation. The bundle may assume tables like persona exist.
    • If extending, create custom migrations for new fields:
      php bin/console make:migration
      
  2. Circular References:

    • Avoid bidirectional associations without proper lazy-loading. Example:
      // Persona.php
      #[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'personas')]
      private $user;
      
      Ensure User has personas defined as OneToMany with mappedBy.
  3. Type Collisions:

    • Persona 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();
      }
      
  4. Performance with Large Datasets:

    • Use DQL for complex queries instead of loading all personas:
      $personas = $this->createQueryBuilder('p')
          ->where('p.user = :user')
          ->andWhere('p.type IN (:types)')
          ->setParameter('user', $user)
          ->setParameter('types', ['admin', 'editor'])
          ->getQuery()
          ->getResult();
      

Debugging Tips

  1. Entity Not Found:

    • Verify the Persona entity is properly mapped and the DigitalStatePlatformUserPersonaBundle is enabled in bundles.php.
  2. Query Issues:

    • Enable SQL logging in config/packages/dev/doctrine.yaml:
      doctrine:
          dbal:
              logging: true
              profiling: true
      
    • Check for typos in type values (case-sensitive).
  3. Permission Denied:

    • Ensure voters/services are properly tagged and loaded. Test with:
      php bin/console debug:container persona_voter
      

Extension Points

  1. Custom Persona Types:

    • Extend 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;
          }
      }
      
  2. Validation:

    • Add constraints to Persona:
      use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
      
      #[UniqueEntity(fields: ['user', 'type'], message: 'This persona already exists.')]
      class Persona {}
      
  3. Serialization:

    • Override Persona serialization (e.g., for API responses):
      use Symfony\Component\Serializer\Annotation\Groups;
      
      class Persona {
          #[Groups(['persona:read'])]
          public function getType(): string { ... }
      }
      
  4. Testing:

    • Mock the PersonaRepository in unit tests:
      $personaRepo = $this->createMock(PersonaRepository::class);
      $personaRepo->method('findBy')->willReturn([$mockPersona]);
      $container->set(PersonaRepository::class, $personaRepo);
      
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor