cptburke/application-primitives
Lightweight set of PHP/Laravel application primitives: small value objects, helpers, and foundational abstractions to standardize common patterns across a codebase. Intended to be reused across projects to keep core logic consistent and reduce boilerplate.
Installation
composer require cptburke/application-primitives
No publisher or service provider is required—use primitives as standalone classes.
First Use Case: Command Bus Define a command:
namespace App\Commands;
use CptBurke\ApplicationPrimitives\Command;
class CreateUserCommand implements Command
{
public function __construct(
public string $name,
public string $email
) {}
}
Create a handler:
namespace App\Handlers;
use App\Commands\CreateUserCommand;
use CptBurke\ApplicationPrimitives\CommandHandler;
class CreateUserCommandHandler implements CommandHandler
{
public function handle(CreateUserCommand $command): void
{
// Business logic here
}
}
Dispatch via the CommandBus:
use CptBurke\ApplicationPrimitives\CommandBus;
$bus = new CommandBus();
$bus->dispatch(new CreateUserCommand('John', 'john@example.com'));
Key Entry Points
CommandBus: Dispatch commands to handlers.EventBus: Publish/subscribe to events.QueryBus: Execute queries (read operations).Repository: Abstract data access (e.g., Eloquent, custom DB).Service: Stateless business logic wrapper.// Dispatch
$bus->dispatch(new SendEmailCommand($user->email, $template));
// Handle
class SendEmailCommandHandler implements CommandHandler
{
public function __construct(private EmailService $emailService) {}
public function handle(SendEmailCommand $command): void
{
$this->emailService->send($command->to, $command->template);
}
}
// Publish
$bus->publish(new UserCreatedEvent($user));
// Subscribe
class LogUserCreation implements EventSubscriber
{
public function handle(UserCreatedEvent $event): void
{
Log::info("User created: {$event->user->email}");
}
}
$bus->subscribe(LogUserCreation::class);
$queryBus = new QueryBus();
$user = $queryBus->ask(new GetUserQuery($userId));
class GetUserQuery implements Query
{
public function __construct(public int $id) {}
}
class UserRepository implements Repository
{
public function find(int $id): ?User
{
return User::find($id);
}
}
$repository = new UserRepository(); // Real
$repository = $this->mock(UserRepository::class); // Test
class TaxCalculatorService implements Service
{
public function calculate(float $amount): float
{
return $amount * 1.1; // 10% tax
}
}
use CptBurke\ApplicationPrimitives\CommandBus;
use CptBurke\ApplicationPrimitives\EventBus;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(CommandBus::class, fn() => new CommandBus());
$this->app->singleton(EventBus::class, fn() => new EventBus());
}
}
use CptBurke\ApplicationPrimitives\CommandBus;
class SendWelcomeEmailCommand extends Command
{
protected $signature = 'email:welcome {userId}';
public function handle(CommandBus $bus)
{
$bus->dispatch(new SendWelcomeEmailCommand($this->argument('userId')));
}
}
CommandBus/EventBus.
$bus->registerHandler(
CreateUserCommand::class,
CreateUserCommandHandler::class
);
$bus->registerHandlersFromContainer($this->app);
try-catch:
try {
$bus->dispatch($command);
} catch (Exception $e) {
Log::error("Command failed: {$e->getMessage()}");
}
$bus->subscribe(AsyncEventSubscriber::class);
// AsyncEventSubscriber dispatches events to a queue.
$bus = $this->partialMock(CommandBus::class, ['dispatch']);
$bus->expects($this->once())->method('dispatch');
$bus = new CommandBus([
'handler_namespace' => 'App\\Handlers',
]);
$bus->pipe(new LoggingMiddleware());
$bus = new CommandBus(['debug' => true]);
Logs dispatched commands/handlers to storage/logs/laravel.log.$this->app->bind(EmailService::class, fn() => new MailgunService());
How can I help you explore Laravel packages today?