PHP code example of yntech / domain-forge

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);
    }
}

// Create with hashed password (from database)
$user = User::fromPrimitives(
    id: '123',
    email: '[email protected]',
    password: '$2y$10$...' // Already hashed
);

// Hash plain password
$password = UserPassword::hash('my-plain-password');

// Create user with hashed password
$user = User::create(
    email: UserEmail::create('[email protected]'),
    password: UserPassword::hash('plain-password')
);

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;
    }
}

// ❌ Wrong
OrderStatus::fromString('PENDING'); // ValueError

// ✅ Correct
OrderStatus::fromString('pending');
bash
php artisan domain-forge:install
bash
composer dump-autoload
bash
php artisan domain-forge:domain User

src/Contexts/User/
├── Application/
│   ├── Commands/
│   ├── Handlers/
│   ├── DTOs/
│   ├── Services/
│   └── UseCases/
├── Domain/
│   ├── Entities/
│   │   └── User.php
│   ├── Contracts/
│   │   └── UserRepositoryContract.php
│   ├── Exceptions/
│   └── ValueObjects/
└── Infrastructure/
    ├── Http/
    │   ├── Controllers/
    │   ├── Requests/
    │   ├── Resources/
    │   └── Routes/
    │       └── User.php
    ├── Persistence/
    │   ├── Mappers/
    │   └── Repositories/
    │       └── Eloquent/
    │           └── UserRepository.php
    └── UserServiceProvider.php
bash
php artisan domain-forge:publish-stubs
bash
php artisan domain-forge:publish-stubs --force
bash
chmod -R 755 src/Contexts
chmod 755 bootstrap/providers.php
bash
composer dump-autoload