PageRenderTime 39ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/google-analytics-dashboard-for-wp/tools/src/Google/Http/MediaFileUpload.php

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