Skip to content

Commit 54de04f

Browse files
committed
Refactor for v2
1 parent 045cad6 commit 54de04f

14 files changed

+217
-253
lines changed

README.md

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ composer require spatie/laravel-onboard
2626

2727
## Usage
2828

29-
Add the `Spatie\Onboard\GetsOnboarded` trait to your app's `User` model.
29+
Add the `Spatie\Onboard\Concerns\GetsOnboarded` trait and `Spatie\Onboard\Concerns\Onboardable` interface to any model or class in your app, for example the `User` model:
3030

3131
```php
32-
class User extends Model
32+
class User extends Model implements \Spatie\Onboard\Concerns\Onboardable
3333
{
34-
use \Spatie\Onboard\GetsOnboarded;
34+
use \Spatie\Onboard\Concerns\GetsOnboarded;
3535
...
3636
```
3737

@@ -41,25 +41,30 @@ Configure your steps in your `App\Providers\AppServiceProvider.php`
4141

4242
```php
4343
use App\User;
44-
use Spatie\Onboard\OnboardFacade;
44+
use Spatie\Onboard\Facades\Onboard;
4545

4646
class AppServiceProvider extends ServiceProvider
4747
{
4848
// ...
4949

5050
public function boot()
5151
{
52-
OnboardFacade::addStep('Complete Profile')
52+
Onboard::addStep('Complete Profile')
5353
->link('/profile')
5454
->cta('Complete')
55-
->completeIf(function (User $user) {
55+
/**
56+
* The completeIf will pass the class that you've added the
57+
* interface & trait to. You can use Laravel's dependency
58+
* injection here to inject anything else as well.
59+
*/
60+
->completeIf(function (User $model) {
5661
return $user->profile->isComplete();
5762
});
5863

59-
OnboardFacade::addStep('Create Your First Post')
64+
Onboard::addStep('Create Your First Post')
6065
->link('/post/create')
6166
->cta('Create Post')
62-
->completeIf(function (User $user) {
67+
->completeIf(function (User $model) {
6368
return $user->posts->count() > 0;
6469
});
6570
```
@@ -68,10 +73,9 @@ class AppServiceProvider extends ServiceProvider
6873

6974
Now you can access these steps along with their state wherever you like. Here is an example blade template:
7075

71-
```php
76+
```blade
7277
@if (auth()->user()->onboarding()->inProgress())
7378
<div>
74-
7579
@foreach (auth()->user()->onboarding()->steps as $step)
7680
<span>
7781
@if($step->complete())
@@ -94,10 +98,13 @@ Now you can access these steps along with their state wherever you like. Here is
9498
Check out all the available features below:
9599

