PageRenderTime 25ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/wordpress-seo/vendor/yoast/api-libs/google/service/Google_MediaFileUpload.php

https://gitlab.com/ngochuynh1991/cuacuon
PHP | 262 lines | 160 code | 37 blank | 65 comment | 37 complexity | 4116ceb1e809eaa5ba3b94416a7cc157 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. /**
  18. * @author Chirag Shah <chirags@google.com>
  19. *
  20. */
  21. class Yoast_Google_MediaFileUpload {
  22. const UPLOAD_MEDIA_TYPE = 'media';
  23. const UPLOAD_MULTIPART_TYPE = 'multipart';
  24. const UPLOAD_RESUMABLE_TYPE = 'resumable';
  25. /** @var string $mimeType */
  26. public $mimeType;
  27. /** @var string $data */
  28. public $data;
  29. /** @var bool $resumable */
  30. public $resumable;
  31. /** @var int $chunkSize */
  32. public $chunkSize;
  33. /** @var int $size */
  34. public $size;
  35. /** @var string $resumeUri */
  36. public $resumeUri;
  37. /** @var int $progress */
  38. public $progress;
  39. /**
  40. * @param $mimeType string
  41. * @param $data string The bytes you want to upload.
  42. * @param $resumable bool
  43. * @param bool $chunkSize File will be uploaded in chunks of this many bytes.
  44. * only used if resumable=True
  45. */
  46. public function __construct($mimeType, $data, $resumable=false, $chunkSize=false) {
  47. $this->mimeType = $mimeType;
  48. $this->data = $data;
  49. $this->size = strlen($this->data);
  50. $this->resumable = $resumable;
  51. if(!$chunkSize) {
  52. $chunkSize = 256 * 1024;
  53. }
  54. $this->chunkSize = $chunkSize;
  55. $this->progress = 0;
  56. }
  57. public function setFileSize($size) {
  58. $this->size = $size;
  59. }
  60. /**
  61. * @static
  62. * @param $meta
  63. * @param $params
  64. * @return array|bool
  65. */
  66. public static function process($meta, &$params) {
  67. $payload = array();
  68. $meta = is_string($meta) ? json_decode($meta, true) : $meta;
  69. $uploadType = self::getUploadType($meta, $payload, $params);
  70. if (!$uploadType) {
  71. // Process as a normal API request.
  72. return false;
  73. }
  74. // Process as a media upload request.
  75. $params['uploadType'] = array(
  76. 'type' => 'string',
  77. 'location' => 'query',
  78. 'value' => $uploadType,
  79. );
  80. $mimeType = isset($params['mimeType'])
  81. ? $params['mimeType']['value']
  82. : false;
  83. unset($params['mimeType']);
  84. if (!$mimeType) {
  85. $mimeType = $payload['content-type'];
  86. }
  87. if (isset($params['file'])) {
  88. // This is a standard file upload with curl.
  89. $file = $params['file']['value'];
  90. unset($params['file']);
  91. return self::processFileUpload($file, $mimeType);
  92. }
  93. $data = isset($params['data'])
  94. ? $params['data']['value']
  95. : false;
  96. unset($params['data']);
  97. if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) {
  98. $payload['content-type'] = $mimeType;
  99. $payload['postBody'] = is_string($meta) ? $meta : json_encode($meta);
  100. } elseif (self::UPLOAD_MEDIA_TYPE == $uploadType) {
  101. // This is a simple media upload.
  102. $payload['content-type'] = $mimeType;
  103. $payload['postBody'] = $data;
  104. }
  105. elseif (self::UPLOAD_MULTIPART_TYPE == $uploadType) {
  106. // This is a multipart/related upload.
  107. $boundary = isset($params['boundary']['value']) ? $params['boundary']['value'] : mt_rand();
  108. $boundary = str_replace('"', '', $boundary);
  109. $payload['content-type'] = 'multipart/related; boundary=' . $boundary;
  110. $related = "--$boundary\r\n";
  111. $related .= "Content-Type: application/json; charset=UTF-8\r\n";
  112. $related .= "\r\n" . json_encode($meta) . "\r\n";
  113. $related .= "--$boundary\r\n";
  114. $related .= "Content-Type: $mimeType\r\n";
  115. $related .= "Content-Transfer-Encoding: base64\r\n";
  116. $related .= "\r\n" . base64_encode($data) . "\r\n";
  117. $related .= "--$boundary--";
  118. $payload['postBody'] = $related;
  119. }
  120. return $payload;
  121. }
  122. /**
  123. * Prepares a standard file upload via cURL.
  124. * @param $file
  125. * @param $mime
  126. * @return array Includes the processed file name.
  127. * @visible For testing.
  128. */
  129. public static function processFileUpload($file, $mime) {
  130. if (!$file) return array();
  131. if (substr($file, 0, 1) != '@') {
  132. $file = '@' . $file;
  133. }
  134. // This is a standard file upload with curl.
  135. $params = array('postBody' => array('file' => $file));
  136. if ($mime) {
  137. $params['content-type'] = $mime;
  138. }
  139. return $params;
  140. }
  141. /**
  142. * Valid upload types:
  143. * - resumable (UPLOAD_RESUMABLE_TYPE)
  144. * - media (UPLOAD_MEDIA_TYPE)
  145. * - multipart (UPLOAD_MULTIPART_TYPE)
  146. * - none (false)
  147. * @param $meta
  148. * @param $payload
  149. * @param $params
  150. * @return bool|string
  151. */
  152. public static function getUploadType($meta, &$payload, &$params) {
  153. if (isset($params['mediaUpload'])
  154. && get_class($params['mediaUpload']['value']) == 'Google_MediaFileUpload') {
  155. $upload = $params['mediaUpload']['value'];
  156. unset($params['mediaUpload']);
  157. $payload['content-type'] = $upload->mimeType;
  158. if (isset($upload->resumable) && $upload->resumable) {
  159. return self::UPLOAD_RESUMABLE_TYPE;
  160. }
  161. }
  162. // Allow the developer to override the upload type.
  163. if (isset($params['uploadType'])) {
  164. return $params['uploadType']['value'];
  165. }
  166. $data = isset($params['data']['value'])
  167. ? $params['data']['value'] : false;
  168. if (false == $data && false == isset($params['file'])) {
  169. // No upload data available.
  170. return false;
  171. }
  172. if (isset($params['file'])) {
  173. return self::UPLOAD_MEDIA_TYPE;
  174. }
  175. if (false == $meta) {
  176. return self::UPLOAD_MEDIA_TYPE;
  177. }
  178. return self::UPLOAD_MULTIPART_TYPE;
  179. }
  180. public function nextChunk(Yoast_Google_HttpRequest $req, $chunk=false) {
  181. if (false == $this->resumeUri) {
  182. $this->resumeUri = $this->getResumeUri($req);
  183. }
  184. if (false == $chunk) {
  185. $chunk = substr($this->data, $this->progress, $this->chunkSize);
  186. }
  187. $lastBytePos = $this->progress + strlen($chunk) - 1;
  188. $headers = array(
  189. 'content-range' => "bytes $this->progress-$lastBytePos/$this->size",
  190. 'content-type' => $req->getRequestHeader('content-type'),
  191. 'content-length' => $this->chunkSize,
  192. 'expect' => '',
  193. );
  194. $httpRequest = new Yoast_Google_HttpRequest($this->resumeUri, 'PUT', $headers, $chunk);
  195. $response = Yoast_Google_Client::$io->authenticatedRequest($httpRequest);
  196. $code = $response->getResponseHttpCode();
  197. if (308 == $code) {
  198. $range = explode('-', $response->getResponseHeader('range'));
  199. $this->progress = $range[1] + 1;
  200. return false;
  201. } else {
  202. return Yoast_Google_REST::decodeHttpResponse($response);
  203. }
  204. }
  205. private function getResumeUri(Yoast_Google_HttpRequest $httpRequest) {
  206. $result = null;
  207. $body = $httpRequest->getPostBody();
  208. if ($body) {
  209. $httpRequest->setRequestHeaders(array(
  210. 'content-type' => 'application/json; charset=UTF-8',
  211. 'content-length' => Yoast_Google_Utils::getStrLen($body),
  212. 'x-upload-content-type' => $this->mimeType,
  213. 'x-upload-content-length' => $this->size,
  214. 'expect' => '',
  215. ));
  216. }
  217. $response = Yoast_Google_Client::$io->makeRequest($httpRequest);
  218. $location = $response->getResponseHeader('location');
  219. $code = $response->getResponseHttpCode();
  220. if (200 == $code && true == $location) {
  221. return $location;
  222. }
  223. throw new Yoast_Google_Exception("Failed to start the resumable upload");
  224. }
  225. }