Google_Http_MediaFileUpload

The WordPress Core Google Http MediaFileUpload class.

Defined (1)

The class is defined in the following location(s).

/tools/src/Google/Http/MediaFileUpload.php  
  1. class Google_Http_MediaFileUpload 
  2.  
  3. const UPLOAD_MEDIA_TYPE = 'media'; 
  4.  
  5. const UPLOAD_MULTIPART_TYPE = 'multipart'; 
  6.  
  7. const UPLOAD_RESUMABLE_TYPE = 'resumable'; 
  8.  
  9. /** 
  10. * @var string $mimeType 
  11. */ 
  12. private $mimeType; 
  13.  
  14. /** 
  15. * @var string $data 
  16. */ 
  17. private $data; 
  18.  
  19. /** 
  20. * @var bool $resumable 
  21. */ 
  22. private $resumable; 
  23.  
  24. /** 
  25. * @var int $chunkSize 
  26. */ 
  27. private $chunkSize; 
  28.  
  29. /** 
  30. * @var int $size 
  31. */ 
  32. private $size; 
  33.  
  34. /** 
  35. * @var string $resumeUri 
  36. */ 
  37. private $resumeUri; 
  38.  
  39. /** 
  40. * @var int $progress 
  41. */ 
  42. private $progress; 
  43.  
  44. /** 
  45. * @var Google_Client 
  46. */ 
  47. private $client; 
  48.  
  49. /** 
  50. * @var Google_Http_Request 
  51. */ 
  52. private $request; 
  53.  
  54. /** 
  55. * @var string 
  56. */ 
  57. private $boundary; 
  58.  
  59. /** 
  60. * Result code from last HTTP call 
  61. * @var int 
  62. */ 
  63. private $httpResultCode; 
  64.  
  65. /** 
  66. * @param $mimeType string  
  67. * @param $data string 
  68. * The bytes you want to upload. 
  69. * @param $resumable bool  
  70. * @param bool $chunkSize 
  71. * File will be uploaded in chunks of this many bytes. 
  72. * only used if resumable=True 
  73. */ 
  74. public function __construct(Google_Client $client, Google_Http_Request $request, $mimeType, $data, $resumable = false, $chunkSize = false, $boundary = false) 
  75. $this->client = $client; 
  76. $this->request = $request; 
  77. $this->mimeType = $mimeType; 
  78. $this->data = $data; 
  79. $this->size = strlen($this->data); 
  80. $this->resumable = $resumable; 
  81. if (! $chunkSize) { 
  82. $chunkSize = 256 * 1024; 
  83. $this->chunkSize = $chunkSize; 
  84. $this->progress = 0; 
  85. $this->boundary = $boundary; 
  86. // Process Media Request 
  87. $this->process(); 
  88.  
  89. /** 
  90. * Set the size of the file that is being uploaded. 
  91. * @param $size - 
  92. * int file size in bytes 
  93. */ 
  94. public function setFileSize($size) 
  95. $this->size = $size; 
  96.  
  97. /** 
  98. * Return the progress on the upload 
  99. * @return int progress in bytes uploaded. 
  100. */ 
  101. public function getProgress() 
  102. return $this->progress; 
  103.  
  104. /** 
  105. * Return the HTTP result code from the last call made. 
  106. * @return int code 
  107. */ 
  108. public function getHttpResultCode() 
  109. return $this->httpResultCode; 
  110.  
  111. /** 
  112. * Send the next part of the file to upload. 
  113. * @param 
  114. * [$chunk] the next set of bytes to send. If false will used $data passed 
  115. * at construct time. 
  116. */ 
  117. public function nextChunk($chunk = false) 
  118. if (false == $this->resumeUri) { 
  119. $this->resumeUri = $this->getResumeUri(); 
  120. if (false == $chunk) { 
  121. $chunk = substr($this->data, $this->progress, $this->chunkSize); 
  122. $lastBytePos = $this->progress + strlen($chunk) - 1; 
  123. $headers = array( 
  124. 'content-range' => "bytes $this->progress-$lastBytePos/$this->size",  
  125. 'content-type' => $this->request->getRequestHeader('content-type'),  
  126. 'content-length' => $this->chunkSize,  
  127. 'expect' => '' 
  128. ); 
  129. $httpRequest = new Google_Http_Request($this->resumeUri, 'PUT', $headers, $chunk); 
  130. if ($this->client->getClassConfig("Google_Http_Request", "enable_gzip_for_uploads")) { 
  131. $httpRequest->enableGzip(); 
  132. } else { 
  133. $httpRequest->disableGzip(); 
  134. $response = $this->client->getIo()->makeRequest($httpRequest); 
  135. $response->setExpectedClass($this->request->getExpectedClass()); 
  136. $code = $response->getResponseHttpCode(); 
  137. $this->httpResultCode = $code; 
  138. if (308 == $code) { 
  139. // Track the amount uploaded. 
  140. $range = explode('-', $response->getResponseHeader('range')); 
  141. $this->progress = $range[1] + 1; 
  142. // Allow for changing upload URLs. 
  143. $location = $response->getResponseHeader('location'); 
  144. if ($location) { 
  145. $this->resumeUri = $location; 
  146. // No problems, but upload not complete. 
  147. return false; 
  148. } else { 
  149. return Google_Http_REST::decodeHttpResponse($response, $this->client); 
  150.  
  151. /** 
  152. * @param 
  153. * $meta 
  154. * @param 
  155. * $params 
  156. * @return array|bool @visible for testing 
  157. */ 
  158. private function process() 
  159. $postBody = false; 
  160. $contentType = false; 
  161. $meta = $this->request->getPostBody(); 
  162. $meta = is_string($meta) ? json_decode($meta, true) : $meta; 
  163. $uploadType = $this->getUploadType($meta); 
  164. $this->request->setQueryParam('uploadType', $uploadType); 
  165. $this->transformToUploadUrl(); 
  166. $mimeType = $this->mimeType ? $this->mimeType : $this->request->getRequestHeader('content-type'); 
  167. if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) { 
  168. $contentType = $mimeType; 
  169. $postBody = is_string($meta) ? $meta : json_encode($meta); 
  170. } else  
  171. if (self::UPLOAD_MEDIA_TYPE == $uploadType) { 
  172. $contentType = $mimeType; 
  173. $postBody = $this->data; 
  174. } else  
  175. if (self::UPLOAD_MULTIPART_TYPE == $uploadType) { 
  176. // This is a multipart/related upload. 
  177. $boundary = $this->boundary ? $this->boundary : mt_rand(); 
  178. $boundary = str_replace('"', '', $boundary); 
  179. $contentType = 'multipart/related; boundary=' . $boundary; 
  180. $related = "--$boundary\r\n"; 
  181. $related .= "Content-Type: application/json; charset=UTF-8\r\n"; 
  182. $related .= "\r\n" . json_encode($meta) . "\r\n"; 
  183. $related .= "--$boundary\r\n"; 
  184. $related .= "Content-Type: $mimeType\r\n"; 
  185. $related .= "Content-Transfer-Encoding: base64\r\n"; 
  186. $related .= "\r\n" . base64_encode($this->data) . "\r\n"; 
  187. $related .= "--$boundary--"; 
  188. $postBody = $related; 
  189. $this->request->setPostBody($postBody); 
  190. if (isset($contentType) && $contentType) { 
  191. $contentTypeHeader['content-type'] = $contentType; 
  192. $this->request->setRequestHeaders($contentTypeHeader); 
  193.  
  194. private function transformToUploadUrl() 
  195. $base = $this->request->getBaseComponent(); 
  196. $this->request->setBaseComponent($base . '/upload'); 
  197.  
  198. /** 
  199. * Valid upload types: 
  200. * - resumable (UPLOAD_RESUMABLE_TYPE) 
  201. * - media (UPLOAD_MEDIA_TYPE) 
  202. * - multipart (UPLOAD_MULTIPART_TYPE) 
  203. * @param 
  204. * $meta 
  205. * @return string @visible for testing 
  206. */ 
  207. public function getUploadType($meta) 
  208. if ($this->resumable) { 
  209. return self::UPLOAD_RESUMABLE_TYPE; 
  210. if (false == $meta && $this->data) { 
  211. return self::UPLOAD_MEDIA_TYPE; 
  212. return self::UPLOAD_MULTIPART_TYPE; 
  213.  
  214. private function getResumeUri() 
  215. $result = null; 
  216. $body = $this->request->getPostBody(); 
  217. if ($body) { 
  218. $headers = array( 
  219. 'content-type' => 'application/json; charset=UTF-8',  
  220. 'content-length' => Google_Utils::getStrLen($body),  
  221. 'x-upload-content-type' => $this->mimeType,  
  222. 'x-upload-content-length' => $this->size,  
  223. 'expect' => '' 
  224. ); 
  225. $this->request->setRequestHeaders($headers); 
  226. $response = $this->client->getIo()->makeRequest($this->request); 
  227. $location = $response->getResponseHeader('location'); 
  228. $code = $response->getResponseHttpCode(); 
  229. if (200 == $code && true == $location) { 
  230. return $location; 
  231. $message = $code; 
  232. $body = @json_decode($response->getResponseBody()); 
  233. if (! empty($body->error->errors)) { 
  234. $message .= ': '; 
  235. foreach ($body->error->errors as $error) { 
  236. $message .= "{$error->domain}, {$error->message};"; 
  237. $message = rtrim($message, ';'); 
  238. $error = "Failed to start the resumable upload (HTTP {$message})"; 
  239. $this->client->getLogger()->error($error); 
  240. throw new Google_Exception($error);