Skip to content

Commit 27ea37c

Browse files
committed
Handling Workflow Stage
1 parent 5d8b0da commit 27ea37c

File tree

10 files changed

+342
-1
lines changed

10 files changed

+342
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 0.0.4 - WIP
4+
5+
- Adding WorkflowStage Api class for handling workflow stages
6+
-
37
## 0.0.3 - 2025-02-03
48

59
- Adding helper methods for SpaceData (id(), updatedAt())

README.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ if ($response->isOk()) {
527527

528528
## Handling Workflows
529529

530-
If you need to handle workflows (retrieving workflows or create new custome workflow - in the case you have a proper plan - ) you can use the `WorkflowApi` class.
530+
If you need to handle workflows (retrieving workflows or create new custom workflow - in the case you have a proper plan - ) you can use the `WorkflowApi` class.
531531

532532
### Retrieving workflows
533533

@@ -555,6 +555,43 @@ $workflowData->setName("Name");
555555
$response = $workflowApi->create($workflowData);
556556
```
557557

558+
## Handling Workflow Stage
559+
560+
If you need to handle workflow stages (retrieving workflow stages or create new custom workflow stage - in the case you have a proper plan - ) you can use the `WorkflowStageApi` class.
561+
562+
### Retrieving workflow stages
563+
564+
```php
565+
$response = $workflowStageApi->list();
566+
/** @var WorkflowsData $workflows */
567+
$workflowStages = $response->data();
568+
foreach ($workflowStages as $key => $workflowStage) {
569+
echo "Workflow Stage: " . $workflowStage->name() . " - ";
570+
echo $workflowStage->id() . PHP_EOL;
571+
}
572+
```
573+
### Creating a new custom workflow stage
574+
575+
In this example, we are going to retrieve the first workflow id available (probably you should retrieve a proper workflow that makes sense for your use case):
576+
577+
```php
578+
$workflowApi = $client->workflowApi($spaceId);
579+
$response = $workflowApi->list();
580+
$workflowId = $response->data()->get("0.id");
581+
```
582+
583+
And then create a new workflow stage:
584+
585+
```php
586+
use Storyblok\ManagementApi\Data\WorkflowStageData;
587+
588+
$workflowStageApi = $client->workflowStageApi($spaceId);
589+
$workflowStageData = new WorkflowStageData();
590+
$workflowStageData->setName("Name");
591+
$workflowStageData->setWorkflowId($workflowId);
592+
$response = $workflowStageApi->create($workflowStageData);
593+
```
594+
558595

559596
## Using the `ManagementApi` class
560597

src/Data/WorkflowStageData.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Storyblok\ManagementApi\Data;
6+
7+
use Storyblok\ManagementApi\Data\StoryblokData;
8+
use Storyblok\ManagementApi\StoryblokUtils;
9+
10+
class WorkflowStageData extends StoryblokData
11+
{
12+
/**
13+
* @param array<string, array<mixed>> $data
14+
*/
15+
public static function makeFromResponse(array $data = []): self
16+
{
17+
return new self($data["workflow_stage"] ?? []);
18+
}
19+
20+
#[\Override]
21+
public static function make(array $data = []): self
22+
{
23+
return new self($data);
24+
}
25+
26+
public function setName(string $name): void
27+
{
28+
$this->set('name', $name);
29+
}
30+
31+
public function setWorkflowId(string|int $workflowId): void
32+
{
33+
$this->set('workflow_id', $workflowId);
34+
}
35+
36+
37+
38+
39+
40+
public function name(): string
41+
{
42+
return $this->getString('name', "");
43+
}
44+
45+
public function id(): string
46+
{
47+
return $this->getString('id', "");
48+
}
49+
50+
51+
52+
}

src/Data/WorkflowStagesData.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Storyblok\ManagementApi\Data;
6+
7+
class WorkflowStagesData extends StoryblokData
8+
{
9+
#[\Override]
10+
public function getDataClass(): string
11+
{
12+
return WorkflowStageData::class;
13+
}
14+
15+
#[\Override]
16+
public static function make(array $data = []): self
17+
{
18+
return new self($data);
19+
}
20+
21+
/**
22+
* @param array<string, array<mixed>> $data
23+
*/
24+
public static function makeFromResponse(array $data = []): self
25+
{
26+
return new self($data["workflow_stages"] ?? []);
27+
}
28+
29+
30+
public function howManyWorkflowStages(): int
31+
{
32+
return $this->count();
33+
}
34+
35+
}

src/Endpoints/WorkflowStageApi.php

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Storyblok\ManagementApi\Endpoints;
6+
7+
use Storyblok\ManagementApi\Data\StoryblokData;
8+
use Storyblok\ManagementApi\Data\WorkflowStageData;
9+
use Storyblok\ManagementApi\Data\WorkflowStagesData;
10+
use Storyblok\ManagementApi\QueryParameters\WorkflowStagesParams;
11+
use Storyblok\ManagementApi\StoryblokResponseInterface;
12+
13+
/**
14+
*
15+
*/
16+
class WorkflowStageApi extends EndpointSpace
17+
{
18+
/**
19+
* @param string|string[]|null $byIds
20+
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
21+
*/
22+
public function list(
23+
string|int|null $inWorkflowId = null,
24+
string|null $search = null,
25+
string|array|null $byIds = null,
26+
string|null $excludeId = null,
27+
): StoryblokResponseInterface {
28+
$options = [];
29+
$params = new WorkflowStagesParams(
30+
$inWorkflowId,
31+
$search,
32+
$byIds,
33+
$excludeId,
34+
);
35+
36+
$options = [
37+
'query' => $params->toArray(),
38+
];
39+
40+
return $this->makeRequest(
41+
"GET",
42+
'/v1/spaces/' . $this->spaceId . '/workflow_stages',
43+
options: $options,
44+
dataClass: WorkflowStagesData::class,
45+
);
46+
}
47+
48+
public function get(string|int $workflowStageId): StoryblokResponseInterface
49+
{
50+
51+
return $this->makeRequest(
52+
"GET",
53+
'/v1/spaces/' . $this->spaceId . '/workflow_stages/' . $workflowStageId,
54+
dataClass: WorkflowStageData::class,
55+
);
56+
}
57+
58+
59+
/**
60+
* @param string|int $workflowStageId the workflow stage identifier
61+
*/
62+
public function delete(string|int $workflowStageId): StoryblokResponseInterface
63+
{
64+
return $this->makeRequest(
65+
"DELETE",
66+
'/v1/spaces/' . $this->spaceId . '/workflow_stages/' . $workflowStageId,
67+
);
68+
}
69+
70+
public function create(StoryblokData $storyblokData): StoryblokResponseInterface
71+
{
72+
return $this->makeRequest(
73+
"POST",
74+
"/v1/spaces/" . $this->spaceId . '/workflow_stages',
75+
[
76+
"body" => [
77+
"workflow_stage" => $storyblokData->toArray(),
78+
],
79+
],
80+
dataClass: WorkflowStageData::class,
81+
);
82+
}
83+
84+
public function update(string|int $workflowStageId, StoryblokData $storyblokData): StoryblokResponseInterface
85+
{
86+
return $this->makeRequest(
87+
"POST",
88+
"/v1/spaces/" . $this->spaceId . '/workflow_stages/' . $workflowStageId,
89+
[
90+
"body" => $storyblokData->toArray(),
91+
],
92+
dataClass: WorkflowStageData::class,
93+
);
94+
}
95+
96+
97+
98+
99+
100+
}

src/ManagementApiClient.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Storyblok\ManagementApi\Endpoints\TagApi;
1313
use Storyblok\ManagementApi\Endpoints\UserApi;
1414
use Storyblok\ManagementApi\Endpoints\WorkflowApi;
15+
use Storyblok\ManagementApi\Endpoints\WorkflowStageApi;
1516
use Symfony\Component\HttpClient\HttpClient;
1617
use Symfony\Contracts\HttpClient\HttpClientInterface;
1718
use Psr\Log\LoggerInterface;
@@ -105,6 +106,11 @@ public function workflowApi(string|int $spaceId): WorkflowApi
105106
return new WorkflowApi($this->httpClient, $spaceId);
106107
}
107108

109+
public function workflowStageApi(string|int $spaceId): WorkflowStageApi
110+
{
111+
return new WorkflowStageApi($this->httpClient, $spaceId);
112+
}
113+
108114
public function managementApi(): ManagementApi
109115
{
110116
return new ManagementApi($this->httpClient);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Storyblok\ManagementApi\QueryParameters;
6+
7+
use Storyblok\ManagementApi\QueryParameters\Type\SortBy;
8+
9+
class WorkflowStagesParams
10+
{
11+
/**
12+
* @param string|string[]|null $byIds
13+
*/
14+
public function __construct(
15+
private readonly string|int|null $inWorkflowId = null,
16+
private readonly string|null $search = null,
17+
private readonly string|array|null $byIds = null,
18+
private readonly string|null $excludeId = null,
19+
) {}
20+
21+
/**
22+
* @return array<mixed>
23+
*/
24+
public function toArray(): array
25+
{
26+
$array = [];
27+
if (null !== $this->inWorkflowId) {
28+
$array['in_workflow'] = $this->inWorkflowId;
29+
}
30+
31+
if (null !== $this->search) {
32+
$array['search'] = $this->search;
33+
}
34+
35+
if (null !== $this->excludeId) {
36+
$array['exclude_id'] = $this->excludeId;
37+
}
38+
39+
40+
41+
if (null !== $this->byIds) {
42+
if (is_array($this->byIds)) {
43+
$array['by_ids'] = implode(",", $this->byIds);
44+
}
45+
46+
if (is_string($this->byIds)) {
47+
$array['by_ids'] = $this->byIds;
48+
}
49+
}
50+
51+
return $array;
52+
}
53+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"workflow_stages": [
3+
{
4+
"allow_publish":false,
5+
"is_default":false,
6+
"id":653554,"user_ids":[],"space_role_ids":[],"workflow_stage_ids":[653555],"name":"Drafting","color":"#babcb6","allow_all_stages":false,"allow_admin_publish":false,"allow_all_users":true,"allow_admin_change":false,"allow_editor_change":false,"position":1,"after_publish_id":null,"workflow_id":93606,"story_editing_locked":false,"allow_none_for_next_stages":false,"auto_remove_assignee":false,"_new":false,"_destroy":false
7+
}
8+
,
9+
{
10+
"allow_publish":false,
11+
"is_default":false,
12+
"id":653555,"user_ids":[],"space_role_ids":[],"workflow_stage_ids":[653556],"name":"Review","color":"#babcb6","allow_all_stages":false,"allow_admin_publish":false,"allow_all_users":true,"allow_admin_change":false,"allow_editor_change":false,"position":1,"after_publish_id":null,"workflow_id":93606,"story_editing_locked":false,"allow_none_for_next_stages":false,"auto_remove_assignee":false,"_new":false,"_destroy":false
13+
}
14+
]
15+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"workflow_stage":{
3+
"allow_publish":false,
4+
"is_default":false,
5+
"id":653554,"user_ids":[],"space_role_ids":[],"workflow_stage_ids":[653555],"name":"Draftin","color":"#babcb6","allow_all_stages":false,"allow_admin_publish":false,"allow_all_users":true,"allow_admin_change":false,"allow_editor_change":false,"position":1,"after_publish_id":null,"workflow_id":93606,"story_editing_locked":false,"allow_none_for_next_stages":false,"auto_remove_assignee":false,"_new":false,"_destroy":false}
6+
}
7+

tests/Feature/WorkflowStageTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
6+
use Storyblok\ManagementApi\ManagementApiClient;
7+
use Symfony\Component\HttpClient\MockHttpClient;
8+
9+
test('Testing list of workflow stages', function (): void {
10+
$responses = [
11+
\mockResponse("list-workflow-stages", 200, []),
12+
\mockResponse("list-workflow-stages", 200,[]),
13+
//\mockResponse("empty-asset", 404),
14+
];
15+
16+
$client = new MockHttpClient($responses);
17+
$mapiClient = ManagementApiClient::initTest($client);
18+
$workflowStageApi = $mapiClient->workflowStageApi("222");
19+
20+
$storyblokResponse = $workflowStageApi->list(
21+
inWorkflowId: "12345"
22+
);
23+
$string = $storyblokResponse->getLastCalledUrl();
24+
expect($string)->toMatch('/.*in_workflow=12345.*$/');
25+
26+
$storyblokResponse = $workflowStageApi->list(
27+
byIds: [ "12345", "54321" ]
28+
);
29+
$string = $storyblokResponse->getLastCalledUrl();
30+
expect($string)->toMatch('/.*by_ids=12345%2C54321.*$/');
31+
32+
});

0 commit comments

Comments
 (0)