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 Usage Limiter Laravel Package

nabilhassen/laravel-usage-limiter

Track, limit, and restrict usage for users/accounts or any model in Laravel. Define per-plan limits with reset frequencies, consume/unconsume on create/delete, check remaining allowance, generate usage reports, and auto-reset via scheduled Artisan command.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require nabilhassen/laravel-usage-limiter
    php artisan vendor:publish --provider="NabilHassen\LaravelUsageLimiter\ServiceProvider"
    php artisan migrate
    
  2. Apply Trait to Model:

    use NabilHassen\LaravelUsageLimiter\Traits\HasLimits;
    
    class User extends Authenticatable
    {
        use HasLimits;
    }
    
  3. Define a Limit:

    php artisan limit:create --name="projects" --allowed_amount=5 --plan="standard" --reset_frequency="every month"
    
  4. Attach Limit to Model:

    $user->setLimit('projects', 'standard');
    
  5. Consume Limit:

    $user->useLimit('projects', 'standard'); // Consume 1
    $user->useLimit('projects', 'standard', 3); // Consume 3
    

First Use Case

Track API Requests for Free Users:

// In your API middleware
public function handle(Request $request, Closure $next)
{
    $user = auth()->user();
    if (!$user->hasEnoughLimit('api_calls', 'free')) {
        abort(429, 'API limit exceeded');
    }
    $user->useLimit('api_calls', 'free');
    return $next($request);
}

Implementation Patterns

Core Workflows

1. Plan-Based Limit Management

// Define limits per plan
$freeLimit = Limit::create([
    'name' => 'api_calls',
    'allowed_amount' => 100,
    'plan' => 'free',
    'reset_frequency' => 'every month'
]);

$proLimit = Limit::create([
    'name' => 'api_calls',
    'allowed_amount' => 1000,
    'plan' => 'pro',
    'reset_frequency' => 'every month'
]);

// Attach to user
$user->setLimit($freeLimit); // Free plan user
$proUser->setLimit($proLimit); // Pro plan user

2. Event-Driven Limit Consumption

// In ProjectCreated event
public function handle()
{
    $user = $this->project->user;
    $user->useLimit('projects', $user->plan);
}

// In ProjectDeleted event
public function handle()
{
    $user = $this->project->user;
    $user->unuseLimit('projects', $user->plan);
}

3. Dynamic Limit Assignment

// In UserPlanUpdated event
public function handle()
{
    $user = $this->user;
    $newLimit = Limit::where('name', 'projects')->where('plan', $user->new_plan)->first();

    if ($newLimit) {
        $user->setLimit($newLimit);
    }
}

4. Batch Operations

// Bulk-create projects with limit checks
foreach ($request->projects as $projectData) {
    if ($user->hasEnoughLimit('projects', $user->plan)) {
        Project::create($projectData);
        $user->useLimit('projects', $user->plan);
    }
}

Integration Tips

With Laravel Policies

// app/Policies/ProjectPolicy.php
public function create(User $user)
{
    return $user->hasEnoughLimit('projects', $user->plan);
}

With API Rate Limiting

// In API controller
public function store(Request $request)
{
    if (!$request->user()->hasEnoughLimit('api_calls', 'free')) {
        return response()->json(['error' => 'Rate limit exceeded'], 429);
    }
    // Process request
    $request->user()->useLimit('api_calls', 'free');
    return response()->json([...]);
}

With Observers

// app/Observers/ProjectObserver.php
public function created(Project $project)
{
    $project->user->useLimit('projects', $project->user->plan);
}

public function deleted(Project $project)
{
    $project->user->unuseLimit('projects', $project->user->plan);
}

With Queues for Async Processing

// Dispatch after project creation
ProjectCreated::dispatch($project);

// In handler
public function handle(ProjectCreated $event)
{
    $event->project->user->useLimit('projects', $event->project->user->plan);
}

Gotchas and Tips

Pitfalls

  1. Cache Invalidation:

    • After creating/updating/deleting limits, always clear the cache:
      php artisan limit:cache-reset
      
    • Or programmatically:
      app(\NabilHassen\LaravelUsageLimiter\LimitManager::class)->flushCache();
      
  2. Reset Frequency Precision:

    • For "every second" frequency, requires Laravel 10+ (throws error in older versions).
    • Test reset logic thoroughly for edge cases (e.g., DST changes, leap seconds).
  3. Negative Limit Exceptions:

    • unuseLimit() throws an exception if it would set usage below 0. Handle gracefully:
      try {
          $user->unuseLimit('projects', $user->plan, 2);
      } catch (\Exception $e) {
          // Log or notify admin
      }
      
  4. Plan Mismatches:

    • Ensure users are always assigned the correct plan’s limit. Use middleware to validate:
      public function handle($request, Closure $next)
      {
          if ($request->user()->plan !== $request->user()->getLimitPlan('projects')) {
              $request->user()->setLimit('projects', $request->user()->plan);
          }
          return $next($request);
      }
      
  5. Concurrent Requests:

    • Limits are not atomic by default. For high-traffic APIs, use database transactions:
      DB::transaction(function () use ($user) {
          $user->useLimit('api_calls', 'free');
      });
      

Debugging Tips

  1. Check Limit Usage:

    $user->limitUsageReport(); // Full report
    $user->usedLimit('projects', 'free'); // Current usage
    $user->remainingLimit('projects', 'free'); // Remaining
    
  2. Manual Reset:

    php artisan limit:reset --model=User --limit=projects --plan=free
    

    Or programmatically:

    $user->resetLimit('projects', 'free');
    
  3. Cache Inspection:

    • View cached limits:
      php artisan cache:table
      
    • Clear specific cache:
      Cache::forget('limits');
      
  4. Artisan Command Debugging:

    • List all limits:
      php artisan limit:list
      
    • Delete a limit:
      php artisan limit:delete --name=projects --plan=free
      

Extension Points

  1. Custom Limit Model:

    • Extend the Limit model:
      class CustomLimit extends \NabilHassen\LaravelUsageLimiter\Models\Limit
      {
          protected $table = 'custom_limits';
      }
      
    • Update config:
      'model' => \App\Models\CustomLimit::class,
      
  2. Custom Relationship Name:

    • Change the relationship key in config/limit.php:
      'relationship' => 'usage_restrictions',
      
    • Then use:
      $user->usage_restrictions; // Instead of $user->limits
      
  3. Custom Cache Store:

    • Configure in config/limit.php:
      'cache_store' => 'redis',
      
    • Requires Redis driver setup.
  4. Custom Reset Logic:

    • Override the resetLimit() method in your model:
      public function resetLimit($limit, $plan = null)
      {
          // Custom logic (e.g., log reset, notify user)
          parent::resetLimit($limit, $plan);
      }
      
  5. Event Hooks:

    • Listen for limit events (e.g., LimitConsumed):
      // In EventServiceProvider
      protected $listen = [
          \NabilHassen\LaravelUsageLimiter\Events\LimitConsumed::class => [
              \App\Listeners\LogLimitUsage::class,
          ],
      ];
      

Performance Optimization

  1. Eager Load Limits:

    $users = User::with(['limits' => function($query) {
        $query->where('name', 'projects');
    }])->get();
    
  2. Batch Limit Checks:

    $users = User::whereHas('limits', function($query) {
        $query->where('name', 'projects')
              ->
    
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.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony