Skip to content

Commit e6ff1e9

Browse files
authored
Standalone actions. (#259)
* Standalone actions. * Apply fixes from StyleCI (#258) * Docs
1 parent da83adc commit e6ff1e9

File tree

6 files changed

+128
-7
lines changed

6 files changed

+128
-7
lines changed

docs/docs/3.0/actions/actions.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,44 @@ public function handle(ActionRequest $request, Post $post): JsonResponse
236236
//
237237
}
238238
```
239+
240+
## Standalone actions
241+
242+
Sometimes you don't need to have an action with models. Let's say for example the authenticated user wants to disable his account. For this we have `standalone` actions:
243+
244+
245+
```php
246+
// UserRepository
247+
248+
public function actions(RestifyRequest $request)
249+
{
250+
return [
251+
DisableProfileAction::new()->standalone(),
252+
];
253+
}
254+
```
255+
256+
Just mark it as standalone with `->standalone` or override the property directly into the action:
257+
258+
```php
259+
class DisableProfileAction extends Action
260+
{
261+
public $standalone = true;
262+
263+
//...
264+
}
265+
```
266+
267+
268+
## URI Key
269+
270+
Usually the URL for the action is make based on the action name. You can use your own URI key if you want:
271+
272+
```php
273+
class DisableProfileAction extends Action
274+
{
275+
public static $uriKey = 'disable_profile';
276+
277+
//...
278+
}
279+
```

src/Actions/Action.php

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,34 @@
1414
use Closure;
1515
use Exception;
1616
use Illuminate\Database\Eloquent\Model;
17-
use Illuminate\Http\JsonResponse;
1817
use Illuminate\Http\Request;
19-
use Illuminate\Support\Collection;
2018
use Illuminate\Support\Str;
2119
use JsonSerializable;
2220

2321
abstract class Action extends RestController implements JsonSerializable
2422
{
2523
use AuthorizedToSee, ProxiesCanSeeToGate, Make, Visibility;
2624

25+
/**
26+
* Number of models into a chunk when action for 'all'.
27+
*
28+
* @var int
29+
*/
2730
public static int $chunkCount = 200;
2831

32+
/**
33+
* Indicated if this action don't require any models.
34+
*
35+
* @var bool
36+
*/
37+
public bool $standalone = false;
38+
39+
/**
40+
* Default uri key for the action.
41+
* @var string
42+
*/
43+
public static $uriKey;
44+
2945
public static function indexQuery(RestifyRequest $request, $query)
3046
{
3147
return $query;
@@ -50,7 +66,7 @@ public function name()
5066
*/
5167
public function uriKey()
5268
{
53-
return Str::slug($this->name(), '-', null);
69+
return static::$uriKey ?? Str::slug($this->name(), '-', null);
5470
}
5571

5672
/**
@@ -88,6 +104,29 @@ public function payload(): array
88104
return [];
89105
}
90106

107+
/**
108+
* Make current action being standalone. No model query will be performed.
109+
*
110+
* @param bool $standalone
111+
* @return self
112+
*/
113+
public function standalone(bool $standalone = true): self
114+
{
115+
$this->standalone = $standalone;
116+
117+
return $this;
118+
}
119+
120+
/**
121+
* Check if the action is standalone.
122+
*
123+
* @return bool
124+
*/
125+
public function isStandalone(): bool
126+
{
127+
return $this->standalone;
128+
}
129+
91130
// abstract public function handle(ActionRequest $request, Collection $models): JsonResponse;
92131

93132
public function handleRequest(ActionRequest $request)
@@ -96,6 +135,10 @@ public function handleRequest(ActionRequest $request)
96135
throw new Exception('Missing handle method from the action.');
97136
}
98137

138+
if ($this->isStandalone()) {
139+
return Transaction::run(fn () => $this->handle($request));
140+
}
141+
99142
$response = null;
100143

101144
if (! $request->isForRepositoryRequest()) {

src/Http/Controllers/PerformActionController.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ class PerformActionController extends RepositoryController
88
{
99
public function __invoke(ActionRequest $request)
1010
{
11-
$request->validate([
12-
'repositories' => 'required',
13-
]);
14-
1511
$action = $request->action();
1612

13+
if (! $action->isStandalone()) {
14+
$request->validate([
15+
'repositories' => 'required',
16+
]);
17+
}
18+
1719
return $action->handleRequest(
1820
$request,
1921
);

tests/Actions/PerformActionsControllerTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Binaryk\LaravelRestify\Tests\Fixtures\Post\PublishPostAction;
66
use Binaryk\LaravelRestify\Tests\Fixtures\User\ActivateAction;
7+
use Binaryk\LaravelRestify\Tests\Fixtures\User\DisableProfileAction;
78
use Binaryk\LaravelRestify\Tests\IntegrationTest;
89

910
class PerformActionsControllerTest extends IntegrationTest
@@ -64,4 +65,15 @@ public function test_show_action_not_need_repositories()
6465

6566
$this->assertEquals(1, ActivateAction::$applied[0]->id);
6667
}
68+
69+
public function test_could_perform_standalone_action()
70+
{
71+
$this->post('/restify-api/users/action?action='.(new DisableProfileAction())->uriKey())
72+
->assertSuccessful()
73+
->assertJsonStructure([
74+
'data',
75+
]);
76+
77+
$this->assertEquals('foo', DisableProfileAction::$applied[0]);
78+
}
6779
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Binaryk\LaravelRestify\Tests\Fixtures\User;
4+
5+
use Binaryk\LaravelRestify\Actions\Action;
6+
use Binaryk\LaravelRestify\Http\Requests\ActionRequest;
7+
use Illuminate\Http\JsonResponse;
8+
9+
class DisableProfileAction extends Action
10+
{
11+
public static $applied = [];
12+
13+
public static $uriKey = 'disable_profile';
14+
15+
public function handle(ActionRequest $request, $foo = 'foo'): JsonResponse
16+
{
17+
static::$applied[] = $foo;
18+
19+
return $this->response()->data(['succes' => 'true'])->respond();
20+
}
21+
}

tests/Fixtures/User/UserRepository.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public function actions(RestifyRequest $request)
4444
{
4545
return [
4646
ActivateAction::new(),
47+
48+
DisableProfileAction::new()->standalone(),
4749
];
4850
}
4951

0 commit comments

Comments
 (0)