PHP Classes

File: example/GoogleClient/service/Google_MediaFileUpload.php

Recommend this page to a friend!
  Classes of Vivek Muthal   Viv OAuth IMAP   example/GoogleClient/service/Google_MediaFileUpload.php   Download  
File: example/GoogleClient/service/Google_MediaFileUpload.php
Role: Example script
Content type: text/plain
Description: Example script
Class: Viv OAuth IMAP
Access messages in IMAP server using OAuth token
Author: By
Last change: Update of example/GoogleClient/service/Google_MediaFileUpload.php
Date: 8 months ago
Size: 7,636 bytes
 

Contents

Class file image Download
<?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 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(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 Google_HttpRequest($this->resumeUri, 'PUT', $headers, $chunk);
   
$response = 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
Google_REST::decodeHttpResponse($response);
    }
  }

  private function
getResumeUri(Google_HttpRequest $httpRequest) {
   
$result = null;
   
$body = $httpRequest->getPostBody();
    if (
$body) {
     
$httpRequest->setRequestHeaders(array(
       
'content-type' => 'application/json; charset=UTF-8',
       
'content-length' => Google_Utils::getStrLen($body),
       
'x-upload-content-type' => $this->mimeType,
       
'x-upload-content-length' => $this->size,
       
'expect' => '',
      ));
    }

   
$response = Google_Client::$io->makeRequest($httpRequest);
   
$location = $response->getResponseHeader('location');
   
$code = $response->getResponseHttpCode();
    if (
200 == $code && true == $location) {
      return
$location;
    }
    throw new
Google_Exception("Failed to start the resumable upload");
  }
}