PluginProbe
WP Database Backup – Unlimited Database & Files Backup by Backup for WP / 7.13
WP Database Backup – Unlimited Database & Files Backup by Backup for WP v7.13
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 7.13, at includes/admin/Destination/Google/google-api-php-client/src/service/Google_MediaFileUpload.php

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