Skip to content

Commit b6d8d59

Browse files
committed
✨ standalone action
1 parent b177212 commit b6d8d59

File tree

6 files changed

+152
-8
lines changed

6 files changed

+152
-8
lines changed

src/Actions/Action.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ class Action implements \JsonSerializable
4949
*/
5050
public $name;
5151

52+
/**
53+
* Indicates if the action can be run with no model.
54+
*
55+
* @var bool
56+
*/
57+
public $standalone = false;
58+
5259
/**
5360
* The number of models that should be included in each chunk.
5461
*
@@ -76,6 +83,28 @@ public function uriKey()
7683
return Str::slug($this->name(), '-', null);
7784
}
7885

86+
/**
87+
* Mark the action as a standalone action.
88+
*
89+
* @return $this
90+
*/
91+
public function standalone()
92+
{
93+
$this->standalone = true;
94+
95+
return $this;
96+
}
97+
98+
/**
99+
* Determine if the action is a standalone action.
100+
*
101+
* @return bool
102+
*/
103+
public function isStandalone()
104+
{
105+
return $this->standalone;
106+
}
107+
79108
/**
80109
* Prepare the action for JSON serialization.
81110
*
@@ -90,6 +119,7 @@ public function jsonSerialize(): array
90119
'uriKey' => $this->uriKey(),
91120
'fields' => $this->fields($request),
92121
'meta' => $this->meta(),
122+
'standalone' => $this->isStandalone()
93123
];
94124
}
95125

src/Actions/DispatchAction.php

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,26 @@ protected function configureBatchJob(\Lomkit\Rest\Actions\Action $action, array
9595
*/
9696
public function dispatch($chunkCount)
9797
{
98+
if ($this->action->isStandalone()) {
99+
$modelsImpacted = $this->handleStandalone();
100+
} else {
101+
$modelsImpacted = $this->handleClassic($chunkCount);
102+
}
103+
104+
if (!is_null($this->batchJob)) {
105+
$this->batchJob->dispatch();
106+
}
107+
108+
return $modelsImpacted;
109+
}
110+
111+
/**
112+
* Dispatch the given action.
113+
*
114+
* @param int $chunkCount
115+
* @return int
116+
*/
117+
public function handleClassic(int $chunkCount) {
98118
$searchQuery =
99119
app()->make(QueryBuilder::class, ['resource' => $this->request->resource, 'query' => null])
100120
->search($this->request->input('search', []));
@@ -112,25 +132,34 @@ function ($chunk) {
112132
}
113133
);
114134

115-
if (!is_null($this->batchJob)) {
116-
$this->batchJob->dispatch();
117-
}
118-
119135
return $searchQuery->count();
120136
}
121137

138+
/**
139+
* Dispatch the given standalone action.
140+
*
141+
* @return int
142+
*
143+
*/
144+
public function handleStandalone() {
145+
146+
$this->forModels(
147+
\Illuminate\Database\Eloquent\Collection::make()
148+
);
149+
150+
return 0;
151+
}
152+
122153
/**
123154
* Dispatch the given action.
124155
*
125156
* @param Collection $models
126157
*
127-
* @throws \Throwable
128-
*
129158
* @return mixed|void
130159
*/
131160
public function forModels(Collection $models)
132161
{
133-
if ($models->isEmpty()) {
162+
if ($models->isEmpty() && !$this->action->isStandalone()) {
134163
return;
135164
}
136165

src/Http/Requests/OperateRequest.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ public function operateRules(Resource $resource)
4444
$operatedAction = $resource->action($this, $this->route()->parameter('action'));
4545

4646
return array_merge(
47-
app(SearchRequest::class)->searchRules($resource, 'search'),
47+
$operatedAction->isStandalone() ? [
48+
'search' => [
49+
'prohibited'
50+
]
51+
] : [],
52+
!$operatedAction->isStandalone() ? app(SearchRequest::class)->searchRules($resource, 'search') : [],
4853
[
4954
'fields.*.name' => [
5055
Rule::in(array_keys($operatedAction->fields($this))),

tests/Feature/Controllers/ActionsOperationsTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,58 @@ public function test_operate_action(): void
3636
);
3737
}
3838

39+
public function test_operate_standalone_action(): void
40+
{
41+
$model = ModelFactory::new()->create();
42+
ModelFactory::new()->create();
43+
44+
Gate::policy(Model::class, GreenPolicy::class);
45+
46+
$response = $this->post(
47+
'/api/models/actions/standalone-modify-number',
48+
[],
49+
['Accept' => 'application/json']
50+
);
51+
52+
$response->assertJson([
53+
'data' => [
54+
'impacted' => 0,
55+
],
56+
]);
57+
$this->assertEquals(
58+
1,
59+
Model::where('number', 100000000)->count()
60+
);
61+
}
62+
63+
public function test_operate_standalone_action_with_fields(): void
64+
{
65+
$model = ModelFactory::new()->create();
66+
ModelFactory::new()->create();
67+
68+
Gate::policy(Model::class, GreenPolicy::class);
69+
70+
$response = $this->post(
71+
'/api/models/actions/standalone-modify-number',
72+
[
73+
'fields' => [
74+
['name' => 'number', 'value' => 100000001],
75+
],
76+
],
77+
['Accept' => 'application/json']
78+
);
79+
80+
$response->assertJson([
81+
'data' => [
82+
'impacted' => 0,
83+
],
84+
]);
85+
$this->assertEquals(
86+
1,
87+
Model::where('number', 100000001)->count()
88+
);
89+
}
90+
3991
public function test_operate_not_found_action(): void
4092
{
4193
ModelFactory::new()->count(2)->create();
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Lomkit\Rest\Tests\Support\Rest\Actions;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use Illuminate\Support\Collection;
7+
use Lomkit\Rest\Actions\Action;
8+
use Lomkit\Rest\Http\Requests\RestRequest;
9+
10+
class StandaloneModifyNumberAction extends ModifyNumberAction
11+
{
12+
/**
13+
* Perform the action on the given models.
14+
*
15+
* @param array $fields
16+
* @param \Illuminate\Support\Collection $models
17+
*
18+
* @return mixed
19+
*/
20+
public function handle(array $fields, Collection $models)
21+
{
22+
\Lomkit\Rest\Tests\Support\Models\Model::first()
23+
->forceFill(['number' => $fields['number'] ?? 100000000])
24+
->save();
25+
}
26+
}

tests/Support/Rest/Resources/ModelResource.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Lomkit\Rest\Tests\Support\Rest\Actions\BatchableModifyNumberAction;
2323
use Lomkit\Rest\Tests\Support\Rest\Actions\ModifyNumberAction;
2424
use Lomkit\Rest\Tests\Support\Rest\Actions\QueueableModifyNumberAction;
25+
use Lomkit\Rest\Tests\Support\Rest\Actions\StandaloneModifyNumberAction;
2526
use Lomkit\Rest\Tests\Support\Rest\Actions\WithMetaModifyNumberAction;
2627
use Lomkit\Rest\Tests\Support\Rest\Instructions\NumberedInstruction;
2728

@@ -133,6 +134,7 @@ public function actions(RestRequest $request): array
133134
{
134135
return [
135136
ModifyNumberAction::make(),
137+
StandaloneModifyNumberAction::make()->standalone(),
136138
QueueableModifyNumberAction::make(),
137139
WithMetaModifyNumberAction::make(),
138140
BatchableModifyNumberAction::make(),

0 commit comments

Comments
 (0)