File tree Expand file tree Collapse file tree 7 files changed +44
-7
lines changed Expand file tree Collapse file tree 7 files changed +44
-7
lines changed Original file line number Diff line number Diff line change @@ -47,6 +47,9 @@ class Context
47
47
// Links to be returned in the document's links object
48
48
public ArrayObject $documentLinks;
49
49
50
+ // Active JSON:API profile URIs for the current response
51
+ public ArrayObject $activeProfiles;
52
+
50
53
// Get the request method
51
54
public function method(): string;
52
55
@@ -79,5 +82,8 @@ class Context
79
82
80
83
// Determine whether a sort field has been requested
81
84
public function sortRequested(string $field): bool;
85
+
86
+ // Activate a JSON:API profile for the current response
87
+ public function activateProfile(string $uri): static;
82
88
}
83
89
```
Original file line number Diff line number Diff line change @@ -24,6 +24,7 @@ class Context
24
24
public ?array $ include = null ;
25
25
public ArrayObject $ documentMeta ;
26
26
public ArrayObject $ documentLinks ;
27
+ public ArrayObject $ activeProfiles ;
27
28
public WeakMap $ resourceMeta ;
28
29
29
30
private ?array $ body ;
@@ -45,6 +46,7 @@ public function __construct(public JsonApi $api, public ServerRequestInterface $
45
46
46
47
$ this ->documentMeta = new ArrayObject ();
47
48
$ this ->documentLinks = new ArrayObject ();
49
+ $ this ->activeProfiles = new ArrayObject ();
48
50
49
51
$ this ->resourceMeta = new WeakMap ();
50
52
}
@@ -289,6 +291,13 @@ public function resourceMeta($model, array $meta): static
289
291
return $ this ;
290
292
}
291
293
294
+ public function activateProfile (string $ uri ): static
295
+ {
296
+ $ this ->activeProfiles [$ uri ] = true ;
297
+
298
+ return $ this ;
299
+ }
300
+
292
301
public function forModel (array $ collections , ?object $ model ): static
293
302
{
294
303
$ new = clone $ this ;
Original file line number Diff line number Diff line change 3
3
namespace Tobyz \JsonApiServer \Exception \Pagination ;
4
4
5
5
use Tobyz \JsonApiServer \Exception \BadRequestException ;
6
+ use Tobyz \JsonApiServer \Pagination \CursorPagination ;
6
7
7
8
class MaxPageSizeExceededException extends BadRequestException
8
9
{
@@ -11,9 +12,7 @@ public function __construct(private readonly int $maxSize)
11
12
parent ::__construct ('Page size requested is too large ' );
12
13
13
14
$ this ->meta (['page ' => ['maxSize ' => $ this ->maxSize ]])->links ([
14
- 'type ' => [
15
- 'https://jsonapi.org/profiles/ethanresnick/cursor-pagination/max-size-exceeded ' ,
16
- ],
15
+ 'type ' => [CursorPagination::PROFILE_URI . '/max-size-exceeded ' ],
17
16
]);
18
17
}
19
18
}
Original file line number Diff line number Diff line change 3
3
namespace Tobyz \JsonApiServer \Exception \Pagination ;
4
4
5
5
use Tobyz \JsonApiServer \Exception \BadRequestException ;
6
+ use Tobyz \JsonApiServer \Pagination \CursorPagination ;
6
7
7
8
class RangePaginationNotSupportedException extends BadRequestException
8
9
{
@@ -11,9 +12,7 @@ public function __construct()
11
12
parent ::__construct ('Range pagination is not supported ' );
12
13
13
14
$ this ->links ([
14
- 'type ' => [
15
- 'https://jsonapi.org/profiles/ethanresnick/cursor-pagination/range-pagination-not-supported ' ,
16
- ],
15
+ 'type ' => [CursorPagination::PROFILE_URI . '/range-pagination-not-supported ' ],
17
16
]);
18
17
}
19
18
}
Original file line number Diff line number Diff line change @@ -166,6 +166,16 @@ public function handle(Request $request): Response
166
166
throw $ e ?? new NotFoundException ();
167
167
}
168
168
169
+ if (count ($ context ->activeProfiles )) {
170
+ $ contentType = $ response ->getHeaderLine ('Content-Type ' );
171
+
172
+ if (str_starts_with ($ contentType , self ::MEDIA_TYPE )) {
173
+ $ profileUris = array_keys (array_filter ($ context ->activeProfiles ->getArrayCopy ()));
174
+ $ contentType .= '; profile=" ' . implode (' ' , $ profileUris ) . '" ' ;
175
+ $ response = $ response ->withHeader ('Content-Type ' , $ contentType );
176
+ }
177
+ }
178
+
169
179
return $ response ->withAddedHeader ('Vary ' , 'Accept ' );
170
180
}
171
181
Original file line number Diff line number Diff line change @@ -13,6 +13,8 @@ class CursorPagination implements Pagination
13
13
{
14
14
use HasSizeParameter;
15
15
16
+ public const PROFILE_URI = 'https://jsonapi.org/profiles/ethanresnick/cursor-pagination ' ;
17
+
16
18
public readonly int $ size ;
17
19
public readonly ?string $ after ;
18
20
public readonly ?string $ before ;
@@ -24,6 +26,8 @@ public function __construct(int $defaultSize = 20, ?int $maxSize = 50)
24
26
25
27
public function paginate (object $ query , Context $ context ): array
26
28
{
29
+ $ context ->activateProfile (self ::PROFILE_URI );
30
+
27
31
$ size = $ this ->getSize ($ context , 'size ' );
28
32
$ after = $ this ->getCursor ($ context , 'after ' );
29
33
$ before = $ this ->getCursor ($ context , 'before ' );
Original file line number Diff line number Diff line change 4
4
5
5
use Tobyz \JsonApiServer \Endpoint \Index ;
6
6
use Tobyz \JsonApiServer \Exception \BadRequestException ;
7
- use Tobyz \JsonApiServer \JsonApi ;
8
7
use Tobyz \JsonApiServer \Exception \Pagination \MaxPageSizeExceededException ;
9
8
use Tobyz \JsonApiServer \Exception \Pagination \RangePaginationNotSupportedException ;
9
+ use Tobyz \JsonApiServer \JsonApi ;
10
10
use Tobyz \Tests \JsonApiServer \AbstractTestCase ;
11
11
use Tobyz \Tests \JsonApiServer \MockResource ;
12
12
@@ -27,6 +27,16 @@ public function setUp(): void
27
27
);
28
28
}
29
29
30
+ public function test_includes_profile_in_content_type (): void
31
+ {
32
+ $ response = $ this ->api ->handle ($ this ->buildRequest ('GET ' , '/articles ' ));
33
+
34
+ $ this ->assertEquals (
35
+ 'application/vnd.api+json; profile="https://jsonapi.org/profiles/ethanresnick/cursor-pagination" ' ,
36
+ $ response ->getHeaderLine ('Content-Type ' ),
37
+ );
38
+ }
39
+
30
40
public function test_first_page_includes_expected_links_and_item_cursors (): void
31
41
{
32
42
$ response = $ this ->api ->handle ($ this ->buildRequest ('GET ' , '/articles ' ));
You can’t perform that action at this time.
0 commit comments