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

User Bundle Laravel Package

damienharper/user-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require damienharper/user-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        DamienHarper\UserBundle\DamienHarperUserBundle::class => ['all' => true],
    ];
    
  2. Publish Configuration:

    php artisan vendor:publish --provider="DamienHarper\UserBundle\DamienHarperUserBundle" --tag="config"
    

    This generates config/user_bundle.php. Review and customize:

    • user_class (default: App\Entity\User)
    • firewall_name (default: main)
    • account_locking settings
    • password_expiration settings
  3. Create User Entity: Extend DamienHarper\UserBundle\Entity\User or implement DamienHarper\UserBundle\Model\UserInterface:

    namespace App\Entity;
    
    use DamienHarper\UserBundle\Entity\User as BaseUser;
    
    class User extends BaseUser {}
    
  4. Configure Security: Update config/packages/security.yaml:

    security:
        providers:
            user_provider:
                id: DamienHarper\UserBundle\Security\User\DoctrineUserProvider
        firewalls:
            main:
                provider: user_provider
                # ... other firewall config
    
  5. Run Migrations:

    php artisan doctrine:migrations:diff
    php artisan doctrine:migrations:migrate
    

First Use Case: Authentication

Use the built-in login form or create a custom controller:

use Symfony\Component\HttpFoundation\Request;
use DamienHarper\UserBundle\Security\Authentication\AuthenticationUtils;

class LoginController extends AbstractController
{
    public function login(Request $request, AuthenticationUtils $authenticationUtils)
    {
        if ($authenticationUtils->getLastAuthenticationError()) {
            // Handle error
        }

        return $this->render('security/login.html.twig', [
            'last_username' => $authenticationUtils->getLastUsername(),
            'error' => $authenticationUtils->getLastAuthenticationError(),
        ]);
    }
}

Implementation Patterns

Core Workflows

1. User Registration

Leverage the UserManager service:

use DamienHarper\UserBundle\Manager\UserManagerInterface;

class RegistrationController
{
    public function register(Request $request, UserManagerInterface $userManager)
    {
        $user = $userManager->createUser();
        $form = $this->createForm(UserType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $userManager->updateUser($user);
            // Redirect or flash success
        }
    }
}

2. Password Reset

Use the PasswordResetManager:

use DamienHarper\UserBundle\Manager\PasswordResetManagerInterface;

class PasswordResetController
{
    public function requestReset(
        Request $request,
        PasswordResetManagerInterface $passwordResetManager
    ) {
        $form = $this->createForm(PasswordResetRequestType::class);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $email = $form->get('email')->getData();
            $passwordResetManager->requestReset($email);
            // Notify user
        }
    }
}

3. Account Locking

Configure in config/user_bundle.php:

account_locking:
    enabled: true
    max_attempts: 5
    lock_time: 3600 # 1 hour

Check lock status in controllers:

$user = $this->getUser();
if ($user->isAccountLocked()) {
    // Handle locked account
}

4. Password Expiration

Configure in config/user_bundle.php:

password_expiration:
    enabled: true
    days_before_expiration: 30
    days_after_expiration: 7

Force password reset on login:

force_password_reset:
    enabled: true
    first_login_only: true

Integration Tips

Custom User Fields

Extend the User entity:

use DamienHarper\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

class User extends BaseUser
{
    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $customField;
}

Event Listeners

Listen to user events (e.g., UserEvents::PASSWORD_RESET):

use DamienHarper\UserBundle\Event\UserEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class CustomUserSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [
            UserEvents::PASSWORD_RESET => 'onPasswordReset',
        ];
    }

    public function onPasswordReset(PasswordResetEvent $event)
    {
        // Custom logic
    }
}

Twig Extensions

Access user data in templates:

{{ app.user.isAccountLocked() ? 'Account locked' : 'Active' }}
{{ app.user.getPasswordExpirationDate() }}

API Integration

Use the UserManager for API endpoints:

use DamienHarper\UserBundle\Manager\UserManagerInterface;

class UserApiController
{
    public function updateProfile(
        Request $request,
        UserManagerInterface $userManager
    ) {
        $user = $this->getUser();
        $data = json_decode($request->getContent(), true);
        $user->setFirstName($data['first_name']);
        $user->setLastName($data['last_name']);
        $userManager->updateUser($user);
    }
}

Gotchas and Tips

Pitfalls

  1. Doctrine Dependency:

    • The bundle requires Doctrine ORM. If using Eloquent or another ORM, this bundle is incompatible.
    • Workaround: Fork and modify the DoctrineUserProvider to work with your ORM.
  2. Configuration Overrides:

    • Customizing config/user_bundle.php must be done after publishing the config. Forgetting this step leads to default values being ignored.
    • Tip: Use php artisan config:clear after changes to ensure updates take effect.
  3. User Entity Naming:

    • The bundle expects a User entity by default. Renaming it requires updating:
      • config/user_bundle.php (user_class).
      • Security provider configuration.
      • Gotcha: Forgetting to update the security provider causes UserNotFoundException.
  4. Password Hashing:

    • The bundle uses Symfony’s UserPasswordHasherInterface. If you override the hasher, ensure compatibility with the bundle’s UserManager.
    • Tip: Test password resets thoroughly after changing hashers.
  5. Account Locking Race Conditions:

    • Concurrent login attempts may cause race conditions when incrementing failed attempts.
    • Mitigation: Use database transactions or optimistic locking in your User entity.
  6. First Login Password Reset:

    • Enabling force_password_reset with first_login_only: true requires checking the isFirstLogin() method, which may not persist across sessions.
    • Workaround: Store a first_login flag in the user entity and clear it after the first password reset.

Debugging Tips

  1. Authentication Errors:

    • Check AuthenticationUtils for errors:
      $error = $authenticationUtils->getLastAuthenticationError();
      // Error codes: 'invalid_credentials', 'account_locked', 'expired_password'
      
  2. Event Debugging:

    • Enable event dispatching logging in config/packages/dev/monolog.yaml:
      handlers:
          main:
              type: stream
              level: debug
              channels: ['!event']
      
  3. Database Issues:

    • Verify migrations include the user table with columns like failed_attempts, locked_at, password_expired_at.
    • Tip: Use php artisan doctrine:schema:validate to check schema consistency.
  4. Configuration Validation:

    • Run:
      php artisan config:dump
      
    • Verify user_bundle settings are loaded correctly.

Extension Points

  1. Custom User Provider:

    • Implement UserProviderInterface for non-Doctrine setups:
      use DamienHarper\UserBundle\Model\UserProviderInterface;
      
      class CustomUserProvider implements UserProviderInterface
      {
          public function loadUserByUsername($username) { ... }
          public function refreshUser(UserInterface $user) { ... }
          public function supportsClass($class) { ... }
      }
      
    • Register in security.yaml:
      providers:
          custom_user_provider:
              id: App\Security\CustomUserProvider
      
  2. Custom Password Reset Token:

    • Extend PasswordResetToken entity or override the PasswordResetManager:
      use DamienHarper\UserBundle\Manager\PasswordResetManagerInterface;
      
      class CustomPasswordResetManager implements PasswordResetManagerInterface
      {
          public function requestReset
      
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui