22
33namespace Http \Message \MultipartStream ;
44
5+ use Http \Discovery \Exception \NotFoundException ;
6+ use Http \Discovery \Psr17FactoryDiscovery ;
57use Http \Discovery \StreamFactoryDiscovery ;
6- use Http \Message \StreamFactory ;
8+ use Http \Message \StreamFactory as HttplugStreamFactory ;
9+ use Psr \Http \Message \StreamFactoryInterface ;
710use Psr \Http \Message \StreamInterface ;
811
912/**
1619class MultipartStreamBuilder
1720{
1821 /**
19- * @var StreamFactory
22+ * @var StreamFactory|StreamFactoryInterface
2023 */
2124 private $ streamFactory ;
2225
@@ -36,11 +39,37 @@ class MultipartStreamBuilder
3639 private $ data = [];
3740
3841 /**
39- * @param StreamFactory|null $streamFactory
42+ * @param StreamFactory|StreamFactoryInterface| null $streamFactory
4043 */
41- public function __construct (StreamFactory $ streamFactory = null )
44+ public function __construct ($ streamFactory = null )
4245 {
43- $ this ->streamFactory = $ streamFactory ?: StreamFactoryDiscovery::find ();
46+ if ($ streamFactory instanceof StreamFactoryInterface || $ streamFactory instanceof HttplugStreamFactory) {
47+ $ this ->streamFactory = $ streamFactory ;
48+
49+ return ;
50+ }
51+
52+ if (null !== $ streamFactory ) {
53+ throw new \LogicException (sprintf (
54+ 'First arguemnt to the constructor of "%s" must be of type "%s", "%s" or null. Got %s ' ,
55+ __CLASS__ ,
56+ StreamFactoryInterface::class,
57+ HttplugStreamFactory::class,
58+ \is_object ($ streamFactory ) ? \get_class ($ streamFactory ) : \gettype ($ streamFactory )
59+ ));
60+ }
61+
62+ // Try to find a stream factory.
63+ try {
64+ $ this ->streamFactory = Psr17FactoryDiscovery::findStreamFactory ();
65+ } catch (NotFoundException $ psr17Exception ) {
66+ try {
67+ $ this ->streamFactory = StreamFactoryDiscovery::find ();
68+ } catch (NotFoundException $ httplugException ) {
69+ // we could not find any factory.
70+ throw $ psr17Exception ;
71+ }
72+ }
4473 }
4574
4675 /**
@@ -58,7 +87,7 @@ public function __construct(StreamFactory $streamFactory = null)
5887 */
5988 public function addResource ($ name , $ resource , array $ options = [])
6089 {
61- $ stream = $ this ->streamFactory -> createStream ($ resource );
90+ $ stream = $ this ->createStream ($ resource );
6291
6392 // validate options['headers'] exists
6493 if (!isset ($ options ['headers ' ])) {
@@ -108,7 +137,7 @@ public function build()
108137 // Append end
109138 $ streams .= "-- {$ this ->getBoundary ()}-- \r\n" ;
110139
111- return $ this ->streamFactory -> createStream ($ streams );
140+ return $ this ->createStream ($ streams );
112141 }
113142
114143 /**
@@ -275,4 +304,31 @@ private function basename($path)
275304
276305 return $ filename ;
277306 }
307+
308+ /**
309+ * @param string|resource|StreamInterface $resource
310+ *
311+ * @return StreamInterface
312+ */
313+ private function createStream ($ resource )
314+ {
315+ if ($ resource instanceof StreamInterface) {
316+ return $ resource ;
317+ }
318+
319+ if ($ this ->streamFactory instanceof HttplugStreamFactory) {
320+ return $ this ->streamFactory ->createStream ($ resource );
321+ }
322+
323+ // Assert: We are using a PSR17 stream factory.
324+ if (\is_string ($ resource )) {
325+ return $ this ->streamFactory ->createStream ($ resource );
326+ }
327+
328+ if (\is_resource ($ resource )) {
329+ return $ this ->streamFactory ->createStreamFromResource ($ resource );
330+ }
331+
332+ throw new \InvalidArgumentException (sprintf ('First argument to "%s::createStream()" must be a string, resource or StreamInterface. ' , __CLASS__ ));
333+ }
278334}
0 commit comments