Google_Http_MediaFileUpload

The SZ - Google Google Http MediaFileUpload class.

Defined (1)

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

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