Skip to content

Commit c0324f6

Browse files
committed
Extend active state funcionality to allow handling of enum values and use general purpose methods, add helper method for different coding styles
1 parent fac8a2a commit c0324f6

File tree

4 files changed

+164
-4
lines changed

4 files changed

+164
-4
lines changed

composer.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"keywords": [
55
"laravel",
66
"laravel-stateful-resources",
7-
"api",
7+
"api",
88
"resources"
99
],
1010
"homepage": "https://github.com/farbcodegmbh/laravel-stateful-resources",
@@ -48,7 +48,10 @@
4848
"Workbench\\App\\": "workbench/app/",
4949
"Workbench\\Database\\Factories\\": "workbench/database/factories/",
5050
"Workbench\\Database\\Seeders\\": "workbench/database/seeders/"
51-
}
51+
},
52+
"files": [
53+
"src/helpers.php"
54+
]
5255
},
5356
"scripts": {
5457
"post-autoload-dump": [

src/ActiveState.php

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22

33
namespace Farbcode\StatefulResources;
44

5+
use Farbcode\StatefulResources\Concerns\ResolvesState;
6+
use Farbcode\StatefulResources\Contracts\ResourceState;
7+
58
/**
69
* ActiveState manages which state is currently active for resources.
710
*/
811
class ActiveState
912
{
13+
use ResolvesState;
14+
1015
private ?string $sharedState;
1116

1217
private array $resourceStates = [];
@@ -19,8 +24,9 @@ public function __construct()
1924
/**
2025
* Set the shared state for all resources.
2126
*/
22-
public function setShared(string $state): void
27+
public function setShared(string|ResourceState $state): void
2328
{
29+
$state = $this->resolveState($state);
2430
$this->sharedState = $state;
2531
}
2632

@@ -32,11 +38,21 @@ public function getShared(): string
3238
return $this->sharedState ?? app(StateRegistry::class)->getDefaultState();
3339
}
3440

41+
/**
42+
* Check if a specific resource class has a state set.
43+
*/
44+
public function matchesShared(string|ResourceState $state): bool
45+
{
46+
$state = $this->resolveState($state);
47+
return $this->getShared() === $state;
48+
}
49+
3550
/**
3651
* Set the state for a specific resource class.
3752
*/
38-
public function setForResource(string $resourceClass, string $state): void
53+
public function setForResource(string $resourceClass, string|ResourceState $state): void
3954
{
55+
$state = $this->resolveState($state);
4056
$this->resourceStates[$resourceClass] = $state;
4157
}
4258

@@ -47,4 +63,64 @@ public function getForResource(string $resourceClass): string
4763
{
4864
return $this->resourceStates[$resourceClass] ?? app(StateRegistry::class)->getDefaultState();
4965
}
66+
67+
/**
68+
* Check if the current state matches the resource's state.
69+
*/
70+
public function matchesResource(string $resourceClass, string|ResourceState $state): bool
71+
{
72+
$state = $this->resolveState($state);
73+
return $this->getForResource($resourceClass) === $state;
74+
}
75+
76+
/**
77+
* Get the current state for a resource.
78+
* If no resource class is provided, returns the shared state.
79+
*
80+
* @param string|null $resourceClass
81+
*/
82+
public function get($resourceClass = null): string
83+
{
84+
if ($resourceClass === null) {
85+
return $this->getShared();
86+
}
87+
88+
return $this->getForResource($resourceClass);
89+
}
90+
91+
/**
92+
* Set the current state for a resource.
93+
* If no resource class is provided, sets the shared state.
94+
*
95+
* @param string|ResourceState $state
96+
* @param string|null $resourceClass
97+
*/
98+
public function set($state, $resourceClass = null): void
99+
{
100+
$state = $this->resolveState($state);
101+
102+
if ($resourceClass === null) {
103+
$this->setShared($state);
104+
} else {
105+
$this->setForResource($resourceClass, $state);
106+
}
107+
}
108+
109+
/**
110+
* Check if the current state matches the given state for a resource.
111+
* If no resource class is provided, checks against the shared state.
112+
*
113+
* @param string|ResourceState $state
114+
* @param string|null $resourceClass
115+
*/
116+
public function matches($state, $resourceClass = null): bool
117+
{
118+
$state = $this->resolveState($state);
119+
120+
if ($resourceClass === null) {
121+
return $this->matchesShared($state);
122+
}
123+
124+
return $this->matchesResource($resourceClass, $state);
125+
}
50126
}

src/helpers.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
use Farbcode\StatefulResources\ActiveState;
4+
5+
if (! function_exists('resourceState')) {
6+
function resourceState(): ActiveState
7+
{
8+
return app(ActiveState::class);
9+
}
10+
}

tests/Feature/SharedStateTest.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
use Farbcode\StatefulResources\ActiveState as ActiveStateService;
4+
use Farbcode\StatefulResources\Enums\State;
45
use Farbcode\StatefulResources\Facades\ActiveState;
56
use Workbench\App\Http\Resources\CatResource;
67
use Workbench\App\Models\Cat;
@@ -74,6 +75,76 @@
7475
]);
7576
});
7677

78+
it('can set the shared state through the resourceState helper function', function () {
79+
$cat = Cat::factory()->new()->createOne();
80+
$dogs = Dog::factory()->count(3)->create();
81+
82+
$cat->enemies()->attach($dogs->pluck('id'));
83+
84+
resourceState()->setShared(State::Table);
85+
86+
$resource = CatResource::make($cat)->toJson();
87+
88+
expect(resourceState()->matchesShared(State::Table))->toBeTrue();
89+
90+
expect($resource)->toBeJson();
91+
92+
expect($resource)->json()->toEqual([
93+
'id' => $cat->id,
94+
'name' => $cat->name,
95+
'breed' => $cat->breed,
96+
'enemies' => [
97+
[
98+
'id' => $dogs[0]->id,
99+
'name' => $dogs[0]->name,
100+
],
101+
[
102+
'id' => $dogs[1]->id,
103+
'name' => $dogs[1]->name,
104+
],
105+
[
106+
'id' => $dogs[2]->id,
107+
'name' => $dogs[2]->name,
108+
],
109+
],
110+
]);
111+
});
112+
113+
it('can set the shared state through the resourceState helper function and the genereal purpose methods', function () {
114+
$cat = Cat::factory()->new()->createOne();
115+
$dogs = Dog::factory()->count(3)->create();
116+
117+
$cat->enemies()->attach($dogs->pluck('id'));
118+
119+
resourceState()->set(State::Table);
120+
121+
$resource = CatResource::make($cat)->toJson();
122+
123+
expect(resourceState()->matches(State::Table))->toBeTrue();
124+
125+
expect($resource)->toBeJson();
126+
127+
expect($resource)->json()->toEqual([
128+
'id' => $cat->id,
129+
'name' => $cat->name,
130+
'breed' => $cat->breed,
131+
'enemies' => [
132+
[
133+
'id' => $dogs[0]->id,
134+
'name' => $dogs[0]->name,
135+
],
136+
[
137+
'id' => $dogs[1]->id,
138+
'name' => $dogs[1]->name,
139+
],
140+
[
141+
'id' => $dogs[2]->id,
142+
'name' => $dogs[2]->name,
143+
],
144+
],
145+
]);
146+
});
147+
77148
it('works correctly when shared state is disabled', function () {
78149
config()->set('stateful-resources.shared_state', false);
79150

0 commit comments

Comments
 (0)