Routing and tenancy
Published sites use /s/{organizationSlug}/{path?} when local paths are enabled and/or {organizationSlug}.{central_domain}/{path?} when configured. Preview uses signed /preview/{organizationSlug}/{path?}. SiteUrlGenerator prefers subdomain for published links when configured and signs preview links for preview_link_ttl minutes.
Tenant context API
set(Organization $organization): void;
get(): Organization;
id(): string;
check(): bool;
bypass(): void;
isBypassed(): bool;
run(Organization $organization, Closure $callback): mixed;
runBypassed(Closure $callback): mixed;
clear(): void;
BelongsToOrganization installs the global scope, fills ownership, rejects creation without context or with another tenant, and forbids changing ownership. Use run() in controlled tests/jobs; bypass is central infrastructure only.
Publication and resolution
Published CMS queries require status = published. Events additionally requires published status, non-null published_at, and published_at <= now(). Signed preview includes drafts.
Fundraising public project resolution includes published and completed records with an effective publication timestamp; only published accepts a new donation. Organization management lives under /plugins/fundraising/manage while /plugins/fundraising remains the platform settings page. Donation proof paths never pass through site routing: authenticated policy-protected dashboard downloads stream them from the private disk.
The normalized non-empty path is matched against effective plugin pages before an exact CMS slug. Dynamic {parameter} captures one segment and is URL-decoded. Dynamic pages cannot enter navigation. Enablement matches plugin patterns against existing CMS slugs and blocks collisions.
Middleware
- Charity UI:
web,auth,organization.route,organization.member. - Plugin dashboards: Charity guards plus
plugin.available:{slug}whenrequiresEnabledis true, orplugin.available:{slug},installedwhen false. Definition validation enforces this pairing. - Plugin Super Admin pages:
web,auth,super.admin,plugin.available:{slug},installed; never organization middleware. - Public plugin actions:
web,organization.route,plugin.available:{slug}, throttling. - Admin:
web,auth,super.admin.
Enabled availability checks installed, active, and effective tenant state. Installed mode checks global installed/active only, allowing a package management route while its tenant assignment is disabled.
EnsureSuperAdmin bypasses tenant scope for the platform request. Super Admin plugin pages therefore query across organizations; they must identify the owning organization and remain explicitly protected and bounded.