reachweb/statamic-resrv
Resrv is a flexible reservation and booking addon for Statamic. It adds availability calendars, date-based pricing, and reservation management so you can define bookable items, set rates and restrictions, and accept bookings through a customizable frontend.
v6.4.0 is a low-risk, additive release: one bug fix (partner/affiliate bookings now resolve), one new optional tag parameter (statuses), and improved error handling (themed 404s + actionable validation messages). No breaking changes, no deprecations — upgrading is a composer update away.
Minimal steps:
composer update <vendor>/<package> then skim the tag class behind reservationFromUri (usually something like src/Tags/ReservationFromUriTag.php or a Tags/ directory). That single class is the whole story of this release — the URI parsing, the status filter, and the 404 behaviour all live there.resources/views/errors/404.blade.php exists (or your app's custom handler returns one) and renders sensibly when hit from a tag-driven page rather than a normal route.If you've never used the tag: start with the default behaviour (no statuses argument) and only reach for the new parameter once you have a concrete need. The defaults are deliberately conservative.
Default lookup — the safe path. Invoke the tag with just the URI. This is what a customer-facing reservation page should do 95% of the time: it returns confirmed/active bookings, now including partner and skip-payment bookings, and excludes pending, expired and cancelled.
{{-- default: confirmed-style statuses only, partner bookings included --}}
@reservationFromUri($uri)
{{-- reservation found --}}
@else
{{-- nothing matched --}}
@endreservationFromUri
(Adapt to your package's actual tag syntax — the point is that omitting statuses is the recommended default.)
Explicit status widening — opt in deliberately. The new statuses parameter is pipe-separated and validated against the package's known status list. Use it when you're building an internal view (support dashboard, admin lookup, "show me cancelled reservations") where the public-facing conservatism doesn't apply.
{{-- support tool: show cancelled and expired too --}}
@reservationFromUri($uri, statuses: 'confirmed|cancelled|expired')
Key behaviours to design around:
pending, expired and cancelled are not included by naming some other status — they only appear when explicitly listed. So statuses: 'confirmed' is narrower than or equal to the default, never wider in the "hidden" categories. Don't assume passing statuses resets to "everything."statuses from untrusted input without whitelisting first.Pattern: config-driven status sets. Rather than hardcoding pipe strings in views, centralise them:
// config/reservations.php
return [
'public_statuses' => 'confirmed',
'internal_statuses' => 'confirmed|pending|cancelled|expired',
];
Then statuses: config('reservations.internal_statuses') in the internal view, default (no argument) in the public one. This keeps the "which statuses are public?" decision in one reviewable place.
Pattern: guard the parameter at the boundary. If a status set ever comes from a request (e.g. an admin filter dropdown), map it through a fixed array before it reaches the tag:
$allowed = ['confirmed', 'pending', 'cancelled', 'expired'];
$statuses = collect($request->input('statuses', []))
->intersect($allowed)
->implode('|');
abort_if($statuses === '', 404);
Pattern: distinguish "not found" from "broken". Now that errors render your themed 404, a misconfigured tag and a genuinely missing reservation can look identical to the user. Inside the tag's else/empty branch, log at debug level with the URI so support can tell the two apart:
Log::debug('reservationFromUri: no match', ['uri' => $uri, 'statuses' => $statuses ?? 'default']);
Integration tips. Render the tag inside a normal controller-backed page rather than at the top of a layout, so the rest of the page (nav, footer, analytics) doesn't depend on the tag resolving. If your site has full-page caching, the affiliate fix means previously-cached 404s for partner URIs are now stale — purge by URI prefix after deploy. And if you have feature tests around the reservation page, add one case per status category plus one partner-booking case; that's exactly the regression surface this release touched.
statuses: 'confirmed|cancelled' expecting everything except those two. It's a whitelist. Whatever you list is what gets looked up.storage/logs/laravel.log for the actionable message the release notes mention.APP_DEBUG=true so the "clear, actionable messages" actually reach you; in production, make sure your 404 template logs the underlying reason (or that the package does) before rendering.errors/404.blade.php calls helpers, composers, or view-shared data that assume a routed request, it may itself throw — turning a clean 404 into a 500. Test the 404 path directly.statuses: 'confirmed|pending|expired|cancelled' on the customer page to "see what's there." That leaks cancelled/expired reservations to anyone with a URI. Keep the wide set on internal tooling only.Bottom line: upgrade confidently, test the affiliate path and the 404 template, and treat statuses as an internal-tooling escape hatch rather than something customer-facing pages should set.
How can I help you explore Laravel packages today?