| 1 | efrain | 1 | <?php
 | 
        
           |  |  | 2 | namespace Aws\S3;
 | 
        
           |  |  | 3 |   | 
        
           |  |  | 4 | use Aws\CommandInterface;
 | 
        
           |  |  | 5 | use Aws\Multipart\UploadState;
 | 
        
           |  |  | 6 | use Aws\ResultInterface;
 | 
        
           |  |  | 7 |   | 
        
           |  |  | 8 | trait MultipartUploadingTrait
 | 
        
           |  |  | 9 | {
 | 
        
           | 1441 | ariadna | 10 |     private $uploadedBytes = 0;
 | 
        
           |  |  | 11 |   | 
        
           | 1 | efrain | 12 |     /**
 | 
        
           |  |  | 13 |      * Creates an UploadState object for a multipart upload by querying the
 | 
        
           |  |  | 14 |      * service for the specified upload's information.
 | 
        
           |  |  | 15 |      *
 | 
        
           |  |  | 16 |      * @param S3ClientInterface $client   S3Client used for the upload.
 | 
        
           |  |  | 17 |      * @param string            $bucket   Bucket for the multipart upload.
 | 
        
           |  |  | 18 |      * @param string            $key      Object key for the multipart upload.
 | 
        
           |  |  | 19 |      * @param string            $uploadId Upload ID for the multipart upload.
 | 
        
           |  |  | 20 |      *
 | 
        
           |  |  | 21 |      * @return UploadState
 | 
        
           |  |  | 22 |      */
 | 
        
           |  |  | 23 |     public static function getStateFromService(
 | 
        
           |  |  | 24 |         S3ClientInterface $client,
 | 
        
           |  |  | 25 |         $bucket,
 | 
        
           |  |  | 26 |         $key,
 | 
        
           |  |  | 27 |         $uploadId
 | 
        
           |  |  | 28 |     ) {
 | 
        
           |  |  | 29 |         $state = new UploadState([
 | 
        
           |  |  | 30 |             'Bucket'   => $bucket,
 | 
        
           |  |  | 31 |             'Key'      => $key,
 | 
        
           |  |  | 32 |             'UploadId' => $uploadId,
 | 
        
           |  |  | 33 |         ]);
 | 
        
           |  |  | 34 |   | 
        
           |  |  | 35 |         foreach ($client->getPaginator('ListParts', $state->getId()) as $result) {
 | 
        
           |  |  | 36 |             // Get the part size from the first part in the first result.
 | 
        
           |  |  | 37 |             if (!$state->getPartSize()) {
 | 
        
           |  |  | 38 |                 $state->setPartSize($result->search('Parts[0].Size'));
 | 
        
           |  |  | 39 |             }
 | 
        
           |  |  | 40 |             // Mark all the parts returned by ListParts as uploaded.
 | 
        
           |  |  | 41 |             foreach ($result['Parts'] as $part) {
 | 
        
           |  |  | 42 |                 $state->markPartAsUploaded($part['PartNumber'], [
 | 
        
           |  |  | 43 |                     'PartNumber' => $part['PartNumber'],
 | 
        
           |  |  | 44 |                     'ETag'       => $part['ETag']
 | 
        
           |  |  | 45 |                 ]);
 | 
        
           |  |  | 46 |             }
 | 
        
           |  |  | 47 |         }
 | 
        
           |  |  | 48 |   | 
        
           |  |  | 49 |         $state->setStatus(UploadState::INITIATED);
 | 
        
           |  |  | 50 |   | 
        
           |  |  | 51 |         return $state;
 | 
        
           |  |  | 52 |     }
 | 
        
           |  |  | 53 |   | 
        
           |  |  | 54 |     protected function handleResult(CommandInterface $command, ResultInterface $result)
 | 
        
           |  |  | 55 |     {
 | 
        
           | 1441 | ariadna | 56 |         $partData = [];
 | 
        
           |  |  | 57 |         $partData['PartNumber'] = $command['PartNumber'];
 | 
        
           |  |  | 58 |         $partData['ETag'] = $this->extractETag($result);
 | 
        
           |  |  | 59 |         $commandName = $command->getName();
 | 
        
           |  |  | 60 |         $checksumResult = $commandName === 'UploadPart'
 | 
        
           |  |  | 61 |             ? $result
 | 
        
           |  |  | 62 |             : $result[$commandName . 'Result'];
 | 
        
           |  |  | 63 |   | 
        
           |  |  | 64 |         if (isset($command['ChecksumAlgorithm'])) {
 | 
        
           |  |  | 65 |             $checksumMemberName = 'Checksum' . strtoupper($command['ChecksumAlgorithm']);
 | 
        
           |  |  | 66 |             $partData[$checksumMemberName] = $checksumResult[$checksumMemberName] ?? null;
 | 
        
           |  |  | 67 |         }
 | 
        
           |  |  | 68 |   | 
        
           |  |  | 69 |         $this->getState()->markPartAsUploaded($command['PartNumber'], $partData);
 | 
        
           |  |  | 70 |   | 
        
           |  |  | 71 |         // Updates counter for uploaded bytes.
 | 
        
           |  |  | 72 |         $this->uploadedBytes += $command["ContentLength"];
 | 
        
           |  |  | 73 |         // Sends uploaded bytes to progress tracker if getDisplayProgress set
 | 
        
           |  |  | 74 |         if ($this->displayProgress) {
 | 
        
           |  |  | 75 |             $this->getState()->getDisplayProgress($this->uploadedBytes);
 | 
        
           |  |  | 76 |         }
 | 
        
           | 1 | efrain | 77 |     }
 | 
        
           |  |  | 78 |   | 
        
           |  |  | 79 |     abstract protected function extractETag(ResultInterface $result);
 | 
        
           |  |  | 80 |   | 
        
           |  |  | 81 |     protected function getCompleteParams()
 | 
        
           |  |  | 82 |     {
 | 
        
           |  |  | 83 |         $config = $this->getConfig();
 | 
        
           |  |  | 84 |         $params = isset($config['params']) ? $config['params'] : [];
 | 
        
           |  |  | 85 |   | 
        
           |  |  | 86 |         $params['MultipartUpload'] = [
 | 
        
           |  |  | 87 |             'Parts' => $this->getState()->getUploadedParts()
 | 
        
           |  |  | 88 |         ];
 | 
        
           |  |  | 89 |   | 
        
           |  |  | 90 |         return $params;
 | 
        
           |  |  | 91 |     }
 | 
        
           |  |  | 92 |   | 
        
           |  |  | 93 |     protected function determinePartSize()
 | 
        
           |  |  | 94 |     {
 | 
        
           |  |  | 95 |         // Make sure the part size is set.
 | 
        
           |  |  | 96 |         $partSize = $this->getConfig()['part_size'] ?: MultipartUploader::PART_MIN_SIZE;
 | 
        
           |  |  | 97 |   | 
        
           |  |  | 98 |         // Adjust the part size to be larger for known, x-large uploads.
 | 
        
           |  |  | 99 |         if ($sourceSize = $this->getSourceSize()) {
 | 
        
           |  |  | 100 |             $partSize = (int) max(
 | 
        
           |  |  | 101 |                 $partSize,
 | 
        
           |  |  | 102 |                 ceil($sourceSize / MultipartUploader::PART_MAX_NUM)
 | 
        
           |  |  | 103 |             );
 | 
        
           |  |  | 104 |         }
 | 
        
           |  |  | 105 |   | 
        
           |  |  | 106 |         // Ensure that the part size follows the rules: 5 MB <= size <= 5 GB.
 | 
        
           |  |  | 107 |         if ($partSize < MultipartUploader::PART_MIN_SIZE || $partSize > MultipartUploader::PART_MAX_SIZE) {
 | 
        
           |  |  | 108 |             throw new \InvalidArgumentException('The part size must be no less '
 | 
        
           |  |  | 109 |                 . 'than 5 MB and no greater than 5 GB.');
 | 
        
           |  |  | 110 |         }
 | 
        
           |  |  | 111 |   | 
        
           |  |  | 112 |         return $partSize;
 | 
        
           |  |  | 113 |     }
 | 
        
           |  |  | 114 |   | 
        
           |  |  | 115 |     protected function getInitiateParams()
 | 
        
           |  |  | 116 |     {
 | 
        
           |  |  | 117 |         $config = $this->getConfig();
 | 
        
           |  |  | 118 |         $params = isset($config['params']) ? $config['params'] : [];
 | 
        
           |  |  | 119 |   | 
        
           |  |  | 120 |         if (isset($config['acl'])) {
 | 
        
           |  |  | 121 |             $params['ACL'] = $config['acl'];
 | 
        
           |  |  | 122 |         }
 | 
        
           |  |  | 123 |   | 
        
           |  |  | 124 |         // Set the ContentType if not already present
 | 
        
           |  |  | 125 |         if (empty($params['ContentType']) && $type = $this->getSourceMimeType()) {
 | 
        
           |  |  | 126 |             $params['ContentType'] = $type;
 | 
        
           |  |  | 127 |         }
 | 
        
           |  |  | 128 |   | 
        
           |  |  | 129 |         return $params;
 | 
        
           |  |  | 130 |     }
 | 
        
           |  |  | 131 |   | 
        
           |  |  | 132 |     /**
 | 
        
           |  |  | 133 |      * @return UploadState
 | 
        
           |  |  | 134 |      */
 | 
        
           |  |  | 135 |     abstract protected function getState();
 | 
        
           |  |  | 136 |   | 
        
           |  |  | 137 |     /**
 | 
        
           |  |  | 138 |      * @return array
 | 
        
           |  |  | 139 |      */
 | 
        
           |  |  | 140 |     abstract protected function getConfig();
 | 
        
           |  |  | 141 |   | 
        
           |  |  | 142 |     /**
 | 
        
           |  |  | 143 |      * @return int
 | 
        
           |  |  | 144 |      */
 | 
        
           |  |  | 145 |     abstract protected function getSourceSize();
 | 
        
           |  |  | 146 |   | 
        
           |  |  | 147 |     /**
 | 
        
           |  |  | 148 |      * @return string|null
 | 
        
           |  |  | 149 |      */
 | 
        
           |  |  | 150 |     abstract protected function getSourceMimeType();
 | 
        
           |  |  | 151 | }
 |