1. Go to this page and download the library: Download yntech/domain-forge library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
yntech / domain-forge example snippets
namespace Src\Contexts\Product\Domain\Entities;
use Src\Contexts\Product\Domain\ValueObjects\ProductName;
use Src\Contexts\Product\Domain\ValueObjects\ProductPrice;
use Src\Contexts\Product\Domain\ValueObjects\ProductStock;
use Src\Contexts\Product\Domain\ValueObjects\ProductDescription;
final readonly class Product
{
private function __construct(
private ProductName $name,
private ProductPrice $price,
private ProductStock $stock,
private ProductDescription $description,
) {}
public function name(): ProductName
{
return $this->name;
}
public function price(): ProductPrice
{
return $this->price;
}
// ... other getters
public static function create(
ProductName $name,
ProductPrice $price,
ProductStock $stock,
ProductDescription $description,
): static {
return new self(
name: $name,
price: $price,
stock: $stock,
description: $description,
);
}
public static function fromPrimitives(
string $name,
float $price,
int $stock,
?string $description,
): static {
return new self(
name: ProductName::fromString($name),
price: ProductPrice::fromFloat($price),
stock: ProductStock::fromInt($stock),
description: ProductDescription::fromNullableString($description),
);
}
}
final readonly class PostExcerpt
{
private function __construct(
private ?string $value
) {
$this->validate($value);
}
public function value(): ?string
{
return $this->value;
}
public static function fromNullableString(?string $value): static
{
return new self($value);
}
}
namespace Src\Contexts\Order\Domain\Enums;
enum OrderStatus: string
{
case PENDING = 'pending';
case PROCESSING = 'processing';
case SHIPPED = 'shipped';
case DELIVERED = 'delivered';
case CANCELLED = 'cancelled';
/**
* Get all possible enum values
*
* @return array<self>
*/
public static function all(): array
{
return [
self::PENDING,
self::PROCESSING,
self::SHIPPED,
self::DELIVERED,
self::CANCELLED,
];
}
/**
* Create enum from string value
*
* @throws \ValueError
*/
public static function fromString(string $value): self
{
return self::from($value);
}
/**
* Create enum from nullable string value
*/
public static function fromNullableString(?string $value): ?self
{
return $value !== null ? self::from($value) : null;
}
/**
* Get string representation of the enum value
*/
public function toString(): string
{
return $this->value;
}
}
// Create entity with enum
$order = Order::create(
customer_name: OrderCustomerName::create('John Doe'),
status: OrderStatus::PENDING,
total: OrderTotal::create(99.99)
);
// From primitives
$order = Order::fromPrimitives(
id: '123-456',
customer_name: 'John Doe',
status: 'pending',
total: 99.99
);
// Access enum value
$status = $order->status(); // OrderStatus
$statusString = $order->status()->toString(); // 'pending'
$statusValue = $order->status()->value; // 'pending'
// Get all available statuses
$allStatuses = OrderStatus::all();
// Check specific status
if ($order->status() === OrderStatus::DELIVERED) {
// Order delivered logic
}
final readonly class UserId
{
private function __construct(
private string $value
) {
$this->validate($value);
}
/**
* Generate a new unique ID.
* By default uses UUID v4. Override to use ULID or other strategies.
*/
public static function generate(): static
{
return new self(\Illuminate\Support\Str::uuid()->toString());
}
/**
* Generate using ULID (uncomment if preferred)
*/
// public static function generate(): static
// {
// return new self(\Illuminate\Support\Str::ulid()->toString());
// }
public static function fromString(string $value): static
{
return new self($value);
}
public function value(): string
{
return $this->value;
}
}
public static function create(
UserName $name,
UserEmail $email,
): static {
return new self(
id: UserId::generate(), // Auto-generated
name: $name,
email: $email,
);
}
public static function generate(): static
{
// This is a placeholder. Usually handled by database auto-increment
throw new \RuntimeException('ID generation should be handled by the database');
}
final readonly class UserPassword
{
public static function fromHashed(string $hashedPassword): static
{
return new self($hashedPassword);
}
public static function hash(string $plainPassword): static
{
return new self(\Illuminate\Support\Facades\Hash::make($plainPassword));
}
public static function fromString(string $value): static
{
return new self($value);
}
}
final readonly class {{ className }}
{
private function __construct(
{{ constructorParams }}
private \DateTime $createdAt,
private ?\DateTime $updatedAt = null,
) {}
public function createdAt(): \DateTime
{
return $this->createdAt;
}
public function updatedAt(): ?\DateTime
{
return $this->updatedAt;
}
{{ getters }}
// ... rest of the code
}
namespace Src\Contexts\User\Infrastructure\Persistence\Mappers;
use App\Models\User as UserModel;
use Src\Contexts\User\Domain\Entities\User;
class UserMapper
{
public static function toDomain(UserModel $model): User
{
return User::fromPrimitives(
id: $model->id,
name: $model->name,
email: $model->email,
password: $model->password,
);
}
public static function toEloquent(User $entity): array
{
return [
'name' => $entity->name()->value(),
'email' => $entity->email()->value(),
'password' => $entity->password()->value(),
];
}
}
public function findById(UserId $id): ?User
{
$model = UserModel::find($id->value());
return $model ? UserMapper::toDomain($model) : null;
}
public function save(User $user): void
{
$data = UserMapper::toEloquent($user);
UserModel::updateOrCreate(
['id' => $user->id()->value()],
$data
);
}
// Instead of primitive obsession
$user->email = 'invalid-email'; // No validation!
// Use Value Objects
$user->updateEmail(UserEmail::create('[email protected]')); // Validated!
final readonly class Order
{
private array $domainEvents = [];
public function markAsPaid(): void
{
$this->status = OrderStatus::PAID;
$this->domainEvents[] = new OrderPaidEvent($this);
}
public function pullDomainEvents(): array
{
$events = $this->domainEvents;
$this->domainEvents = [];
return $events;
}
}