black/user
DDD/CQRS-oriented user management library by black/user, with a Symfony bundle for integration. Provides domain user model foundations and ORM configuration hooks to plug into your Symfony app. MIT licensed.
Installation Add the package via Composer:
composer require black/user
Check the releases page for a stable version (e.g., "black/user": "1.2.0").
Symfony Bundle Integration
Register the bundle in config/bundles.php:
return [
// ...
Black\Bundle\UserBundle\BlackUserBundle::class => ['all' => true],
];
Basic Configuration
Define your custom User entity (e.g., src/Account/Domain/Entity/User.php) and configure the bundle in config/packages/black_user.yaml:
black_user:
db_driver: orm # or 'doctrine' if using Doctrine ORM
user_class: Account\Domain\Entity\User
First Use Case
Create a simple User entity extending the base class (example placeholder—check the package’s src/Entity/User.php for details):
namespace Account\Domain\Entity;
use Black\User\Entity\User as BaseUser;
class User extends BaseUser
{
// Add custom fields/methods here
}
Run migrations (php bin/console doctrine:migrations:diff + php bin/console doctrine:migrations:migrate).
User Creation Use the bundle’s command or service to create users:
use Black\User\Command\CreateUserCommand;
use Black\User\CommandHandler\CreateUserCommandHandler;
$command = new CreateUserCommand(
'john.doe@example.com',
'securepassword123',
['role' => 'ROLE_USER']
);
$handler = new CreateUserCommandHandler($entityManager);
$user = $handler->handle($command);
Authentication
Integrate with Symfony’s security system by configuring a UserProvider:
# config/packages/security.yaml
security:
providers:
black_user_provider:
id: Black\User\Security\UserProvider
Domain-Driven Design (DDD) Patterns
UpdateUserCommand, GetUserQuery).UserRegisteredEvent) for side effects:
use Black\User\Event\UserRegisteredEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class UserRegistrationSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
UserRegisteredEvent::class => 'onUserRegistered',
];
}
public function onUserRegistered(UserRegisteredEvent $event): void
{
// Send welcome email, log activity, etc.
}
}
API Integration Use Symfony’s serializer to expose user data:
use Black\User\Entity\User;
use Symfony\Component\Serializer\Annotation\Groups;
class User
{
#[Groups(['user:read'])]
public string $email;
#[Groups(['user:write'])]
public string $password;
}
User entity uses Doctrine annotations/attributes for mappings (e.g., @ORM\Entity).User class to add custom validation constraints (e.g., Symfony’s Assert).CommandHandler or use the bundle’s test utilities for unit/integration tests.Version Mismatches
@stable Composer constraint may pull unstable versions. Pin to a specific release (e.g., "1.2.0").Entity Inheritance
User class carefully. Avoid breaking method signatures or required fields.protected properties, ensure your subclass initializes them in the constructor.Configuration Overrides
db_driver must match your setup (orm for Doctrine, doctrine for Doctrine ORM). Misconfiguration may cause:
[RuntimeException] Driver "xyz" is not supported.
Event Dispatching
UserRegisteredEvent are not auto-dispatched. Subscribe explicitly in your services.yaml:
services:
App\EventSubscriber\UserRegistrationSubscriber:
tags: ['kernel.event_subscriber']
CommandHandler for exceptions. Enable debug mode (APP_DEBUG=1) for stack traces.user_class in black_user.yaml matches your custom entity’s fully qualified name.php bin/console doctrine:schema:validate to check schema compatibility.Custom Commands
Extend the base commands (e.g., CreateUserCommand) or create new ones by implementing CommandInterface:
namespace App\Command;
use Black\User\Command\CommandInterface;
class CustomUserCommand implements CommandInterface
{
// Implement handle() and validate() methods
}
Event Customization
Create custom events by extending UserEvent:
namespace App\Event;
use Black\User\Event\UserEvent;
class UserProfileUpdatedEvent extends UserEvent
{
public function __construct(User $user, array $changes)
{
parent::__construct($user);
$this->changes = $changes;
}
}
Security Integration
Override the UserProvider to add custom logic (e.g., multi-factor auth):
use Black\User\Security\UserProvider as BaseUserProvider;
class CustomUserProvider extends BaseUserProvider
{
public function loadUserByIdentifier(string $identifier): UserInterface
{
// Custom logic here
return parent::loadUserByIdentifier($identifier);
}
}
API Resources
Use Symfony’s Resource component to shape API responses:
use Symfony\Component\Serializer\Annotation\Context;
#[Context(['groups' => ['user:read']])]
class UserResource
{
public function __construct(private User $user) {}
public function getData(): array
{
return [
'id' => $this->user->getId(),
'email' => $this->user->getEmail(),
];
}
}
User class may use traits (e.g., UserTrait). Reuse them in your entity to avoid duplication.@ORM\PrePersist/@ORM\PostLoad to the User entity for automatic actions (e.g., password hashing).use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
#[AsLiveComponent('user_form')]
class UserFormComponent extends Component
{
// Handle user updates in real-time
}
How can I help you explore Laravel packages today?