GuzzleHttpPsr7MultipartStream

Stream that when read returns bytes for a streaming multipart or multipart/form-data stream.

Defined (1)

The class is defined in the following location(s).

/lib/Azure/GuzzleHttp/Psr7/MultipartStream.php  
  1. class MultipartStream implements StreamInterface 
  2. use StreamDecoratorTrait; 
  3.  
  4. private $boundary; 
  5.  
  6. /** 
  7. * @param array $elements Array of associative arrays, each containing a 
  8. * required "name" key mapping to the form field,  
  9. * name, a required "contents" key mapping to a 
  10. * StreamInterface/resource/string, an optional 
  11. * "headers" associative array of custom headers,  
  12. * and an optional "filename" key mapping to a 
  13. * string to send as the filename in the part. 
  14. * @param string $boundary You can optionally provide a specific boundary 
  15. * @throws \InvalidArgumentException 
  16. */ 
  17. public function __construct(array $elements = [], $boundary = null) 
  18. $this->boundary = $boundary ?: uniqid(); 
  19. $this->stream = $this->createStream($elements); 
  20.  
  21. /** 
  22. * Get the boundary 
  23. * @return string 
  24. */ 
  25. public function getBoundary() 
  26. return $this->boundary; 
  27.  
  28. public function isWritable() 
  29. return false; 
  30.  
  31. /** 
  32. * Get the headers needed before transferring the content of a POST file 
  33. */ 
  34. private function getHeaders(array $headers) 
  35. $str = ''; 
  36. foreach ($headers as $key => $value) { 
  37. $str .= "{$key}: {$value}\r\n"; 
  38.  
  39. return "--{$this->boundary}\r\n" . trim($str) . "\r\n\r\n"; 
  40.  
  41. /** 
  42. * Create the aggregate stream that will be used to upload the POST data 
  43. */ 
  44. protected function createStream(array $elements) 
  45. $stream = new AppendStream(); 
  46.  
  47. foreach ($elements as $element) { 
  48. $this->addElement($stream, $element); 
  49.  
  50. // Add the trailing boundary with CRLF 
  51. $stream->addStream(stream_for("--{$this->boundary}--\r\n")); 
  52.  
  53. return $stream; 
  54.  
  55. private function addElement(AppendStream $stream, array $element) 
  56. foreach (['contents', 'name'] as $key) { 
  57. if (!array_key_exists($key, $element)) { 
  58. throw new \InvalidArgumentException("A '{$key}' key is required"); 
  59.  
  60. $element['contents'] = stream_for($element['contents']); 
  61.  
  62. if (empty($element['filename'])) { 
  63. $uri = $element['contents']->getMetadata('uri'); 
  64. if (substr($uri, 0, 6) !== 'php://') { 
  65. $element['filename'] = $uri; 
  66.  
  67. list($body, $headers) = $this->createElement( 
  68. $element['name'],  
  69. $element['contents'],  
  70. isset($element['filename']) ? $element['filename'] : null,  
  71. isset($element['headers']) ? $element['headers'] : [] 
  72. ); 
  73.  
  74. $stream->addStream(stream_for($this->getHeaders($headers))); 
  75. $stream->addStream($body); 
  76. $stream->addStream(stream_for("\r\n")); 
  77.  
  78. /** 
  79. * @return array 
  80. */ 
  81. private function createElement($name, $stream, $filename, array $headers) 
  82. // Set a default content-disposition header if one was no provided 
  83. $disposition = $this->getHeader($headers, 'content-disposition'); 
  84. if (!$disposition) { 
  85. $headers['Content-Disposition'] = ($filename === '0' || $filename) 
  86. ? sprintf('form-data; name="%s"; filename="%s"',  
  87. $name,  
  88. basename($filename)) 
  89. : "form-data; name=\"{$name}\""; 
  90.  
  91. // Set a default content-length header if one was no provided 
  92. $length = $this->getHeader($headers, 'content-length'); 
  93. if (!$length) { 
  94. if ($length = $stream->getSize()) { 
  95. $headers['Content-Length'] = (string) $length; 
  96.  
  97. // Set a default Content-Type if one was not supplied 
  98. $type = $this->getHeader($headers, 'content-type'); 
  99. if (!$type && ($filename === '0' || $filename)) { 
  100. if ($type = mimetype_from_filename($filename)) { 
  101. $headers['Content-Type'] = $type; 
  102.  
  103. return [$stream, $headers]; 
  104.  
  105. private function getHeader(array $headers, $key) 
  106. $lowercaseHeader = strtolower($key); 
  107. foreach ($headers as $k => $v) { 
  108. if (strtolower($k) === $lowercaseHeader) { 
  109. return $v; 
  110.  
  111. return null;