PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 18.2
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v18.2
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / vendor_prefixed / guzzlehttp / psr7 / src / MultipartStream.php

MultipartStream.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 18.2, at vendor_prefixed/guzzlehttp/psr7/src/MultipartStream.php

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