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

Laravel Lockable Laravel Package

lowerrocklabs/laravel-lockable

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require lowerrocklabs/laravel-lockable
    

    Publish the migration (if needed):

    php artisan vendor:publish --provider="LowerRockLabs\Lockable\LockableServiceProvider" --tag="migrations"
    php artisan migrate
    
  2. Apply the Trait: Use the Lockable trait in your Eloquent model:

    use LowerRockLabs\Lockable\Traits\Lockable;
    
    class User extends Model
    {
        use Lockable;
    }
    
  3. First Use Case: Lock/unlock a model instance:

    $user = User::find(1);
    $user->lock(); // Locks the user
    $user->unlock(); // Unlocks the user
    
  4. Check Lock Status:

    if ($user->isLocked()) {
        // Handle locked state
    }
    

Implementation Patterns

Core Workflows

  1. Locking Logic Integration:

    • Use lock()/unlock() in business logic (e.g., admin actions, sensitive operations).
    • Example: Lock a user before editing their profile:
      $user->lock();
      try {
          $user->update($request->all());
      } finally {
          $user->unlock();
      }
      
  2. Permission Integration:

    • Combine with Laravel’s gates/policies:
      public function update(UpdateUserRequest $request, User $user)
      {
          if ($user->isLocked()) {
              abort(403, 'User is locked');
          }
          // Proceed with update
      }
      
  3. Query Scoping:

    • Filter locked/unlocked records:
      $lockedUsers = User::locked()->get();
      $unlockedUsers = User::unlocked()->get();
      
  4. Soft Locking (Optional):

    • Extend the trait to add soft-locking (e.g., is_soft_locked column) via a custom trait:
      trait SoftLockable {
          public function softLock() { /* ... */ }
      }
      

Advanced Patterns

  1. Event-Based Locking:

    • Trigger events on lock/unlock:
      $user->lock(); // Dispatches `Locking` event
      $user->unlock(); // Dispatches `Unlocking` event
      
    • Listen to events in EventServiceProvider:
      protected $listen = [
          'LowerRockLabs\Lockable\Events\Locking' => [
              'App\Listeners\LogLockAction',
          ],
      ];
      
  2. Lock Expiry:

    • Add a locked_at column and auto-unlock logic:
      // In a queue job or scheduled task
      User::where('locked_at', '<', now()->subHours(1))
          ->update(['locked_at' => null]);
      
  3. Multi-Tenant Locking:

    • Scope locks to tenants:
      $tenantUser = Tenant::find(1)->users()->locked()->get();
      

Gotchas and Tips

Pitfalls

  1. Race Conditions:

    • Locking/unlocking in parallel requests may cause inconsistencies. Use database transactions:
      DB::transaction(function () use ($user) {
          $user->lock();
          // Critical operations
          $user->unlock();
      });
      
  2. Missing Migration:

    • If the locked_at column is missing, the trait will throw ColumnNotFoundException. Run migrations first.
  3. Caching Issues:

    • Lock status may not reflect in cached queries. Clear relevant caches or use fresh():
      $user = User::find(1)->fresh(); // Ensures latest lock status
      
  4. Over-Permissive Locking:

    • Avoid locking models globally (e.g., User::all()->lock()). Use targeted locking.

Debugging Tips

  1. Check Lock Status:

    • Verify the locked_at column in the database:
      SELECT locked_at FROM users WHERE id = 1;
      
  2. Event Debugging:

    • Listen to events temporarily for debugging:
      event(new \LowerRockLabs\Lockable\Events\Locking(User::find(1)));
      
  3. Query Logging:

    • Enable Laravel’s query log to inspect scope queries:
      \DB::enableQueryLog();
      User::locked()->get();
      \DB::getQueryLog();
      

Extension Points

  1. Custom Lock Logic:

    • Override lock()/unlock() in your model:
      public function lock()
      {
          $this->locked_at = now()->addHours(2); // Custom expiry
          $this->save();
      }
      
  2. Additional Lock Types:

    • Add metadata (e.g., lock_reason):
      protected $lockMetadata = ['reason' => null];
      
      public function lock(string $reason = null)
      {
          $this->lockMetadata['reason'] = $reason;
          $this->locked_at = now();
          $this->save();
      }
      
  3. API Responses:

    • Include lock status in API responses:
      return UserResource::make($user)->additional([
          'is_locked' => $user->isLocked(),
      ]);
      
  4. Livewire Integration:

    • React to lock status in Livewire components:
      public function updatedLockStatus()
      {
          $this->emit('lockStatusChanged', $this->model->isLocked());
      }
      
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor