Preparing a model
Add the GetsOnboarded trait to any Eloquent model that should expose its onboarding flow. The trait asks the OnboardingManager for a copy of the model’s flow bound to the model, so every step’s rule receives that model — and Onboarding::fake() sees every trait call:
use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\Onboarding\Traits\GetsOnboarded;
class User extends Model
{
use GetsOnboarded;
}Reading a model’s flow
$user = User::first();
$flow = $user->onboarding(); // the resolver's flow, else defaultOnboardingKey()'s, bound to $user
$flow = $user->onboarding('admin'); // a specific flow by key
$flow = $user->onboarding('missing', new Flow()); // fallback when the key is unknownonboarding() returns null when no matching flow is registered and no fallback is given — hence the null-safe ?-> throughout these docs.
Choosing the default key
By default the model uses the default flow key. Override defaultOnboardingKey() to choose a different one — for example, from a column on the model. When a resolver is registered, its choice comes first and defaultOnboardingKey() is the fallback for a null or unknown answer:
public function defaultOnboardingKey(): string
{
return $this->onboarding_flow ?? 'default';
}Null-safe readers
The trait adds one-liners so you don’t have to chain through onboarding()?->… yourself. Each accepts an optional flow key; without one it reads the same flow as $user->onboarding() — the resolver’s choice, else defaultOnboardingKey():
$user->hasCompletedOnboarding(); // bool — false when no flow is registered
$user->isOnboarding(); // bool — in progress
$user->onboardingProgress(); // float — 0.0 when no flow is registered
$user->nextOnboardingStep(); // ?Step
$user->dismissOnboardingStep('add-bio'); // dismiss an optional, dismissible step (needs a store)
$user->hasCompletedOnboarding('admin'); // target a specific flow key| Method | Returns | Purpose |
|---|---|---|
onboarding(?string $key = null, ?Flow $default = null) | ?Flow | A copy of the flow under the key — without one, the resolver’s choice, else defaultOnboardingKey()’s — bound to the model. |
resolvedOnboarding() | ?Flow | Onboarding::for($model) — the resolver’s flow, else the default flow. |
defaultOnboardingKey() | string | The model’s fallback flow key when the resolver answers null or an unknown key — OnboardingManager::$default (default) unless you override it. |
hasCompletedOnboarding(?string $key = null) | bool | Flow complete; false when no flow is registered. |
isOnboarding(?string $key = null) | bool | Flow in progress; false when no flow is registered. |
onboardingProgress(?string $key = null) | float | percentageCompleted(); 0.0 when no flow is registered. |
nextOnboardingStep(?string $key = null) | ?Step | The current step to resume on. |
dismissOnboardingStep(string $step, ?string $key = null) | void | Dismiss an optional, dismissible step; a no-op without a store or for an unknown or non-dismissible step. |
In a Blade view
@if ($user->isOnboarding())
<div class="onboarding-banner">
<progress value="{{ $user->onboardingProgress() }}" max="100"></progress>
<p>Next: {{ $user->nextOnboardingStep()?->resolvedTitle() }}</p>
</div>
@endifShow 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.