# ๐ Field Transformers Field transformers automatically modify and clean your data when creating DTOs. They provide a powerful way to ensure data consistency and apply business rules at the DTO level. ## How Transformers Work ``` Raw Input โ Transformers โ Validated Data โ DTO Creation โ โ โ โ " John DOE " โ trim โ "John DOE" โ title_case โ "John Doe" ``` Transformers run **before validation**, ensuring clean, consistent data throughout your application. ## Built-in Transformers ### String Transformers ```yaml fields: # Trim whitespace name: type: string transformers: [trim] # " John Doe " โ "John Doe" # Convert case email: type: email transformers: [trim, lowercase] # " USER@EXAMPLE.COM " โ "user@example.com" # Title case for names full_name: type: string transformers: [trim, title_case] # "john doe smith" โ "John Doe Smith" # Uppercase for codes product_code: type: string transformers: [trim, uppercase] # "abc123" โ "ABC123" ``` ### URL and Slug Transformers ```yaml fields: # Create URL-friendly slugs slug: type: string transformers: [slugify] # "Hello World! How are you?" โ "hello-world-how-are-you" # Clean URLs website: type: url transformers: [trim, normalize_url] # " HTTPS://EXAMPLE.COM/PATH " โ "https://example.com/path" # Social media handles twitter_handle: type: string transformers: [trim, lowercase, remove_at_symbol] # "@JohnDoe" โ "johndoe" ``` ### Numeric Transformers ```yaml fields: # Round decimals price: type: decimal precision: 2 transformers: [round_to_precision] # 19.999 โ 19.99 # Absolute values distance: type: decimal transformers: [absolute] # -15.5 โ 15.5 # Format phone numbers phone: type: string transformers: [normalize_phone] # "(555) 123-4567" โ "+15551234567" ``` ### Text Transformers ```yaml fields: # Remove HTML tags description: type: text transformers: [strip_tags, trim] # "
Hello world!
" โ "Hello world!" # Normalize whitespace content: type: text transformers: [normalize_whitespace] # "Hello\n\n\nworld" โ "Hello\nworld" # Excerpt generation excerpt: type: string transformers: [strip_tags, truncate:150, add_ellipsis] # Long text โ "First 150 characters..." ``` ## Advanced Transformers ### Custom Business Logic ```yaml fields: # Tax calculation tax_amount: type: decimal transformers: [calculate_tax] # Based on base_amount and tax_rate # Discount application final_price: type: decimal transformers: [apply_discount] # Original price minus discount # Generate reference numbers order_number: type: string transformers: [generate_order_number] # "ORD-2024-001234" ``` ### Data Validation and Correction ```yaml fields: # Validate and format credit card credit_card: type: string transformers: [format_credit_card, mask_credit_card] # "4111111111111111" โ "4111-****-****-1111" # Validate and format tax ID tax_id: type: string transformers: [format_tax_id, validate_tax_id] # "123456789" โ "123-45-6789" # Clean and validate postal codes postal_code: type: string transformers: [format_postal_code] # "k1a0a6" โ "K1A 0A6" (Canadian format) ``` ## Transformer Chaining Transformers execute in the order specified: ```yaml fields: product_name: type: string transformers: [trim, strip_tags, title_case, truncate:100] # " awesome product name " # โ "Awesome Product Name" (if under 100 chars) slug: type: string transformers: [trim, lowercase, slugify, ensure_unique] # " My Awesome Product! " # โ "my-awesome-product" or "my-awesome-product-2" if exists ``` ## Complete Transformer Reference ### String Manipulation ```yaml transformers: - trim # Remove leading/trailing whitespace - lowercase # Convert to lowercase - uppercase # Convert to uppercase - title_case # Title Case Conversion - snake_case # convert_to_snake_case - camel_case # convertToCamelCase - pascal_case # ConvertToPascalCase - kebab_case # convert-to-kebab-case ``` ### Text Processing ```yaml transformers: - strip_tags # Remove HTML/XML tags - strip_tags:allowed # Remove tags except allowed ones - normalize_whitespace # Normalize multiple spaces/newlines - remove_extra_spaces # Remove multiple consecutive spaces - truncate:length # Truncate to specified length - pad_left:length:char # Pad left side with character - pad_right:length:char # Pad right side with character ``` ### URL and Web ```yaml transformers: - slugify # Create URL-friendly slug - normalize_url # Normalize URL format - add_http # Add http:// if missing - remove_www # Remove www. prefix - extract_domain # Extract domain from URL ``` ### Numbers and Math ```yaml transformers: - round_to_precision # Round to field precision - absolute # Convert to absolute value - ceil # Round up to integer - floor # Round down to integer - format_currency # Format as currency - percentage_to_decimal # Convert 50% to 0.5 ``` ### Dates and Time ```yaml transformers: - parse_date # Parse various date formats - format_date:format # Format date to specific format - timezone_convert:tz # Convert timezone - relative_time # Convert to relative time ``` ### Validation and Formatting ```yaml transformers: - normalize_phone # Normalize phone number format - format_credit_card # Format credit card number - mask_credit_card # Mask credit card (show last 4) - validate_email # Ensure valid email format - normalize_email # Normalize email address ``` ## Real-World Examples ### User Registration DTO ```yaml header: class: UserRegistrationDto namespace: App\DTOs\Auth fields: # Clean and format name first_name: type: string required: true max_length: 50 transformers: [trim, title_case] last_name: type: string required: true max_length: 50 transformers: [trim, title_case] # Normalize email email: type: email required: true unique: true transformers: [trim, lowercase, normalize_email] # Format username username: type: string required: true unique: true min_length: 3 max_length: 20 transformers: [trim, lowercase, alphanumeric_only] # Clean phone number phone: type: string nullable: true transformers: [normalize_phone] ``` ### Product Data DTO ```yaml header: class: ProductDataDto namespace: App\DTOs\Catalog fields: # Product name and slug name: type: string required: true max_length: 255 transformers: [trim, title_case] slug: type: string unique: true transformers: [trim, lowercase, slugify, ensure_unique] # Clean description description: type: text max_length: 2000 transformers: [trim, strip_tags, normalize_whitespace] # Format pricing price: type: decimal precision: 2 min: 0 transformers: [round_to_precision] # Clean and format SKU sku: type: string required: true unique: true transformers: [trim, uppercase, alphanumeric_dash_only] # Process tags tags: type: array items: type: string transformers: [trim_array_items, lowercase_array, unique_array] ``` ### Contact Form DTO ```yaml header: class: ContactFormDto namespace: App\DTOs\Contact fields: # Personal information name: type: string required: true max_length: 100 transformers: [trim, title_case] email: type: email required: true transformers: [trim, lowercase] company: type: string nullable: true max_length: 100 transformers: [trim, title_case] # Message content subject: type: string required: true max_length: 200 transformers: [trim, title_case] message: type: text required: true max_length: 2000 transformers: [trim, strip_tags, normalize_whitespace] # Optional fields phone: type: string nullable: true transformers: [normalize_phone] website: type: url nullable: true transformers: [trim, lowercase, normalize_url, add_http] ``` ## Custom Transformers Create your own transformers for specific business needs: ### 1. Register Custom Transformer ```php // In AppServiceProvider or dedicated service provider use Grazulex\LaravelArc\Support\Transformers\TransformerRegistry; public function boot() { TransformerRegistry::register('format_tax_id', function ($value) { // Remove any existing formatting $clean = preg_replace('/[^0-9]/', '', $value); // Format as XXX-XX-XXXX if (strlen($clean) === 9) { return substr($clean, 0, 3) . '-' . substr($clean, 3, 2) . '-' . substr($clean, 5, 4); } return $value; }); } ``` ### 2. Use in YAML ```yaml fields: tax_id: type: string required: true transformers: [trim, format_tax_id] validation: ["regex:/^\d{3}-\d{2}-\d{4}$/"] ``` ### Advanced Custom Transformer ```php TransformerRegistry::register('generate_customer_id', function ($value, $context) { // Access other field values through context $prefix = $context['company_type'] === 'enterprise' ? 'ENT' : 'STD'; $timestamp = now()->format('ymd'); $random = str_pad((string) random_int(1, 9999), 4, '0', STR_PAD_LEFT); return "{$prefix}-{$timestamp}-{$random}"; }); ``` ## Transformer Performance ### Efficient Chaining ```yaml # Good - logical order transformers: [trim, lowercase, slugify] # Avoid - redundant operations transformers: [trim, lowercase, trim, uppercase, lowercase] ``` ### Conditional Transformers ```yaml fields: phone: type: string transformers: - trim - normalize_phone:if_not_empty # Only if value exists - format_phone:country={{country}} # Dynamic based on other field ``` ## Integration with Validation Transformers run before validation, ensuring clean data: ```yaml fields: email: type: email transformers: [trim, lowercase] # Clean first validation: ["email:rfc,dns"] # Then validate slug: type: string transformers: [slugify] # Create slug validation: ["unique:posts,slug"] # Then check uniqueness ``` ## What's Next? Now that you understand field transformers: - **[Behavioral Traits](Behavioral-Traits.md)** - Add common functionality to DTOs - **[Generated DTO Structure](Generated-DTO-Structure.md)** - Understanding the generated code - **[Collections](Collections.md)** - Working with arrays of DTOs - **[Complete Examples](Complete-Examples.md)** - See transformers in action --- *Field transformers ensure your data is clean, consistent, and ready for validation. They're the silent heroes of data integrity.* ๐งน