Quick start
The whole flow, end to end — a zone, an ad in it, then serving, rendering and counting:
use RoundlyConsulting\Advertisements\DataTransferObjects\AdvertisementData;
use RoundlyConsulting\Advertisements\DataTransferObjects\ImpressionData;
use RoundlyConsulting\Advertisements\Facades\Advertisements;
use RoundlyConsulting\Advertisements\Models\Placement;
// 1. A zone to serve ads in (once — e.g. in a seeder)
Placement::query()->create([
'name' => ['en' => 'Sidebar'],
'slug' => 'sidebar',
'width' => 300,
'height' => 250,
]);
// 2. Create, place and publish an ad
$ad = Advertisements::create(AdvertisementData::fromDecimal(
name: 'Vintage road bike',
amount: '250.00', // in default_currency (EUR)
author: $user, // any Eloquent model (polymorphic author)
));
Advertisements::for($ad)->placements()->attach(['sidebar']);
Advertisements::publish($ad); // → AdvertisementPublished
// 3. Serve it: one random active ad for the zone, rendered and counted
$ad = Advertisements::random('sidebar');
if ($ad !== null) {
echo $ad->renderCreative('sidebar'); // <img> creative, or the text-ad fallback
Advertisements::for($ad)->track('sidebar')->impression(new ImpressionData(ip: request()->ip()));
}renderCreative() returns an HtmlString, so {{ $ad->renderCreative('sidebar') }} in Blade outputs it without double-escaping. Without an uploaded image it renders the text ad: name, description and price.
Every call above goes through the Advertisements facade — see The Advertisements facade for its whole surface, or DI and actions to inject the manager or call the action classes instead.
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 cryptoBy 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.