96100
```php
101+
/** @var \Spatie\Onboard\OnboardingManager $onboarding **/
97102
$onboarding = Auth::user()->onboarding();
98103

99104
$onboarding->inProgress();
100105

106+
$onboarding->percentageCompleted();
107+
101108
$onboarding->finished();
102109

103110
$onboarding->steps()->each(function($step) {
@@ -113,7 +120,7 @@ Definining custom attributes and accessing them:
113120

114121
```php
115122
// Defining the attributes
116-
OnboardFacade::addStep('Step w/ custom attributes')
123+
Onboard::addStep('Step w/ custom attributes')
117124
->attributes([
118125
'name' => 'Waldo',
119126
'shirt_color' => 'Red & White',
@@ -126,7 +133,7 @@ $step->shirt_color;
126133

127134
### Example middleware
128135

129-
If you want to ensure that your user is redirected to the next unfinished onboarding step, whenever they access your web application, you can use the following middleware as a starting point:
136+
If you want to ensure that your User is redirected to the next unfinished onboarding step, whenever they access your web application, you can use the following middleware as a starting point:
130137

131138
```php
132139
<?php

UPGRADING.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## Upgrading
2+
### Upgrading from v1 to v2
3+
4+
* Support for PHP 7.4 has been dropped
5+
* Support for Laravel 7 and 8 has been dropped
6+
* The `\Spatie\Onboard\OnboardFacade` has been moved to `\Spatie\Onboard\Facades\Onboard`
7+
* The `\Spatie\Onboard\GetsOnboarded` trait has been moved to `\Spatie\Onboard\Concerns\GetsOnboarded`
8+
* You should add the new `\Spatie\Onboard\Concerns\Onboardable` interface to your `User` model
9+
* The `$user` parameter in the `completeIf` callbacks has been renamed to `$model`

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
}
1717
],
1818
"require": {
19-
"php": "^7.4|^8.0|^8.1",
19+
"php": "^8.0|^8.1",
20+
"illuminate/contracts": "^7.0|^8.0|^9.0",
2021
"spatie/laravel-package-tools": "^1.9.2",
21-
"illuminate/contracts": "^7.0|^8.0|^9.0"
22+
"spatie/once": "^3.1"
2223
},
2324
"require-dev": {
2425
"friendsofphp/php-cs-fixer": "^3.8",

src/Concerns/GetsOnboarded.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Spatie\Onboard\Concerns;
4+
5+
use Illuminate\Support\Facades\App;
6+
use Spatie\Onboard\OnboardingManager;
7+
8+
trait GetsOnboarded
9+
{
10+
public function onboarding(): OnboardingManager
11+
{
12+
return App::make(OnboardingManager::class, ['model' => $this]);
13+
}
14+
}

src/Concerns/Onboardable.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Spatie\Onboard\Concerns;
4+
5+
use Spatie\Onboard\OnboardingManager;
6+
7+
interface Onboardable
8+
{
9+
public function onboarding(): OnboardingManager;
10+
}

src/Facades/Onboard.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Spatie\Onboard\Facades;
4+
5+
use Illuminate\Support\Collection;
6+
use Illuminate\Support\Facades\Facade;
7+
use Spatie\Onboard\Concerns\Onboardable;
8+
use Spatie\Onboard\OnboardingStep;
9+
use Spatie\Onboard\OnboardingSteps;
10+
11+
/**
12+
* @method OnboardingStep addStep(string $title)
13+
* @method Collection<OnboardingStep> steps(Onboardable $model)
14+
*/
15+
class Onboard extends Facade
16+
{
17+
protected static function getFacadeAccessor(): string
18+
{
19+
return OnboardingSteps::class;
20+
}
21+
}

src/GetsOnboarded.php

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/OnboardFacade.php

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/OnboardServiceProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ public function configurePackage(Package $package): void
1212
$package
1313
->name('laravel-onboard');
1414

15-
$this->app->singleton(OnboardingSteps::class);
15+
$this->app->scoped(OnboardingSteps::class);
1616
}
1717
}

src/OnboardingManager.php

Lines changed: 23 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,75 +2,47 @@
22

33
namespace Spatie\Onboard;
44

5-
/**
6-
* The gateway into the package. This class exposes the overall
7-
* state of the onboarding instance. It will typically be
8-
* accessed like so: $user->onboarding()
9-
*/
5+
use Illuminate\Support\Collection;
6+
107
class OnboardingManager
118
{
12-
/**
13-
* All defined onboarding steps.
14-
*
15-
* @var \Illuminate\Support\Collection
16-
*/
17-
public $steps;
9+
/** @var Collection<OnboardingStep> */
10+
public Collection $steps;
1811

19-
/**
20-
* Create the Onboarding Manager (should always be a singleton).
21-
*
22-
* @param mixed $user The parent app's user model.
23-
* @param \Spatie\Onboard\OnboardingSteps $onboardingSteps
24-
*/
25-
public function __construct($user, OnboardingSteps $onboardingSteps)
12+
public function __construct($model, OnboardingSteps $onboardingSteps)
2613
{
27-
$this->steps = $onboardingSteps->steps($user);
14+
$this->steps = $onboardingSteps->steps($model);
2815
}
2916

30-
/**
31-
* An accessor for the $steps property
32-
*
33-
* @return \Illuminate\Support\Collection
34-
*/
35-
public function steps()
17+
/** @return Collection<OnboardingStep> */
18+
public function steps(): Collection
3619
{
3720
return $this->steps;
3821
}
3922

40-
/**
41-
* Determine if the users's onboarding is still in progress.
42-
*
43-
* @return bool
44-
*/
45-
public function inProgress()
23+
public function inProgress(): bool
4624
{
4725
return ! $this->finished();
4826
}
4927

50-
/**
51-
* Determine if the users's onboarding is complete.
52-
*
53-
* @return bool
54-
*/
55-
public function finished()
28+
public function finished(): bool
5629
{
57-
return collect($this->steps)->filter(function ($step) {
58-
// Leave only incomplete steps.
59-
return $step->incomplete();
60-
})
61-
// Report onboarding is finished if no incomplete steps remain.
30+
return $this->steps
31+
->filter(fn (OnboardingStep $step) => $step->incomplete())
6232
->isEmpty();
6333
}
6434

65-
/**
66-
* Get the next unfinished onboarding step, or null if already all steps are completed.
67-
*
68-
* @return null|OnboardingStep
69-
*/
70-
public function nextUnfinishedStep()
35+
public function nextUnfinishedStep(): ?OnboardingStep
7136
{
72-
return collect($this->steps)->first(function ($step) {
73-
return $step->incomplete();
74-
});
37+
return $this->steps->first(fn (OnboardingStep $step) => $step->incomplete());
38+
}
39+
40+
public function percentageCompleted(): float
41+
{
42+
$totalCompleteSteps = $this->steps
43+
->filter(fn (OnboardingStep $step) => $step->complete())
44+
->count();
45+
46+
return $totalCompleteSteps / $this->steps->count() * 100;
7547
}
7648
}

0 commit comments

Comments
 (0)