[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
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 require_once 'Google/Client.php'; 19 require_once 'Google/Exception.php'; 20 require_once 'Google/Http/Request.php'; 21 require_once 'Google/Http/REST.php'; 22 require_once 'Google/Utils.php'; 23 24 /** 25 * @author Chirag Shah <[email protected]> 26 * 27 */ 28 class Google_Http_MediaFileUpload 29 { 30 const UPLOAD_MEDIA_TYPE = 'media'; 31 const UPLOAD_MULTIPART_TYPE = 'multipart'; 32 const UPLOAD_RESUMABLE_TYPE = 'resumable'; 33 34 /** @var string $mimeType */ 35 private $mimeType; 36 37 /** @var string $data */ 38 private $data; 39 40 /** @var bool $resumable */ 41 private $resumable; 42 43 /** @var int $chunkSize */ 44 private $chunkSize; 45 46 /** @var int $size */ 47 private $size; 48 49 /** @var string $resumeUri */ 50 private $resumeUri; 51 52 /** @var int $progress */ 53 private $progress; 54 55 /** @var Google_Client */ 56 private $client; 57 58 /** @var Google_Http_Request */ 59 private $request; 60 61 /** @var string */ 62 private $boundary; 63 64 /** 65 * Result code from last HTTP call 66 * @var int 67 */ 68 private $httpResultCode; 69 70 /** 71 * @param $mimeType string 72 * @param $data string The bytes you want to upload. 73 * @param $resumable bool 74 * @param bool $chunkSize File will be uploaded in chunks of this many bytes. 75 * only used if resumable=True 76 */ 77 public function __construct( 78 Google_Client $client, 79 Google_Http_Request $request, 80 $mimeType, 81 $data, 82 $resumable = false, 83 $chunkSize = false, 84 $boundary = false 85 ) { 86 $this->client = $client; 87 $this->request = $request; 88 $this->mimeType = $mimeType; 89 $this->data = $data; 90 $this->size = strlen($this->data); 91 $this->resumable = $resumable; 92 if (!$chunkSize) { 93 $chunkSize = 256 * 1024; 94 } 95 $this->chunkSize = $chunkSize; 96 $this->progress = 0; 97 $this->boundary = $boundary; 98 99 // Process Media Request 100 $this->process(); 101 } 102 103 /** 104 * Set the size of the file that is being uploaded. 105 * @param $size - int file size in bytes 106 */ 107 public function setFileSize($size) 108 { 109 $this->size = $size; 110 } 111 112 /** 113 * Return the progress on the upload 114 * @return int progress in bytes uploaded. 115 */ 116 public function getProgress() 117 { 118 return $this->progress; 119 } 120 121 /** 122 * Return the HTTP result code from the last call made. 123 * @return int code 124 */ 125 public function getHttpResultCode() 126 { 127 return $this->httpResultCode; 128 } 129 130 /** 131 * Send the next part of the file to upload. 132 * @param [$chunk] the next set of bytes to send. If false will used $data passed 133 * at construct time. 134 */ 135 public function nextChunk($chunk = false) 136 { 137 if (false == $this->resumeUri) { 138 $this->resumeUri = $this->getResumeUri(); 139 } 140 141 if (false == $chunk) { 142 $chunk = substr($this->data, $this->progress, $this->chunkSize); 143 } 144 145 $lastBytePos = $this->progress + strlen($chunk) - 1; 146 $headers = array( 147 'content-range' => "bytes $this->progress-$lastBytePos/$this->size", 148 'content-type' => $this->request->getRequestHeader('content-type'), 149 'content-length' => $this->chunkSize, 150 'expect' => '', 151 ); 152 153 $httpRequest = new Google_Http_Request( 154 $this->resumeUri, 155 'PUT', 156 $headers, 157 $chunk 158 ); 159 160 if ($this->client->getClassConfig("Google_Http_Request", "enable_gzip_for_uploads")) { 161 $httpRequest->enableGzip(); 162 } else { 163 $httpRequest->disableGzip(); 164 } 165 166 $response = $this->client->getIo()->makeRequest($httpRequest); 167 $response->setExpectedClass($this->request->getExpectedClass()); 168 $code = $response->getResponseHttpCode(); 169 $this->httpResultCode = $code; 170 171 if (308 == $code) { 172 // Track the amount uploaded. 173 $range = explode('-', $response->getResponseHeader('range')); 174 $this->progress = $range[1] + 1; 175 176 // Allow for changing upload URLs. 177 $location = $response->getResponseHeader('location'); 178 if ($location) { 179 $this->resumeUri = $location; 180 } 181 182 // No problems, but upload not complete. 183 return false; 184 } else { 185 return Google_Http_REST::decodeHttpResponse($response); 186 } 187 } 188 189 /** 190 * @param $meta 191 * @param $params 192 * @return array|bool 193 * @visible for testing 194 */ 195 private function process() 196 { 197 $postBody = false; 198 $contentType = false; 199 200 $meta = $this->request->getPostBody(); 201 $meta = is_string($meta) ? json_decode($meta, true) : $meta; 202 203 $uploadType = $this->getUploadType($meta); 204 $this->request->setQueryParam('uploadType', $uploadType); 205 $this->transformToUploadUrl(); 206 $mimeType = $this->mimeType ? 207 $this->mimeType : 208 $this->request->getRequestHeader('content-type'); 209 210 if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) { 211 $contentType = $mimeType; 212 $postBody = is_string($meta) ? $meta : json_encode($meta); 213 } else if (self::UPLOAD_MEDIA_TYPE == $uploadType) { 214 $contentType = $mimeType; 215 $postBody = $this->data; 216 } else if (self::UPLOAD_MULTIPART_TYPE == $uploadType) { 217 // This is a multipart/related upload. 218 $boundary = $this->boundary ? $this->boundary : mt_rand(); 219 $boundary = str_replace('"', '', $boundary); 220 $contentType = 'multipart/related; boundary=' . $boundary; 221 $related = "--$boundary\r\n"; 222 $related .= "Content-Type: application/json; charset=UTF-8\r\n"; 223 $related .= "\r\n" . json_encode($meta) . "\r\n"; 224 $related .= "--$boundary\r\n"; 225 $related .= "Content-Type: $mimeType\r\n"; 226 $related .= "Content-Transfer-Encoding: base64\r\n"; 227 $related .= "\r\n" . base64_encode($this->data) . "\r\n"; 228 $related .= "--$boundary--"; 229 $postBody = $related; 230 } 231 232 $this->request->setPostBody($postBody); 233 234 if (isset($contentType) && $contentType) { 235 $contentTypeHeader['content-type'] = $contentType; 236 $this->request->setRequestHeaders($contentTypeHeader); 237 } 238 } 239 240 private function transformToUploadUrl() 241 { 242 $base = $this->request->getBaseComponent(); 243 $this->request->setBaseComponent($base . '/upload'); 244 } 245 246 /** 247 * Valid upload types: 248 * - resumable (UPLOAD_RESUMABLE_TYPE) 249 * - media (UPLOAD_MEDIA_TYPE) 250 * - multipart (UPLOAD_MULTIPART_TYPE) 251 * @param $meta 252 * @return string 253 * @visible for testing 254 */ 255 public function getUploadType($meta) 256 { 257 if ($this->resumable) { 258 return self::UPLOAD_RESUMABLE_TYPE; 259 } 260 261 if (false == $meta && $this->data) { 262 return self::UPLOAD_MEDIA_TYPE; 263 } 264 265 return self::UPLOAD_MULTIPART_TYPE; 266 } 267 268 private function getResumeUri() 269 { 270 $result = null; 271 $body = $this->request->getPostBody(); 272 if ($body) { 273 $headers = array( 274 'content-type' => 'application/json; charset=UTF-8', 275 'content-length' => Google_Utils::getStrLen($body), 276 'x-upload-content-type' => $this->mimeType, 277 'x-upload-content-length' => $this->size, 278 'expect' => '', 279 ); 280 $this->request->setRequestHeaders($headers); 281 } 282 283 $response = $this->client->getIo()->makeRequest($this->request); 284 $location = $response->getResponseHeader('location'); 285 $code = $response->getResponseHttpCode(); 286 287 if (200 == $code && true == $location) { 288 return $location; 289 } 290 throw new Google_Exception("Failed to start the resumable upload"); 291 } 292 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |