File tree Expand file tree Collapse file tree 5 files changed +55
-8
lines changed Expand file tree Collapse file tree 5 files changed +55
-8
lines changed Original file line number Diff line number Diff line change @@ -28,6 +28,10 @@ are not meant to be extended.
28
28
Also added PHP 7 type-hinting to all methods in the abstract class.
29
29
30
30
### Fixed
31
+ - [ #265 ] ( https://github.com/cloudcreativity/laravel-json-api/issues/265 )
32
+ Allow wildcard media type parameters when matching decoders. This enables support for media types that
33
+ include random parameter values, primarily the ` multipart/form-data ` type that has a ` boundary ` parameter
34
+ that is unpredictable.
31
35
- [ #280 ] ( https://github.com/cloudcreativity/laravel-json-api/issues/280 )
32
36
Validation error objects for relationship objects now have correct source pointers.
33
37
- [ #284 ] ( https://github.com/cloudcreativity/laravel-json-api/issues/284 )
Original file line number Diff line number Diff line change @@ -589,6 +589,7 @@ class ContentNegotiator extends BaseContentNegotiator
589
589
{
590
590
protected $decoding = [
591
591
'multipart/form-data' => \App\JsonApi\MultipartDecoder::class,
592
+ 'multipart/form-data; boundary=*' => \App\JsonApi\MultipartDecoder::class,
592
593
];
593
594
}
594
595
```
@@ -630,11 +631,12 @@ class ContentNegotiator extends BaseContentNegotiator
630
631
*/
631
632
protected function decodingsForResource(?Avatar $avatar): DecodingList
632
633
{
633
- $multiPart = Decoding::create('multipart/form-data', new MultipartDecoder() );
634
+ $decoder = new MultipartDecoder();
634
635
635
636
return $this
636
637
->decodingMediaTypes()
637
- ->when(is_null($avatar), $multiPart);
638
+ ->when(is_null($avatar), Decoding::create('multipart/form-data', $decoder))
639
+ ->when(is_null($avatar), Decoding::create('multipart/form-data; boundary=*', $decoder));
638
640
}
639
641
640
642
}
Original file line number Diff line number Diff line change 20
20
use CloudCreativity \LaravelJsonApi \Contracts \Decoder \DecoderInterface ;
21
21
use CloudCreativity \LaravelJsonApi \Decoder \JsonApiDecoder ;
22
22
use CloudCreativity \LaravelJsonApi \Exceptions \RuntimeException ;
23
+ use Illuminate \Support \Collection ;
23
24
use Neomerx \JsonApi \Contracts \Http \Headers \MediaTypeInterface ;
24
25
use Neomerx \JsonApi \Http \Headers \MediaType ;
25
26
@@ -145,1
8000
0 +146,37 @@ public function isNotJsonApi(): bool
145
146
/**
146
147
* @param MediaTypeInterface $mediaType
147
148
* @return bool
149
+ * @todo normalization will not be necessary for neomerx/json-api:^3.0
150
+ * @see https://github.com/neomerx/json-api/issues/221
148
151
*/
149
152
public function equalsTo (MediaTypeInterface $ mediaType ): bool
150
153
{
151
- return $ this ->mediaType ->equalsTo ($ mediaType );
154
+ return $ this ->normalize ($ this ->mediaType )->equalsTo (
155
+ $ this ->normalize ($ mediaType )
156
+ );
157
+ }
158
+
159
+ /**
160
+ * @return array
161
+ */
162
+ private function getWildCardParameters (): array
163
+ {
164
+ return collect ((array ) $ this ->mediaType ->getParameters ())->filter (function ($ value ) {
165
+ return '* ' === $ value ;
166
+ })->keys ()->all ();
167
+ }
168
+
169
+ /**
170
+ * @param MediaTypeInterface $mediaType
171
+ * @return MediaTypeInterface
172
+ */
173
+ private function normalize (MediaTypeInterface $ mediaType ): MediaTypeInterface
174
+ {
175
+ $ params = collect ((array ) $ mediaType ->getParameters ())->forget (
176
+ $ this ->getWildCardParameters ()
177
+ )->all ();
178
+
179
+ return new MediaType ($ mediaType ->getType (), $ mediaType ->getSubType (), $ params ?: null );
152
180
}
153
181
154
182
}
Original file line number Diff line number Diff line change @@ -46,11 +46,10 @@ protected function encodingsForOne(?Avatar $avatar): EncodingList
46
46
*/
47
47
protected function decodingsForResource (?Avatar $ avatar ): DecodingList
48
48
{
49
- $ multiPart = Decoding::create ('multipart/form-data ' , new FileDecoder ());
50
-
51
49
return $ this
52
50
->decodingMediaTypes ()
53
- ->when (is_null ($ avatar ), $ multiPart );
51
+ ->when (is_null ($ avatar ), Decoding::create ('multipart/form-data ' , new FileDecoder ()))
52
+ ->when (is_null ($ avatar ), Decoding::create ('multipart/form-data; boundary=* ' , new FileDecoder ()));
54
53
}
55
54
56
55
}
Original file line number Diff line number Diff line change 26
26
class CreateTest extends TestCase
27
27
{
28
28
29
+ /**
30
+ * @return array
31
+ */
32
+ public function multipartProvider (): array
33
+ {
34
+ return [
35
+ ['multipart/form-data ' ],
36
+ ['multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW ' ],
37
+ ];
38
+ }
39
+
29
40
/**
30
41
* Test that a user can upload an avatar to the API using a standard
31
42
* HTML form post. This means our API must allow a non-JSON API content media type
32
43
* when creating the resource.
44
+ *
45
+ * @param string $contentType
46
+ * @dataProvider multipartProvider
33
47
*/
34
- public function test (): void
48
+ public function test (string $ contentType ): void
35
49
{
36
50
$ user = factory (User::class)->create ();
37
51
$ file = UploadedFile::fake ()->create ('avatar.jpg ' );
@@ -45,7 +59,7 @@ public function test(): void
45
59
$ response = $ this ->actingAs ($ user , 'api ' )->post (
46
60
'/api/v1/avatars?include=user ' ,
47
61
['avatar ' => $ file ],
48
- ['Content-Type ' => ' multipart/form-data ' , 'Content-Length ' => '1 ' ]
<
4CD7
td data-grid-cell-id="diff-17b42312ec83876147b463ca48f2b52566222db3476cc5dd282ed6e5f43b3273-48-62-0" data-selected="false" role="gridcell" style="background-color:var(--diffBlob-additionNum-bgColor, var(--diffBlob-addition-bgColor-num));text-align:center" tabindex="-1" valign="top" class="focusable-grid-cell diff-line-number position-relative left-side">
62
+ ['Content-Type ' => $ contentType , 'Content-Length ' => '1 ' ]
49
63
);
50
64
51
65
$ id = $ response
You can’t perform that action at this time.
0 commit comments