Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Text Value Objects Laravel Package

apie/text-value-objects

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require apie/text-value-objects
    

    Ensure your Laravel project meets the package's PHP version requirements (check composer.json for constraints).

  2. First Use Case Import the base TextValueObject class and extend it for domain-specific text values:

    use Apie\TextValueObjects\TextValueObject;
    
    class EmailAddress extends TextValueObject
    {
        public function __construct(string $value)
        {
            parent::__construct($value);
        }
    
        public function validate(): void
        {
            if (!filter_var($this->value, FILTER_VALIDATE_EMAIL)) {
                throw new \InvalidArgumentException('Invalid email format.');
            }
        }
    }
    

    Use it in a Laravel model or DTO:

    $email = new EmailAddress('user@example.com');
    

Implementation Patterns

Core Workflows

  1. Domain-Specific Text Validation Extend TextValueObject to enforce business rules:

    class Username extends TextValueObject
    {
        public function validate(): void
        {
            if (strlen($this->value) < 3) {
                throw new \InvalidArgumentException('Username must be at least 3 characters.');
            }
        }
    }
    
  2. Integration with Laravel Models Use accessors/mutators to convert between plain strings and TextValueObject instances:

    class User extends Model
    {
        protected $casts = [
            'email' => EmailAddress::class,
        ];
    
        public function setEmailAttribute(string $value)
        {
            $this->attributes['email'] = new EmailAddress($value);
        }
    
        public function getEmailAttribute(EmailAddress $value)
        {
            return $value->value;
        }
    }
    
  3. API Request Validation Validate incoming requests using Laravel's FormRequest:

    use Apie\TextValueObjects\TextValueObject;
    
    class StoreUserRequest extends FormRequest
    {
        public function validate()
        {
            return [
                'email' => ['required', function ($attribute, $value, $fail) {
                    try {
                        new EmailAddress($value);
                    } catch (\InvalidArgumentException $e) {
                        $fail($e->getMessage());
                    }
                }],
            ];
        }
    }
    
  4. Serialization/Deserialization Use Laravel's JSON serialization or custom logic:

    $serialized = json_encode(['email' => $user->email->value]);
    $deserialized = new EmailAddress(json_decode($serialized, true)['email']);
    

Gotchas and Tips

Pitfalls

  1. Validation Timing

    • validate() is called only during instantiation. Reuse objects carefully:
      $email = new EmailAddress('test@example.com'); // Validated once
      $email->value = 'invalid'; // No re-validation!
      
    • Fix: Add a revalidate() method or use immutable objects.
  2. Type Safety

    • The base class assumes string input. Explicitly type-hint constructors:
      public function __construct(string $value) { ... }
      
  3. Laravel Caching Quirks

    • Serialized TextValueObject instances may not cache correctly. Use value property explicitly:
      Cache::put('key', $user->email->value);
      

Debugging Tips

  • Override __toString() for debugging:

    public function __toString(): string
    {
        return sprintf('(%s: %s)', static::class, $this->value);
    }
    
  • Custom Exceptions Extend validation errors with domain-specific messages:

    throw new \InvalidArgumentException('Username must be alphanumeric.');
    

Extension Points

  1. Add Metadata Store additional attributes (e.g., createdAt):

    class Tag extends TextValueObject
    {
        public function __construct(string $value, public \DateTime $createdAt)
        {
            parent::__construct($value);
        }
    }
    
  2. Localization Internationalize validation messages:

    public function validate(): void
    {
        if (!preg_match('/^[a-z]+$/', $this->value)) {
            throw new \InvalidArgumentException(__('Validation.custom.alphabetic'));
        }
    }
    
  3. Immutable Design Prevent value modification after creation:

    private function __set(string $name, $value): void
    {
        throw new \RuntimeException('Immutable object.');
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
croct/coding-standard
croct/plug-php
nqxcode/phpmorphy
boundwize/pyrameter
testo/facade
headercat/phpstan-extension-ide-helper
yosymfony/parser-utils
innmind/black-box
babenkoivan/elastic-migrations
babenkoivan/elastic-adapter
develia/commons
dmstr/symfony-system-resources-bundle
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
renatomarinho/laravel-page-speed
develia/geo-bundle
austinheap/laravel-database-encryption
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle