@@ -332,6 +332,7 @@ public function uploadV2($path, array $parameters = [])
332
332
'media ' => fread ($ media , $ this ->chunkSize )
333
333
],
334
334
false ,
335
+ true ,
335
336
);
336
337
}
337
338
fclose ($ media );
@@ -579,7 +580,8 @@ private function http(
579
580
string $ host ,
580
581
string $ path ,
581
582
array $ parameters ,
582
- bool $ json
583
+ bool $ json ,
584
+ bool $ isBinaryMultipart = false
583
585
) {
584
586
$ this ->resetLastResponse ();
585
587
$ this ->resetAttemptsNumber ();
@@ -593,6 +595,7 @@ private function http(
593
595
$ method ,
594
596
$ parameters ,
595
597
$ json ,
598
+ $ isBinaryMultipart
596
599
);
597
600
}
598
601
@@ -648,11 +651,12 @@ private function makeRequests(
648
651
string $ url ,
649
652
string $ method ,
650
653
array $ parameters ,
651
- bool $ json
654
+ bool $ json ,
655
+ bool $ isBinaryMultipart = false
652
656
) {
653
657
do {
654
658
$ this ->sleepIfNeeded ();
655
- $ result = $ this ->oAuthRequest ($ url , $ method , $ parameters , $ json );
659
+ $ result = $ this ->oAuthRequest ($ url , $ method , $ parameters , $ json, $ isBinaryMultipart );
656
660
$ response = JsonDecoder::decode ($ result , $ this ->decodeJsonAsArray );
657
661
$ this ->response ->setBody ($ response );
658
662
$ this ->attempts ++;
@@ -689,15 +693,18 @@ private function oAuthRequest(
689
693
string $ url ,
690
694
string $ method ,
691
695
array $ parameters ,
692
- bool $ json = false
696
+ bool $ json = false ,
697
+ bool $ isBinaryMultipart = false
693
698
) {
694
699
$ request = Request::fromConsumerAndToken (
695
700
$ this ->consumer ,
696
701
$ this ->token ,
697
702
$ method ,
698
703
$ url ,
699
704
$ parameters ,
700
- $ json ,
705
+ // jsonに加えて、binary multipartリクエストの場合でもbodyをoauthのsignatureの生成に利用しない
706
+ // @see https://developer.x.com/en/docs/x-api/v1/media/upload-media/uploading-media/media-best-practices
707
+ $ json || $ isBinaryMultipart
701
708
);
702
709
if (array_key_exists ('oauth_callback ' , $ parameters )) {
703
710
// Twitter doesn't like oauth_callback as a parameter.
@@ -724,6 +731,7 @@ private function oAuthRequest(
724
731
$ authorization ,
725
732
$ parameters ,
726
733
$ json ,
734
+ $ isBinaryMultipart
727
735
);
728
736
}
729
737
@@ -780,7 +788,8 @@ private function request(
780
788
string $ method ,
781
789
string $ authorization ,
782
790
array $ postfields ,
783
- bool $ json = false
791
+ bool $ json = false ,
792
+ bool $ isBinaryMultipart = false
784
793
): string {
785
794
$ options = $ this ->curlOptions ();
786
795
$ options [CURLOPT_URL ] = $ url ;
@@ -799,6 +808,7 @@ private function request(
799
808
$ options ,
800
809
$ postfields ,
801
810
$ json ,
811
+ $ isBinaryMultipart
802
812
);
803
813
break ;
804
814
case 'DELETE ' :
@@ -903,7 +913,8 @@ private function curlCaOpt(string $path): int
903
913
private function setPostfieldsOptions (
904
914
array $ options ,
905
915
array $ postfields ,
906
- bool $ json
916
+ bool $ json ,
917
+ bool $ isBinaryMultipart = false
907
918
): array {
908
919
if ($ json ) {
909
920
$ options [CURLOPT_HTTPHEADER ][] = 'Content-type: application/json ' ;
@@ -912,7 +923,13 @@ private function setPostfieldsOptions(
912
923
JSON_THROW_ON_ERROR ,
913
924
);
914
925
} else {
915
- $ options [CURLOPT_POSTFIELDS ] = Util::buildHttpQuery ($ postfields );
926
+ if ($ isBinaryMultipart ) {
927
+ // binary multipartリクエストの場合headerを設定し、postデータをエンコードせず直接設定(X API v2 メディアアップロードの対応)
928
+ $ options [CURLOPT_HTTPHEADER ][] = 'Content-type: multipart/form-data ' ;
929
+ $ options [CURLOPT_POSTFIELDS ] = $ postfields ;
930
+ } else {
931
+ $ options [CURLOPT_POSTFIELDS ] = Util::buildHttpQuery ($ postfields );
932
+ }
916
933
}
917
934
918
935
return $ options ;
0 commit comments