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 Model Expires Laravel Package

mvdnbrk/laravel-model-expires

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require mvdnbrk/laravel-model-expires
    

    Publish the config (if needed) with:

    php artisan vendor:publish --provider="Mvdnbrk\EloquentExpirable\EloquentExpirableServiceProvider"
    
  2. Add the trait to your Eloquent model:

    use Mvdnbrk\EloquentExpirable\Expirable;
    
    class Subscription extends Model
    {
        use Expirable;
    }
    
  3. Add the expires_at column to your migration:

    Schema::create('subscriptions', function (Blueprint $table) {
        $table->expires(); // Adds `expires_at` column with nullable timestamp
    });
    
  4. Run migrations and start using:

    $subscription = Subscription::create(['expires_at' => now()->addDays(30)]);
    

First Use Case

Check if a model is expired:

if ($subscription->isExpired()) {
    // Handle expiration logic
}

Force-expire a model:

$subscription->expire();

Implementation Patterns

Core Workflows

  1. Setting Expiration Dates:

    • Use expiresAt() to set expiration dynamically:
      $subscription->expiresAt(now()->addMonth());
      $subscription->save();
      
    • Use expire() to set expiration to now:
      $subscription->expire();
      
  2. Querying Expired Models:

    • Scope expired models:
      $expired = Subscription::expired()->get();
      
    • Scope non-expired models:
      $active = Subscription::notExpired()->get();
      
  3. Soft Deletion Integration:

    • Combine with SoftDeletes for auto-purging:
      use Illuminate\Database\Eloquent\SoftDeletes;
      
      class Subscription extends Model
      {
          use Expirable, SoftDeletes;
      
          protected $dates = ['expires_at', 'deleted_at'];
      }
      
    • Add a model observer to auto-delete expired soft-deleted records:
      Subscription::observe(SubscriptionExpiredObserver::class);
      
  4. Custom Expiration Logic:

    • Override isExpired() for business rules:
      public function isExpired(): bool
      {
          return parent::isExpired() || $this->trial_ended_at < now();
      }
      

Integration Tips

  • API Responses: Use the expires_at field in API responses for client-side expiration tracking.
  • Cron Jobs: Schedule a job to clean up expired records:
    Subscription::where('expires_at', '<', now())->delete();
    
  • Validation: Add validation rules for expires_at:
    $rules = ['expires_at' => 'required|date|after:today'];
    

Gotchas and Tips

Pitfalls

  1. Column Name Conflicts:

    • If expires_at conflicts with existing columns, override the column name:
      class Subscription extends Model
      {
          use Expirable;
      
          const EXPIRES_AT = 'subscription_expires_at';
      }
      
    • Or configure globally in config/eloquent-expirable.php:
      'column' => 'custom_expires_at',
      
  2. Timezone Issues:

    • Ensure expires_at uses the correct timezone. Set the model's $dateFormat or use Carbon’s setTimezone():
      $subscription->expiresAt(now()->timezone('UTC')->addDays(30));
      
  3. Soft Deletes + Expirable:

    • If using SoftDeletes, ensure $dates includes both expires_at and deleted_at to avoid serialization issues.
  4. Database Indexes:

    • For large tables, add an index to expires_at for faster queries:
      Schema::table('subscriptions', function (Blueprint $table) {
          $table->index('expires_at');
      });
      

Debugging

  • Check Expiration Logic:
    • Log the raw expires_at value to debug timezone/date issues:
      \Log::debug('Expires at:', [$this->expires_at, $this->expires_at->toDateTimeString()]);
      
  • Verify Trait Loading:
    • Ensure the trait is loaded correctly by checking for the expires_at column in the database and the isExpired() method in the model.

Extension Points

  1. Custom Scopes:

    • Extend the package’s scopes (e.g., expiredBetween):
      public function scopeExpiredBetween($query, $from, $to)
      {
          return $query->whereBetween('expires_at', [$from, $to]);
      }
      
  2. Event Triggers:

    • Listen for expiration events (e.g., ModelExpired):
      use Mvdnbrk\EloquentExpirable\Events\ModelExpired;
      
      ModelExpired::listen(function ($model) {
          // Send notification, log, etc.
      });
      
  3. Custom Expiration Rules:

    • Override shouldExpire() for dynamic expiration logic:
      public function shouldExpire(): bool
      {
          return $this->trial_active && parent::shouldExpire();
      }
      
  4. Batch Processing:

    • Use chunking for bulk expiration checks:
      Subscription::chunk(100, function ($subscriptions) {
          foreach ($subscriptions as $subscription) {
              if ($subscription->isExpired()) {
                  $subscription->delete(); // or softDelete()
              }
          }
      });
      
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.
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
atriumphp/atrium