Install the Bundle
Add the package via Composer (as shown in the README) and enable it in bundles.php.
composer require cnd/ddd-maker-bundle --dev
Run the Generator Command List available commands to understand the options:
php bin/console list cnd_ddd_maker
Example: Generate a Command and Handler for an existing entity:
php bin/console make:ddd:command User --command=CreateUserCommand --handler=CreateUserHandler
First Use Case
Scaffold a Query and Handler for a Product entity:
php bin/console make:ddd:query Product --query=GetProductByIdQuery --handler=GetProductByIdHandler
Verify generated files in:
src/Command/ (for commands)src/Query/ (for queries)src/Handler/ (for handlers)src/Repository/ (for repositories)src/Factory/ (for factories)Entity-Centric Generation
Use the bundle to derive CQRS artifacts from an existing entity (e.g., User, Order).
Example:
# Generate a Command + Handler + Repository
php bin/console make:ddd:command User --command=UpdateUserEmailCommand --handler=UpdateUserEmailHandler --repository=UserRepository
Symfony Messenger Integration The bundle auto-configures generated commands/queries for Symfony Messenger.
MESSENGER_TRANSPORT_DSN is configured in .env.@AsMessageHandler().Custom Templates Override default templates by copying files from:
vendor/cnd/ddd-maker-bundle/Resources/skeleton/
to:
config/packages/cnd_ddd_maker.yaml
Example:
cnd_ddd_maker:
templates:
command: '%kernel.project_dir%/templates/skeleton/command.php.twig'
Aggregate Root Generation For complex entities, generate an Aggregate Root with invariants:
php bin/console make:ddd:aggregate Order --aggregate=OrderAggregate --invariant=OrderInvariant
Value Object Support
Generate Value Objects (e.g., Email, Money) alongside entities:
php bin/console make:ddd:value-object Email --class=Email --property=address
Test Generation Scaffold PHPUnit tests for commands/queries:
php bin/console make:ddd:command-test CreateUserCommand --test=CreateUserCommandTest
make:entity to generate entities first, then use this bundle for DDD layers.@ApiResource().UserCreatedEvent).Namespace Conflicts
--namespace flag to override:
php bin/console make:ddd:command User --namespace=App\Domain\User\Command
Messenger Transport Misconfiguration
php bin/console messenger:consume async -vv
.env for MESSENGER_TRANSPORT_DSN (e.g., doctrine://default).Template Overrides Not Loading
php bin/console cache:clear
Entity Not Found
--entity to specify:
php bin/console make:ddd:query --entity=App\Entity\Product
Symfony 6+ Flex Auto-Wiring
autowire: true in config/packages/messenger.yaml for handlers.Dry Run Mode
Use --dry-run to preview changes without generating files:
php bin/console make:ddd:command User --dry-run
Verbose Output
Add -vv for detailed logs:
php bin/console make:ddd:query Product -vv
Custom Handlers Extend base handlers to add logic (e.g., validation, events):
// src/Handler/CreateUserHandler.php
public function __invoke(CreateUserCommand $command)
{
$user = $this->userFactory->create($command->email);
$this->userRepository->save($user);
$this->eventDispatcher->dispatch(new UserCreatedEvent($user));
}
Dynamic Command/Query Properties Use Twig logic in templates to conditionally generate properties:
{% if command.hasProperty('metadata') %}
private array $metadata;
{% endif %}
Post-Generation Hooks
Add a command subscriber to run tasks after generation (e.g., update composer.json):
# config/services.yaml
services:
App\EventListener\DddMakerSubscriber:
tags:
- { name: kernel.event_listener, event: cnd_ddd_maker.generate, method: onGenerate }
Database Migrations For repository-generated methods, manually add migrations or use Doctrine Migrations:
php bin/console make:migration
Batch Generation Combine commands in a script to scaffold an entire module:
#!/bin/bash
php bin/console make:ddd:command User --command=CreateUserCommand
php bin/console make:ddd:query User --query=ListUsersQuery
php bin/console make:ddd:repository User --repository=UserRepository
API Documentation Use NelmioApiDocBundle to auto-generate Swagger/OpenAPI docs for generated endpoints.
Domain Events
Extend handlers to dispatch events (e.g., UserRegisteredEvent) for event sourcing:
$this->eventDispatcher->dispatch(new UserRegisteredEvent($user));
How can I help you explore Laravel packages today?