      1: <?php
      2: /**
      3:  * Copyright 2012-2014 Rackspace US, 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: namespace OpenCloud\ObjectStore\Upload;
     19:
     20: use Guzzle\Http\Message\Response;
     21: use Guzzle\Http\Url;
     22: use OpenCloud\Common\Constants\Header;
     23:
     24: /**
     25:  * Represents an individual part of the EntityBody being uploaded.
     26:  *
     27:  * @codeCoverageIgnore
     28:  */
     29: class TransferPart
     30: {
     31:     /**
     32:      * @var int Its position in the upload queue.
     33:      */
     34:     protected $partNumber;
     35:
     36:     /**
     37:      * @var string This upload's ETag checksum.
     38:      */
     39:     protected $eTag;
     40:
     41:     /**
     42:      * @var int The length of this upload in bytes.
     43:      */
     44:     protected $contentLength;
     45:
     46:     /**
     47:      * @var string The API path of this upload.
     48:      */
     49:     protected $path;
     50:
     51:     /**
     52:      * @param int $contentLength
     53:      * @return $this
     54:      */
     55:     public function setContentLength($contentLength)
     56:     {
     57:         $this->contentLength = $contentLength;
     58:
     59:         return $this;
     60:     }
     61:
     62:     /**
     63:      * @return int
     64:      */
     65:     public function getContentLength()
     66:     {
     67:         return $this->contentLength;
     68:     }
     69:
     70:     /**
     71:      * @param  string $etag
     72:      * @return $this
     73:      */
     74:     public function setETag($etag)
     75:     {
     76:         $this->etag = $etag;
     77:
     78:         return $this;
     79:     }
     80:
     81:     /**
     82:      * @return string
     83:      */
     84:     public function getETag()
     85:     {
     86:         return $this->etag;
     87:     }
     88:
     89:     /**
     90:      * @param int $partNumber
     91:      * @return $this
     92:      */
     93:     public function setPartNumber($partNumber)
     94:     {
     95:         $this->partNumber = $partNumber;
     96:
     97:         return $this;
     98:     }
     99:
    100:     /**
    101:      * @return int
    102:      */
    103:     public function getPartNumber()
    104:     {
    105:         return $this->partNumber;
    106:     }
    107:
    108:     /**
    109:      * @param $path
    110:      * @return $this
    111:      */
    112:     public function setPath($path)
    113:     {
    114:         $this->path = $path;
    115:
    116:         return $this;
    117:     }
    118:
    119:     /**
    120:      * @return string
    121:      */
    122:     public function getPath()
    123:     {
    124:         return $this->path;
    125:     }
    126:
    127:     /**
    128:      * Create the request needed for this upload to the API.
    129:      *
    130:      * @param EntityBody $part    The entity body being uploaded
    131:      * @param int        $number  Its number/position, needed for name
    132:      * @param OpenStack  $client  Client responsible for issuing requests
    133:      * @param array      $options Set by the Transfer object
    134:      * @return OpenCloud\Common\Http\Request
    135:      */
    136:     public static function createRequest($part, $number, $client, $options)
    137:     {
    138:         $name = sprintf('%s/%s/%d', $options['objectName'], $options['prefix'], $number);
    139:         $url = clone $options['containerUrl'];
    140:         $url->addPath($name);
    141:
    142:         $headers = array(
    143:             Header::CONTENT_LENGTH => $part->getContentLength(),
    144:             Header::CONTENT_TYPE   => $part->getContentType()
    145:         );
    146:
    147:         if ($options['doPartChecksum'] === true) {
    148:             $headers['ETag'] = $part->getContentMd5();
    149:         }
    150:
    151:         $request = $client->put($url, $headers, $part);
    152:
    153:         if (isset($options['progress'])) {
    154:             $request->getCurlOptions()->add('progress', true);
    155:             if (is_callable($options['progress'])) {
    156:                 $request->getCurlOptions()->add('progressCallback', $options['progress']);
    157:             }
    158:         }
    159:
    160:         return $request;
    161:     }
    162:
    163:     /**
    164:      * Construct a TransferPart from a HTTP response delivered by the API.
    165:      *
    166:      * @param Response $response
    167:      * @param int      $partNumber
    168:      * @return TransferPart
    169:      */
    170:     public static function fromResponse(Response $response, $partNumber = 1)
    171:     {
    172:         $responseUri = Url::factory($response->getEffectiveUrl());
    173:
    174:         $object = new self();
    175:
    176:         $object->setPartNumber($partNumber)
    177:             ->setContentLength($response->getHeader(Header::CONTENT_LENGTH))
    178:             ->setETag($response->getHeader(Header::ETAG))
    179:             ->setPath($responseUri->getPath());
    180:
    181:         return $object;
    182:     }
    183: }
    184: