PluginProbe
WP Database Backup – Unlimited Database & Files Backup by Backup for WP / 6.11
WP Database Backup – Unlimited Database & Files Backup by Backup for WP v6.11
7.13 7.12 trunk 1.1 2.1.1 5.9 6.0 6.1 6.10 6.11 6.12 6.12.1 6.2 6.3 6.4 6.5 6.5.1 6.6 6.7 6.8 6.9 7.0 7.0.1 7.1 7.10 All 34 releases
wp-database-backup / includes / admin / Destination / Google / google-api-php-client / src / service / Google_MediaFileUpload.php

Google_MediaFileUpload.php in WP Database Backup – Unlimited Database & Files Backup by Backup for WP 6.11, at includes/admin/Destination/Google/google-api-php-client/src/service/Google_MediaFileUpload.php

262 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Copyright 2012 Google Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /**
19 * @author Chirag Shah <chirags@google.com>
20 *
21 */
22 class Google_MediaFileUpload {
23 const UPLOAD_MEDIA_TYPE = 'media';
24 const UPLOAD_MULTIPART_TYPE = 'multipart';
25 const UPLOAD_RESUMABLE_TYPE = 'resumable';
26
27 /** @var string $mimeType */
28 public $mimeType;
29
30 /** @var string $data */
31 public $data;
32
33 /** @var bool $resumable */
34 public $resumable;
35
36 /** @var int $chunkSize */
37 public $chunkSize;
38
39 /** @var int $size */
40 public $size;
41
42 /** @var string $resumeUri */
43 public $resumeUri;
44
45 /** @var int $progress */
46 public $progress;
47
48 /**
49 * @param $mimeType string
50 * @param $data string The bytes you want to upload.
51 * @param $resumable bool
52 * @param bool $chunkSize File will be uploaded in chunks of this many bytes.
53 * only used if resumable=True
54 */
55 public function __construct($mimeType, $data, $resumable=false, $chunkSize=false) {
56 $this->mimeType = $mimeType;
57 $this->data = $data;
58 $this->size = @strlen($this->data);
59 $this->resumable = $resumable;
60 if(!$chunkSize) {
61 $chunkSize = 256 * 1024;
62 }
63 $this->chunkSize = $chunkSize;
64 $this->progress = 0;
65 }
66
67 public function setFileSize($size) {
68 $this->size = $size;
69 }
70
71 /**
72 * @static
73 * @param $meta
74 * @param $params
75 * @return array|bool
76 */
77 public static function process($meta, &$params) {
78 $payload = array();
79 $meta = is_string($meta) ? json_decode($meta, true) : $meta;
80 $uploadType = self::getUploadType($meta, $payload, $params);
81 if (!$uploadType) {
82 // Process as a normal API request.
83 return false;
84 }
85
86 // Process as a media upload request.
87 $params['uploadType'] = array(
88 'type' => 'string',
89 'location' => 'query',
90 'value' => $uploadType,
91 );
92
93 $mimeType = isset($params['mimeType'])
94 ? $params['mimeType']['value']
95 : false;
96 unset($params['mimeType']);
97
98 if (!$mimeType) {
99 $mimeType = $payload['content-type'];
100 }
101
102 if (isset($params['file'])) {
103 // This is a standard file upload with curl.
104 $file = $params['file']['value'];
105 unset($params['file']);
106 return self::processFileUpload($file, $mimeType);
107 }
108
109 $data = isset($params['data'])
110 ? $params['data']['value']
111 : false;
112 unset($params['data']);
113
114 if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) {
115 $payload['content-type'] = $mimeType;
116 $payload['postBody'] = is_string($meta) ? $meta : wp_json_encode($meta);
117
118 } elseif (self::UPLOAD_MEDIA_TYPE == $uploadType) {
119 // This is a simple media upload.
120 $payload['content-type'] = $mimeType;
121 $payload['postBody'] = $data;
122 }
123
124 elseif (self::UPLOAD_MULTIPART_TYPE == $uploadType) {
125 // This is a multipart/related upload.
126 $boundary = isset($params['boundary']['value']) ? $params['boundary']['value'] : mt_rand();
127 $boundary = str_replace('"', '', $boundary);
128 $payload['content-type'] = 'multipart/related; boundary=' . $boundary;
129 $related = "--$boundary\r\n";
130 $related .= "Content-Type: application/json; charset=UTF-8\r\n";
131 $related .= "\r\n" . wp_json_encode($meta) . "\r\n";
132 $related .= "--$boundary\r\n";
133 $related .= "Content-Type: $mimeType\r\n";
134 $related .= "Content-Transfer-Encoding: base64\r\n";
135 $related .= "\r\n" . base64_encode($data) . "\r\n";
136 $related .= "--$boundary--";
137 $payload['postBody'] = $related;
138 }
139
140 return $payload;
141 }
142
143 /**
144 * Prepares a standard file upload via cURL.
145 * @param $file
146 * @param $mime
147 * @return array Includes the processed file name.
148 * @visible For testing.
149 */
150 public static function processFileUpload($file, $mime) {
151 if (!$file) return array();
152 if (substr($file, 0, 1) != '@') {
153 $file = '@' . $file;
154 }
155
156 // This is a standard file upload with curl.
157 $params = array('postBody' => array('file' => $file));
158 if ($mime) {
159 $params['content-type'] = $mime;
160 }
161
162 return $params;
163 }
164
165 /**
166 * Valid upload types:
167 * - resumable (UPLOAD_RESUMABLE_TYPE)
168 * - media (UPLOAD_MEDIA_TYPE)
169 * - multipart (UPLOAD_MULTIPART_TYPE)
170 * - none (false)
171 * @param $meta
172 * @param $payload
173 * @param $params
174 * @return bool|string
175 */
176 public static function getUploadType($meta, &$payload, &$params) {
177 if (isset($params['mediaUpload'])
178 && get_class($params['mediaUpload']['value']) == 'Google_MediaFileUpload') {
179 $upload = $params['mediaUpload']['value'];
180 unset($params['mediaUpload']);
181 $payload['content-type'] = $upload->mimeType;
182 if (isset($upload->resumable) && $upload->resumable) {
183 return self::UPLOAD_RESUMABLE_TYPE;
184 }
185 }
186
187 // Allow the developer to override the upload type.
188 if (isset($params['uploadType'])) {
189 return $params['uploadType']['value'];
190 }
191
192 $data = isset($params['data']['value'])
193 ? $params['data']['value'] : false;
194
195 if (false == $data && false == isset($params['file'])) {
196 // No upload data available.
197 return false;
198 }
199
200 if (isset($params['file'])) {
201 return self::UPLOAD_MEDIA_TYPE;
202 }
203
204 if (false == $meta) {
205 return self::UPLOAD_MEDIA_TYPE;
206 }
207
208 return self::UPLOAD_MULTIPART_TYPE;
209 }
210
211
212 public function nextChunk(Google_HttpRequest $req, $chunk=false) {
213 if (false == $this->resumeUri) {
214 $this->resumeUri = $this->getResumeUri($req);
215 }
216
217 if (false == $chunk) {
218 $chunk = substr($this->data, $this->progress, $this->chunkSize);
219 }
220
221 $lastBytePos = $this->progress + strlen($chunk) - 1;
222 $headers = array(
223 'content-range' => "bytes $this->progress-$lastBytePos/$this->size",
224 'content-type' => $req->getRequestHeader('content-type'),
225 'content-length' => $this->chunkSize,
226 'expect' => '',
227 );
228
229 $httpRequest = new Google_HttpRequest($this->resumeUri, 'PUT', $headers, $chunk);
230 $response = Google_Client::$io->authenticatedRequest($httpRequest);
231 $code = $response->getResponseHttpCode();
232 if (308 == $code) {
233 $range = explode('-', $response->getResponseHeader('range'));
234 $this->progress = $range[1] + 1;
235 return false;
236 } else {
237 return Google_REST::decodeHttpResponse($response);
238 }
239 }
240
241 private function getResumeUri(Google_HttpRequest $httpRequest) {
242 $result = null;
243 $body = $httpRequest->getPostBody();
244 if ($body) {
245 $httpRequest->setRequestHeaders(array(
246 'content-type' => 'application/json; charset=UTF-8',
247 'content-length' => Google_Utils::getStrLen($body),
248 'x-upload-content-type' => $this->mimeType,
249 'x-upload-content-length' => $this->size,
250 'expect' => '',
251 ));
252 }
253
254 $response = Google_Client::$io->makeRequest($httpRequest);
255 $location = $response->getResponseHeader('location');
256 $code = $response->getResponseHttpCode();
257 if (200 == $code && true == $location) {
258 return $location;
259 }
260 throw new Google_Exception("Failed to start the resumable upload");
261 }
262 }