NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

The package ships no commands of its own — it plugs into Laravel’s and sluggable-for-laravel’s:

# Permanently remove advertisements whose expires_at has passed (Prunable, one by one)
php artisan model:prune --model="RoundlyConsulting\Advertisements\Models\Advertisement"

# Resolved models, tracking mode, currency, creative, geo and slug-history settings
php artisan about --only=advertisements

# Create the per-locale slug indexes for a locale added after migrating
php artisan sluggable:indexes "RoundlyConsulting\Advertisements\Models\Advertisement"

Pruning

The Advertisement model is Prunable: every ad whose expires_at has passed is prunable. Schedule it:

// routes/console.php
use Illuminate\Support\Facades\Schedule;
use RoundlyConsulting\Advertisements\Models\Advertisement;

Schedule::command('model:prune', ['--model' => [Advertisement::class]])->daily();
  • Each expired ad is force-deleted one by one, so pruning cleans up after it: its creatives (media rows and files), placement links, tracking events and slug history go with it.
  • AdvertisementDeleted fires for every pruned ad, like for any other delete.
  • A plain $ad->delete() stays a soft delete that keeps the creatives for a restore; $ad->forceDelete() removes them too.

About

php artisan about --only=advertisements reports the resolved models, tracking mode, default currency, creative and geo settings, slug history and the facade alias. The creative disk and the tracking connection and queue render as presence only (SET / DEFAULT), never by name.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.