/wp-content/plugins/google-analytics-for-wordpress/vendor/yoast/api-libs/google/service/Google_MediaFileUpload.php
PHP | 262 lines | 160 code | 37 blank | 65 comment | 37 complexity | 4116ceb1e809eaa5ba3b94416a7cc157 MD5 | raw file
- <?php
- /**
- * Copyright 2012 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /**
- * @author Chirag Shah <chirags@google.com>
- *
- */
- class Yoast_Google_MediaFileUpload {
- const UPLOAD_MEDIA_TYPE = 'media';
- const UPLOAD_MULTIPART_TYPE = 'multipart';
- const UPLOAD_RESUMABLE_TYPE = 'resumable';
- /** @var string $mimeType */
- public $mimeType;
- /** @var string $data */
- public $data;
- /** @var bool $resumable */
- public $resumable;
- /** @var int $chunkSize */
- public $chunkSize;
- /** @var int $size */
- public $size;
- /** @var string $resumeUri */
- public $resumeUri;
- /** @var int $progress */
- public $progress;
- /**
- * @param $mimeType string
- * @param $data string The bytes you want to upload.
- * @param $resumable bool
- * @param bool $chunkSize File will be uploaded in chunks of this many bytes.
- * only used if resumable=True
- */
- public function __construct($mimeType, $data, $resumable=false, $chunkSize=false) {
- $this->mimeType = $mimeType;
- $this->data = $data;
- $this->size = strlen($this->data);
- $this->resumable = $resumable;
- if(!$chunkSize) {
- $chunkSize = 256 * 1024;
- }
- $this->chunkSize = $chunkSize;
- $this->progress = 0;
- }
- public function setFileSize($size) {
- $this->size = $size;
- }
- /**
- * @static
- * @param $meta
- * @param $params
- * @return array|bool
- */
- public static function process($meta, &$params) {
- $payload = array();
- $meta = is_string($meta) ? json_decode($meta, true) : $meta;
- $uploadType = self::getUploadType($meta, $payload, $params);
- if (!$uploadType) {
- // Process as a normal API request.
- return false;
- }
- // Process as a media upload request.
- $params['uploadType'] = array(
- 'type' => 'string',
- 'location' => 'query',
- 'value' => $uploadType,
- );
- $mimeType = isset($params['mimeType'])
- ? $params['mimeType']['value']
- : false;
- unset($params['mimeType']);
- if (!$mimeType) {
- $mimeType = $payload['content-type'];
- }
- if (isset($params['file'])) {
- // This is a standard file upload with curl.
- $file = $params['file']['value'];
- unset($params['file']);
- return self::processFileUpload($file, $mimeType);
- }
- $data = isset($params['data'])
- ? $params['data']['value']
- : false;
- unset($params['data']);
- if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) {
- $payload['content-type'] = $mimeType;
- $payload['postBody'] = is_string($meta) ? $meta : json_encode($meta);
- } elseif (self::UPLOAD_MEDIA_TYPE == $uploadType) {
- // This is a simple media upload.
- $payload['content-type'] = $mimeType;
- $payload['postBody'] = $data;
- }
- elseif (self::UPLOAD_MULTIPART_TYPE == $uploadType) {
- // This is a multipart/related upload.
- $boundary = isset($params['boundary']['value']) ? $params['boundary']['value'] : mt_rand();
- $boundary = str_replace('"', '', $boundary);
- $payload['content-type'] = 'multipart/related; boundary=' . $boundary;
- $related = "--$boundary\r\n";
- $related .= "Content-Type: application/json; charset=UTF-8\r\n";
- $related .= "\r\n" . json_encode($meta) . "\r\n";
- $related .= "--$boundary\r\n";
- $related .= "Content-Type: $mimeType\r\n";
- $related .= "Content-Transfer-Encoding: base64\r\n";
- $related .= "\r\n" . base64_encode($data) . "\r\n";
- $related .= "--$boundary--";
- $payload['postBody'] = $related;
- }
- return $payload;
- }
- /**
- * Prepares a standard file upload via cURL.
- * @param $file
- * @param $mime
- * @return array Includes the processed file name.
- * @visible For testing.
- */
- public static function processFileUpload($file, $mime) {
- if (!$file) return array();
- if (substr($file, 0, 1) != '@') {
- $file = '@' . $file;
- }
- // This is a standard file upload with curl.
- $params = array('postBody' => array('file' => $file));
- if ($mime) {
- $params['content-type'] = $mime;
- }
- return $params;
- }
- /**
- * Valid upload types:
- * - resumable (UPLOAD_RESUMABLE_TYPE)
- * - media (UPLOAD_MEDIA_TYPE)
- * - multipart (UPLOAD_MULTIPART_TYPE)
- * - none (false)
- * @param $meta
- * @param $payload
- * @param $params
- * @return bool|string
- */
- public static function getUploadType($meta, &$payload, &$params) {
- if (isset($params['mediaUpload'])
- && get_class($params['mediaUpload']['value']) == 'Google_MediaFileUpload') {
- $upload = $params['mediaUpload']['value'];
- unset($params['mediaUpload']);
- $payload['content-type'] = $upload->mimeType;
- if (isset($upload->resumable) && $upload->resumable) {
- return self::UPLOAD_RESUMABLE_TYPE;
- }
- }
- // Allow the developer to override the upload type.
- if (isset($params['uploadType'])) {
- return $params['uploadType']['value'];
- }
- $data = isset($params['data']['value'])
- ? $params['data']['value'] : false;
- if (false == $data && false == isset($params['file'])) {
- // No upload data available.
- return false;
- }
- if (isset($params['file'])) {
- return self::UPLOAD_MEDIA_TYPE;
- }
- if (false == $meta) {
- return self::UPLOAD_MEDIA_TYPE;
- }
- return self::UPLOAD_MULTIPART_TYPE;
- }
- public function nextChunk(Yoast_Google_HttpRequest $req, $chunk=false) {
- if (false == $this->resumeUri) {
- $this->resumeUri = $this->getResumeUri($req);
- }
- if (false == $chunk) {
- $chunk = substr($this->data, $this->progress, $this->chunkSize);
- }
- $lastBytePos = $this->progress + strlen($chunk) - 1;
- $headers = array(
- 'content-range' => "bytes $this->progress-$lastBytePos/$this->size",
- 'content-type' => $req->getRequestHeader('content-type'),
- 'content-length' => $this->chunkSize,
- 'expect' => '',
- );
- $httpRequest = new Yoast_Google_HttpRequest($this->resumeUri, 'PUT', $headers, $chunk);
- $response = Yoast_Google_Client::$io->authenticatedRequest($httpRequest);
- $code = $response->getResponseHttpCode();
- if (308 == $code) {
- $range = explode('-', $response->getResponseHeader('range'));
- $this->progress = $range[1] + 1;
- return false;
- } else {
- return Yoast_Google_REST::decodeHttpResponse($response);
- }
- }
- private function getResumeUri(Yoast_Google_HttpRequest $httpRequest) {
- $result = null;
- $body = $httpRequest->getPostBody();
- if ($body) {
- $httpRequest->setRequestHeaders(array(
- 'content-type' => 'application/json; charset=UTF-8',
- 'content-length' => Yoast_Google_Utils::getStrLen($body),
- 'x-upload-content-type' => $this->mimeType,
- 'x-upload-content-length' => $this->size,
- 'expect' => '',
- ));
- }
- $response = Yoast_Google_Client::$io->makeRequest($httpRequest);
- $location = $response->getResponseHeader('location');
- $code = $response->getResponseHttpCode();
- if (200 == $code && true == $location) {
- return $location;
- }
- throw new Yoast_Google_Exception("Failed to start the resumable upload");
- }
- }