dothiv/dothiv-valueobject-bundle
Symfony bundle providing a set of reusable value objects for Dothiv projects, aimed at consistent domain modeling and type-safe primitives. Includes common immutable objects and utilities to share across services and applications.
Installation
Add the bundle to your composer.json:
composer require dothiv/dothiv-valueobject-bundle
Register the bundle in config/bundles.php:
return [
// ...
Dothiv\ValueObjectBundle\DothivValueObjectBundle::class => ['all' => true],
];
First Use Case
Import and use a built-in value object (e.g., Email):
use Dothiv\ValueObjectBundle\ValueObject\Email;
$email = new Email('user@example.com');
// Automatically validates format on instantiation
Where to Look First
src/ValueObject/ for available value objects (e.g., Email, Money, PhoneNumber).tests/ for usage examples and edge cases.Validation on Instantiation Use built-in value objects to enforce invariants:
$phone = new PhoneNumber('+1234567890'); // Throws \InvalidArgumentException if invalid
Immutable Data Handling Treat value objects as immutable:
$money = new Money(100, 'USD');
// $money->amount = 200; // Fails (no setter)
Integration with Doctrine
Use ValueObjectType for database storage (if extended):
// Example: Custom Doctrine mapping (if supported)
$builder->add('email', ValueObjectType::class, [
'valueObjectClass' => Email::class,
]);
Custom Value Objects
Extend the base AbstractValueObject:
use Dothiv\ValueObjectBundle\ValueObject\AbstractValueObject;
class Username extends AbstractValueObject
{
public function __construct(string $value)
{
$this->assertValid($value, function($v) {
return strlen($v) >= 3 && preg_match('/^[a-zA-Z0-9_]+$/', $v);
});
$this->value = $value;
}
}
Serialization
Use __toString() or jsonSerialize() for interoperability:
$email = new Email('test@example.com');
echo $email; // "test@example.com"
OrderId, UserId).ApiToken).CacheTTL).No Built-in Doctrine Support
Limited Documentation
src/ or tests (e.g., EmailTest.php).Archived Status
Validation Logic
__construct(). Use assertValid() helper:
$this->assertValid($value, fn($v) => $v > 0, 'Value must be positive');
\InvalidArgumentException for invalid inputs.instanceof checks when accepting value objects:
if ($arg instanceof Email) { ... }
Add New Value Objects
Place custom classes in src/ValueObject/ (or a sub-namespace) and autoload them.
Override Defaults
Extend AbstractValueObject to modify behavior (e.g., serialization):
class CustomEmail extends Email {
public function __toString() { return strtoupper($this->value); }
}
Integration with Symfony Forms
Use ValueObjectType (if available) or create a custom form type:
use Symfony\Component\Form\Extension\Core\Type\TextType;
$builder->add('email', TextType::class, [
'constraints' => [new EmailConstraint()],
]);
__construct() may impact performance. Cache results if reused (e.g., in DTOs).How can I help you explore Laravel packages today?