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

Eloquence Mutable Laravel Package

sofa/eloquence-mutable

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require sofa/eloquence-mutable
    

    Register the service provider in config/app.php:

    'providers' => [
        // ...
        Sofa\Eloquence\Mutable\MutableServiceProvider::class,
    ],
    
  2. First Use Case: Apply the Mutable trait to a model (e.g., User.php):

    use Sofa\Eloquence\Mutable\Mutable;
    
    class User extends Model
    {
        use Mutable;
    }
    
  3. Define Mutators: Override getMutators() to define attribute transformations:

    protected function getMutators(): array
    {
        return [
            'full_name' => [
                'get' => fn ($value) => ucwords($value),
                'set' => fn ($value) => strtolower($value),
            ],
            'age' => [
                'get' => fn ($value) => $value ? 'Adult' : 'Minor',
                'set' => fn ($value) => $value === 'Adult' ? 18 : null,
            ],
        ];
    }
    
  4. Usage:

    $user = new User();
    $user->full_name = 'john doe'; // Automatically transformed on set
    echo $user->full_name; // "John Doe" (transformed on get)
    

Implementation Patterns

Core Workflows

  1. Attribute Transformation: Use getMutators() to define dynamic get/set logic for attributes. Example:

    'email' => [
        'get' => fn ($value) => strtolower($value),
        'set' => fn ($value) => filter_var($value, FILTER_SANITIZE_EMAIL),
    ],
    
  2. Conditional Mutators: Leverage closures for runtime logic:

    'status' => [
        'get' => fn ($value) => $value === 'active' ? '✅' : '❌',
        'set' => fn ($value) => $value === '✅' ? 'active' : 'inactive',
    ],
    
  3. Related Model Mutators: Transform nested attributes (e.g., user.address.city):

    'address.city' => [
        'get' => fn ($value) => ucfirst($value),
        'set' => fn ($value) => strtolower($value),
    ],
    
  4. Validation Integration: Combine with Validable trait for pre-set validation:

    use Sofa\Eloquence\Validable\Validable;
    
    class User extends Model
    {
        use Mutable, Validable;
    
        protected function getMutators(): array { /* ... */ }
        protected function getRules(): array { return ['email' => 'required|email']; }
    }
    
  5. API Response Formatting: Use mutators to format responses (e.g., hide sensitive data):

    'password' => [
        'get' => fn () => '********',
    ],
    

Integration Tips

  • Laravel Scout: Pair with Searchable for search-as-you-type with transformed attributes.
  • API Resources: Use mutators to normalize data before serialization (e.g., toArray()).
  • Events: Trigger custom events post-mutation via registerMutatorEvents():
    protected function registerMutatorEvents(): array
    {
        return [
            'full_name' => [
                'set' => fn ($model, $old, $new) => event(new NameUpdated($model, $old, $new)),
            ],
        ];
    }
    

Gotchas and Tips

Pitfalls

  1. Circular References: Avoid recursive mutators (e.g., user.address.cityaddress.user). Fix: Use ignoreMutators() to exclude nested paths:

    protected function ignoreMutators(): array
    {
        return ['address.user'];
    }
    
  2. Performance: Mutators run on every get/set, including mass assignment. For heavy logic, cache results:

    'computed_field' => [
        'get' => fn ($value) => $value ?? Cache::remember("user_{$this->id}_computed", now()->addHours(1), fn () => computeExpensiveValue()),
    ],
    
  3. Database Sync: Mutators do not auto-sync to the database. Use save() explicitly:

    $user->full_name = 'Jane Doe'; // Only mutates in memory
    $user->save(); // Persists transformed value
    
  4. Serialization: Mutators run during toArray()/toJson(). For large datasets, disable temporarily:

    $user->disableMutators();
    $data = $user->toArray();
    $user->enableMutators();
    

Debugging

  • Log Mutations: Enable debug mode to log all mutations:

    config(['eloquence.mutable.debug' => true]);
    

    Check Laravel logs for Sofa\Eloquence\Mutable entries.

  • Override Defaults: Reset mutators dynamically:

    $user->resetMutators(['full_name']);
    

Extension Points

  1. Custom Mutator Types: Extend Sofa\Eloquence\Mutable\Mutator to add validation or side effects:

    class LoggedMutator extends Mutator
    {
        public function set($model, $value)
        {
            Log::info("Mutating {$model->getTable()}.{$this->attribute}: $value");
            return parent::set($model, $value);
        }
    }
    

    Register via getMutatorClasses():

    protected function getMutatorClasses(): array
    {
        return [LoggedMutator::class];
    }
    
  2. Dynamic Mutators: Load mutators from a config file or database:

    protected function getMutators(): array
    {
        return Cache::remember('user_mutators', now()->addHours(1), fn () => config('mutators.user'));
    }
    
  3. Testing: Mock mutators in tests:

    $user = new User();
    $user->shouldReceive('mutateAttribute')->with('full_name', 'john')->andReturn('John');
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle