# 🎯 Behavioral Traits Behavioral traits add common functionality to your DTOs without writing repetitive code. They provide standardized patterns for timestamps, UUIDs, soft deletes, and more. ## How Traits Work ```yaml # In your YAML definition header: class: UserDto namespace: App\DTOs traits: [HasTimestamps, HasUuid, SoftDeletes] # Add behavioral traits # Laravel Arc automatically adds: # - Timestamp fields (created_at, updated_at) # - UUID field with auto-generation # - Soft delete functionality ``` Traits automatically add fields, methods, and functionality to your generated DTOs. ## Available Traits ### HasTimestamps Adds automatic timestamp tracking: ```yaml header: traits: [HasTimestamps] # Automatically adds these fields: fields: created_at: type: datetime auto_fill: true description: "Creation timestamp" updated_at: type: datetime auto_fill: true description: "Last update timestamp" ``` **Generated Methods:** ```php // Touch updated_at timestamp $dto->touch(); // Check if recently created (within last hour) $dto->wasRecentlyCreated(); // boolean // Get age of record $dto->getAge(); // Carbon diff string ``` ### HasUuid Adds UUID field with automatic generation: ```yaml header: traits: [HasUuid] # Automatically adds: fields: uuid: type: uuid auto_fill: true unique: true description: "Unique identifier" ``` **Generated Methods:** ```php // Get UUID string $dto->getUuid(); // "550e8400-e29b-41d4-a716-446655440000" // Generate new UUID $dto->regenerateUuid(); // Find by UUID (when used with collections) UserDto::findByUuid($uuid); ``` ### SoftDeletes Adds soft delete functionality: ```yaml header: traits: [SoftDeletes] # Automatically adds: fields: deleted_at: type: datetime nullable: true description: "Soft delete timestamp" ``` **Generated Methods:** ```php // Soft delete $dto->delete(); // Restore $dto->restore(); // Check if deleted $dto->isDeleted(); // boolean // Force delete (permanent) $dto->forceDelete(); ``` ### HasTags Adds tagging functionality: ```yaml header: traits: [HasTags] # Automatically adds: fields: tags: type: array items: type: string transformers: [trim_array, lowercase_array, unique_array] description: "Associated tags" ``` **Generated Methods:** ```php // Add tags $dto->addTag('important'); $dto->addTags(['urgent', 'review']); // Remove tags $dto->removeTag('outdated'); $dto->removeTags(['old', 'deprecated']); // Check tags $dto->hasTag('important'); // boolean $dto->hasAnyTag(['urgent', 'priority']); // boolean $dto->hasAllTags(['important', 'urgent']); // boolean // Get tags $dto->getTags(); // array $dto->getTagsAsString(); // "important, urgent, review" ``` ### HasStatus Adds status management with predefined states: ```yaml header: traits: [HasStatus] # Configuration (optional) trait_config: HasStatus: default: "draft" states: [draft, published, archived, deleted] transitions: draft: [published, archived] published: [archived, deleted] archived: [published, deleted] # Automatically adds: fields: status: type: string default: "draft" enum: [draft, published, archived, deleted] ``` **Generated Methods:** ```php // Change status $dto->setStatus('published'); // Check status $dto->isDraft(); // boolean $dto->isPublished(); // boolean $dto->isArchived(); // boolean // Status transitions $dto->publish(); // draft → published $dto->archive(); // any → archived $dto->restore(); // archived → previous state // Get available transitions $dto->getAvailableTransitions(); // array $dto->canTransitionTo('published'); // boolean ``` ### HasMetadata Adds flexible metadata storage: ```yaml header: traits: [HasMetadata] # Automatically adds: fields: metadata: type: json default: {} description: "Additional metadata" ``` **Generated Methods:** ```php // Set metadata $dto->setMeta('color', 'blue'); $dto->setMeta('settings', ['theme' => 'dark']); // Get metadata $dto->getMeta('color'); // "blue" $dto->getMeta('missing', 'default'); // "default" $dto->getAllMeta(); // array // Check metadata $dto->hasMeta('color'); // boolean // Remove metadata $dto->removeMeta('color'); $dto->clearMeta(); ``` ### HasSlug Adds automatic slug generation: ```yaml header: traits: [HasSlug] # Configuration trait_config: HasSlug: source: "title" # Field to generate slug from unique: true # Automatically adds: fields: slug: type: string unique: true transformers: [slugify] ``` **Generated Methods:** ```php // Generate slug from title $dto->generateSlug(); // "my-awesome-title" // Regenerate slug $dto->regenerateSlug(); // Get URL-friendly slug $dto->getSlug(); // "my-awesome-title" ``` ## Combining Multiple Traits You can use multiple traits together: ```yaml header: class: BlogPostDto namespace: App\DTOs\Blog traits: [HasTimestamps, HasUuid, HasSlug, HasTags, HasStatus, SoftDeletes] # Configuration for multiple traits trait_config: HasSlug: source: "title" unique: true HasStatus: default: "draft" states: [draft, review, published, archived] transitions: draft: [review] review: [draft, published, archived] published: [archived] archived: [published] fields: title: type: string required: true max_length: 255 content: type: text required: true author_id: type: integer required: true ``` **Generated DTO includes all trait functionality:** ```php $post = BlogPostDto::from([ 'title' => 'My Awesome Blog Post', 'content' => 'This is the content...', 'author_id' => 1 ]); // Trait methods available $post->generateSlug(); // HasSlug $post->addTag('tutorial'); // HasTags $post->setStatus('review'); // HasStatus $post->touch(); // HasTimestamps echo $post->getUuid(); // HasUuid ``` ## Custom Traits Create your own behavioral traits: ### 1. Create Trait Class ```php with(['priority' => $priority]); } public function isHighPriority(): bool { return in_array($this->priority, ['high', 'urgent']); } public function isUrgent(): bool { return $this->priority === 'urgent'; } public function getPriorityColor(): string { return match($this->priority) { 'low' => 'green', 'medium' => 'yellow', 'high' => 'orange', 'urgent' => 'red', }; } } ``` ### 2. Register Trait ```php // In AppServiceProvider use Grazulex\LaravelArc\Support\Traits\BehavioralTraitRegistry; public function boot() { BehavioralTraitRegistry::register('HasPriority', [ 'trait_class' => App\Traits\DTO\HasPriority::class, 'fields' => [ 'priority' => [ 'type' => 'string', 'default' => 'medium', 'enum' => ['low', 'medium', 'high', 'urgent'], 'description' => 'Task priority level' ] ] ]); } ``` ### 3. Use in YAML ```yaml header: class: TaskDto namespace: App\DTOs traits: [HasTimestamps, HasPriority] fields: title: type: string required: true description: type: text ``` ## Real-World Examples ### User Management DTO ```yaml header: class: UserDto namespace: App\DTOs\Users traits: [HasTimestamps, HasUuid, SoftDeletes, HasStatus, HasMetadata] trait_config: HasStatus: default: "pending" states: [pending, active, inactive, banned, deleted] transitions: pending: [active, inactive] active: [inactive, banned] inactive: [active, banned] banned: [deleted] fields: name: type: string required: true max_length: 255 email: type: email required: true unique: true email_verified_at: type: datetime nullable: true ``` **Usage:** ```php $user = UserDto::from([ 'name' => 'John Doe', 'email' => 'john@example.com' ]); // Trait functionality $user->setStatus('active'); $user->setMeta('last_login_ip', '192.168.1.1'); $user->setMeta('preferences', ['theme' => 'dark']); // Check status if ($user->isActive()) { // User can access system } // Soft delete $user->delete(); // Sets deleted_at timestamp ``` ### Content Management DTO ```yaml header: class: ArticleDto namespace: App\DTOs\Content traits: [HasTimestamps, HasSlug, HasTags, HasStatus, HasMetadata] trait_config: HasSlug: source: "title" unique: true HasStatus: default: "draft" states: [draft, review, published, featured, archived] fields: title: type: string required: true max_length: 255 excerpt: type: text max_length: 500 content: type: text required: true author_id: type: integer required: true category_id: type: integer required: true ``` **Usage:** ```php $article = ArticleDto::from([ 'title' => 'Understanding Laravel Arc', 'content' => 'Laravel Arc is...', 'author_id' => 1, 'category_id' => 5 ]); // Auto-generate slug from title $article->generateSlug(); // "understanding-laravel-arc" // Add tags $article->addTags(['laravel', 'php', 'tutorial']); // Set metadata $article->setMeta('reading_time', '5 minutes'); $article->setMeta('difficulty', 'beginner'); // Publish article $article->setStatus('published'); ``` ## Real-World Generated Example ### YAML Definition with Multiple Traits From `examples/modern-traits-comprehensive.yaml`: ```yaml # Comprehensive example showing all behavioral traits working together header: dto: AdvancedUserDTO model: App\Models\User namespace: App\DTO traits: - HasTimestamps # Adds created_at, updated_at - HasUuid # Adds UUID field - HasSoftDeletes # Adds deleted_at, restore methods - HasTagging # Adds tags field and tag methods - HasAuditing # Adds creator_id, updater_id tracking - HasCaching # Adds cache methods - HasSlug # Adds slug field from name - HasStatus # Adds status field with state management - ValidatesData # Adds validation methods - ConvertsData # Adds export methods fields: name: type: string required: true validation: [required, string, min:2, max:100] transformers: [trim, title_case] email: type: string required: true validation: [required, email, unique:users] transformers: [trim, lowercase] bio: type: text required: false validation: [nullable, string, max:1000] transformers: [trim] # Traits configuration trait_options: HasSlug: source_field: name unique: true HasStatus: default: "active" allowed: [active, inactive, pending, banned] HasCaching: ttl: 3600 ``` ### Generated DTO with All Traits The above YAML generates a comprehensive DTO: ```php touch() // HasTimestamps // $dto->addTag('vip') // HasTagging // $dto->setStatus('active') // HasStatus // $dto->cache(3600) // HasCaching // $dto->isDeleted() // HasSoftDeletes // $dto->getSlug() // HasSlug } ``` ## Trait Configuration ### Global Configuration Configure traits globally in `config/arc.php`: ```php 'behavioral_traits' => [ 'HasTimestamps' => [ 'created_field' => 'created_at', 'updated_field' => 'updated_at', 'auto_update' => true, ], 'HasUuid' => [ 'field_name' => 'uuid', 'version' => 4, 'auto_generate' => true, ], 'HasStatus' => [ 'default_states' => ['draft', 'published', 'archived'], 'field_name' => 'status', ], ]; ``` ### Per-DTO Configuration Override defaults in individual YAML files: ```yaml header: traits: [HasTimestamps, HasStatus] trait_config: HasTimestamps: created_field: "date_created" updated_field: "date_modified" HasStatus: field_name: "state" default: "new" states: [new, processing, completed, failed] ``` ## What's Next? Now that you understand behavioral traits: - **[Generated DTO Structure](Generated-DTO-Structure.md)** - See how traits affect generated code - **[Collections](Collections.md)** - Working with arrays of DTOs - **[Nested DTOs](Nested-DTOs.md)** - Complex data structures - **[Complete Examples](Complete-Examples.md)** - Real-world usage examples --- *Behavioral traits eliminate boilerplate code and provide consistent patterns across your DTOs. Use them to build feature-rich data objects effortlessly.* ⚡