PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.6
Booking for Appointments and Events Calendar – Amelia v2.4.6
2.4.7 2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / vendor / guzzlehttp / psr7 / src / MultipartStream.php
ameliabooking / vendor / guzzlehttp / psr7 / src Last commit date
Exception 7 months ago AppendStream.php 7 months ago BufferStream.php 7 months ago CachingStream.php 7 months ago DroppingStream.php 7 months ago FnStream.php 7 months ago Header.php 7 months ago HttpFactory.php 7 months ago InflateStream.php 7 months ago LazyOpenStream.php 7 months ago LimitStream.php 7 months ago Message.php 7 months ago MessageTrait.php 7 months ago MimeType.php 7 months ago MultipartStream.php 7 months ago NoSeekStream.php 7 months ago PumpStream.php 7 months ago Query.php 7 months ago Request.php 7 months ago Response.php 7 months ago Rfc7230.php 7 months ago ServerRequest.php 7 months ago Stream.php 7 months ago StreamDecoratorTrait.php 7 months ago StreamWrapper.php 7 months ago UploadedFile.php 7 months ago Uri.php 7 months ago UriComparator.php 7 months ago UriNormalizer.php 7 months ago UriResolver.php 7 months ago Utils.php 7 months ago
MultipartStream.php
166 lines
1 <?php
2
3 declare(strict_types=1);
4
5 namespace AmeliaVendor\GuzzleHttp\Psr7;
6
7 use AmeliaVendor\Psr\Http\Message\StreamInterface;
8
9 /**
10 * Stream that when read returns bytes for a streaming multipart or
11 * multipart/form-data stream.
12 */
13 final class MultipartStream implements StreamInterface
14 {
15 use StreamDecoratorTrait;
16
17 /** @var string */
18 private $boundary;
19
20 /** @var StreamInterface */
21 private $stream;
22
23 /**
24 * @param array $elements Array of associative arrays, each containing a
25 * required "name" key mapping to the form field,
26 * name, a required "contents" key mapping to a
27 * StreamInterface/resource/string, an optional
28 * "headers" associative array of custom headers,
29 * and an optional "filename" key mapping to a
30 * string to send as the filename in the part.
31 * @param string $boundary You can optionally provide a specific boundary
32 *
33 * @throws \InvalidArgumentException
34 */
35 public function __construct(array $elements = [], ?string $boundary = null)
36 {
37 $this->boundary = $boundary ?: bin2hex(random_bytes(20));
38 $this->stream = $this->createStream($elements);
39 }
40
41 public function getBoundary(): string
42 {
43 return $this->boundary;
44 }
45
46 public function isWritable(): bool
47 {
48 return false;
49 }
50
51 /**
52 * Get the headers needed before transferring the content of a POST file
53 *
54 * @param string[] $headers
55 */
56 private function getHeaders(array $headers): string
57 {
58 $str = '';
59 foreach ($headers as $key => $value) {
60 $str .= "{$key}: {$value}\r\n";
61 }
62
63 return "--{$this->boundary}\r\n".trim($str)."\r\n\r\n";
64 }
65
66 /**
67 * Create the aggregate stream that will be used to upload the POST data
68 */
69 protected function createStream(array $elements = []): StreamInterface
70 {
71 $stream = new AppendStream();
72
73 foreach ($elements as $element) {
74 if (!is_array($element)) {
75 throw new \UnexpectedValueException('An array is expected');
76 }
77 $this->addElement($stream, $element);
78 }
79
80 // Add the trailing boundary with CRLF
81 $stream->addStream(Utils::streamFor("--{$this->boundary}--\r\n"));
82
83 return $stream;
84 }
85
86 private function addElement(AppendStream $stream, array $element): void
87 {
88 foreach (['contents', 'name'] as $key) {
89 if (!array_key_exists($key, $element)) {
90 throw new \InvalidArgumentException("A '{$key}' key is required");
91 }
92 }
93
94 $element['contents'] = Utils::streamFor($element['contents']);
95
96 if (empty($element['filename'])) {
97 $uri = $element['contents']->getMetadata('uri');
98 if ($uri && \is_string($uri) && \substr($uri, 0, 6) !== 'php://' && \substr($uri, 0, 7) !== 'data://') {
99 $element['filename'] = $uri;
100 }
101 }
102
103 [$body, $headers] = $this->createElement(
104 $element['name'],
105 $element['contents'],
106 $element['filename'] ?? null,
107 $element['headers'] ?? []
108 );
109
110 $stream->addStream(Utils::streamFor($this->getHeaders($headers)));
111 $stream->addStream($body);
112 $stream->addStream(Utils::streamFor("\r\n"));
113 }
114
115 /**
116 * @param string[] $headers
117 *
118 * @return array{0: StreamInterface, 1: string[]}
119 */
120 private function createElement(string $name, StreamInterface $stream, ?string $filename, array $headers): array
121 {
122 // Set a default content-disposition header if one was no provided
123 $disposition = self::getHeader($headers, 'content-disposition');
124 if (!$disposition) {
125 $headers['Content-Disposition'] = ($filename === '0' || $filename)
126 ? sprintf(
127 'form-data; name="%s"; filename="%s"',
128 $name,
129 basename($filename)
130 )
131 : "form-data; name=\"{$name}\"";
132 }
133
134 // Set a default content-length header if one was no provided
135 $length = self::getHeader($headers, 'content-length');
136 if (!$length) {
137 if ($length = $stream->getSize()) {
138 $headers['Content-Length'] = (string) $length;
139 }
140 }
141
142 // Set a default Content-Type if one was not supplied
143 $type = self::getHeader($headers, 'content-type');
144 if (!$type && ($filename === '0' || $filename)) {
145 $headers['Content-Type'] = MimeType::fromFilename($filename) ?? 'application/octet-stream';
146 }
147
148 return [$stream, $headers];
149 }
150
151 /**
152 * @param string[] $headers
153 */
154 private static function getHeader(array $headers, string $key): ?string
155 {
156 $lowercaseHeader = strtolower($key);
157 foreach ($headers as $k => $v) {
158 if (strtolower((string) $k) === $lowercaseHeader) {
159 return $v;
160 }
161 }
162
163 return null;
164 }
165 }
166