RequestBodyMultipart   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 132
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 132
ccs 40
cts 40
cp 1
rs 10
c 0
b 0
f 0
wmc 11

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getFileHeaders() 0 3 1
A getBody() 0 19 3
A getBoundary() 0 3 1
A getParamString() 0 7 1
A getNestedParams() 0 12 2
A __construct() 0 5 2
A getFileString() 0 9 1
1
<?php
2
/**
3
 * Copyright 2017 Facebook, Inc.
4
 *
5
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
6
 * use, copy, modify, and distribute this software in source code or binary
7
 * form for use in connection with the web services and APIs provided by
8
 * Facebook.
9
 *
10
 * As with any software that integrates with the Facebook platform, your use
11
 * of this software is subject to the Facebook Developer Principles and
12
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
13
 * shall be included in all copies or substantial portions of the software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * DEALINGS IN THE SOFTWARE.
22
 */
23
namespace Facebook\Http;
24
25
use Facebook\FileUpload\File;
26
27
/**
28
 * Some things copied from Guzzle.
29
 *
30
 * @package Facebook
31
 *
32
 * @see https://github.com/guzzle/guzzle/blob/master/src/Post/MultipartBody.php
33
 */
34
class RequestBodyMultipart implements RequestBodyInterface
35
{
36
    /**
37
     * @var string the boundary
38
     */
39
    private $boundary;
40
41
    /**
42
     * @var array the parameters to send with this request
43
     */
44
    private $params;
45
46
    /**
47
     * @var array the files to send with this request
48
     */
49
    private $files = [];
50
51
    /**
52
     * @param array  $params   the parameters to send with this request
53
     * @param array  $files    the files to send with this request
54
     * @param string $boundary provide a specific boundary
55
     */
56 9
    public function __construct(array $params = [], array $files = [], $boundary = null)
57
    {
58 9
        $this->params = $params;
59 9
        $this->files = $files;
60 9
        $this->boundary = $boundary ?: uniqid();
61 9
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66 9
    public function getBody()
67
    {
68 9
        $body = '';
69
70
        // Compile normal params
71 9
        $params = $this->getNestedParams($this->params);
72 9
        foreach ($params as $k => $v) {
73 9
            $body .= $this->getParamString($k, $v);
74
        }
75
76
        // Compile files
77 9
        foreach ($this->files as $k => $v) {
78 7
            $body .= $this->getFileString($k, $v);
79
        }
80
81
        // Peace out
82 9
        $body .= "--{$this->boundary}--\r\n";
83
84 9
        return $body;
85
    }
86
87
    /**
88
     * Get the boundary.
89
     *
90
     * @return string
91
     */
92 6
    public function getBoundary()
93
    {
94 6
        return $this->boundary;
95
    }
96
97
    /**
98
     * Get the string needed to transfer a file.
99
     *
100
     * @param string $name
101
     * @param File   $file
102
     *
103
     * @return string
104
     */
105 7
    private function getFileString($name, File $file)
106
    {
107 7
        return sprintf(
108 7
            "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"%s\r\n\r\n%s\r\n",
109 7
            $this->boundary,
110 7
            $name,
111 7
            $file->getFileName(),
112 7
            $this->getFileHeaders($file),
113 7
            $file->getContents()
114
        );
115
    }
116
117
    /**
118
     * Get the string needed to transfer a POST field.
119
     *
120
     * @param string $name
121
     * @param string $value
122
     *
123
     * @return string
124
     */
125 9
    private function getParamString($name, $value)
126
    {
127 9
        return sprintf(
128 9
            "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n",
129 9
            $this->boundary,
130 9
            $name,
131 9
            $value
132
        );
133
    }
134
135
    /**
136
     * Returns the params as an array of nested params.
137
     *
138
     * @param array $params
139
     *
140
     * @return array
141
     */
142 9
    private function getNestedParams(array $params)
143
    {
144 9
        $query = http_build_query($params, null, '&');
145 9
        $params = explode('&', $query);
146 9
        $result = [];
147
148 9
        foreach ($params as $param) {
149 9
            list($key, $value) = explode('=', $param, 2);
150 9
            $result[urldecode($key)] = urldecode($value);
151
        }
152
153 9
        return $result;
154
    }
155
156
    /**
157
     * Get the headers needed before transferring the content of a POST file.
158
     *
159
     * @param File $file
160
     *
161
     * @return string
162
     */
163 7
    protected function getFileHeaders(File $file)
164
    {
165 7
        return "\r\nContent-Type: {$file->getMimetype()}";
166
    }
167
}
168