EVOLUTION-MANAGER
Edit File: AbstractTransfer.php
<?php /** * Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file 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. */ namespace DuplicatorPro\Aws\Common\Model\MultipartUpload; use DuplicatorPro\Aws\Common\Client\AwsClientInterface; use DuplicatorPro\Aws\Common\Exception\MultipartUploadException; use DuplicatorPro\Aws\Common\Exception\RuntimeException; use DuplicatorPro\Guzzle\Common\AbstractHasDispatcher; use DuplicatorPro\Guzzle\Http\EntityBody; use DuplicatorPro\Guzzle\Http\EntityBodyInterface; use DuplicatorPro\Guzzle\Service\Command\OperationCommand; use DuplicatorPro\Guzzle\Service\Resource\Model; /** * Abstract class for transfer commonalities */ abstract class AbstractTransfer extends AbstractHasDispatcher implements TransferInterface { const BEFORE_UPLOAD = 'multipart_upload.before_upload'; const AFTER_UPLOAD = 'multipart_upload.after_upload'; const BEFORE_PART_UPLOAD = 'multipart_upload.before_part_upload'; const AFTER_PART_UPLOAD = 'multipart_upload.after_part_upload'; const AFTER_ABORT = 'multipart_upload.after_abort'; const AFTER_COMPLETE = 'multipart_upload.after_complete'; /** * @var AwsClientInterface Client used for the transfers */ protected $client; /** * @var TransferStateInterface State of the transfer */ protected $state; /** * @var EntityBody Data source of the transfer */ protected $source; /** * @var array Associative array of options */ protected $options; /** * @var int Size of each part to upload */ protected $partSize; /** * @var bool Whether or not the transfer has been stopped */ protected $stopped = false; /** * Construct a new transfer object * * @param AwsClientInterface $client Client used for the transfers * @param TransferStateInterface $state State used to track transfer * @param EntityBody $source Data source of the transfer * @param array $options Array of options to apply */ public function __construct( AwsClientInterface $client, TransferStateInterface $state, EntityBody $source, array $options = array() ) { $this->client = $client; $this->state = $state; $this->source = $source; $this->options = $options; $this->init(); $this->partSize = $this->calculatePartSize(); } public function __invoke() { return $this->upload(); } /** * {@inheritdoc} */ public static function getAllEvents() { return array( self::BEFORE_PART_UPLOAD, self::AFTER_UPLOAD, self::BEFORE_PART_UPLOAD, self::AFTER_PART_UPLOAD, self::AFTER_ABORT, self::AFTER_COMPLETE ); } /** * {@inheritdoc} */ public function abort() { $command = $this->getAbortCommand(); $result = $command->getResult(); $this->state->setAborted(true); $this->stop(); $this->dispatch(self::AFTER_ABORT, $this->getEventData($command)); return $result; } /** * {@inheritdoc} */ public function stop() { $this->stopped = true; return $this->state; } /** * {@inheritdoc} */ public function getState() { return $this->state; } /** * Get the array of options associated with the transfer * * @return array */ public function getOptions() { return $this->options; } /** * Set an option on the transfer * * @param string $option Name of the option * @param mixed $value Value to set * * @return self */ public function setOption($option, $value) { $this->options[$option] = $value; return $this; } /** * Get the source body of the upload * * @return EntityBodyInterface */ public function getSource() { return $this->source; } /** * {@inheritdoc} * @throws MultipartUploadException when an error is encountered. Use getLastException() to get more information. * @throws RuntimeException when attempting to upload an aborted transfer */ public function upload() { if ($this->state->isAborted()) { throw new RuntimeException('The transfer has been aborted and cannot be uploaded'); } $this->stopped = false; $eventData = $this->getEventData(); $this->dispatch(self::BEFORE_UPLOAD, $eventData); try { $this->transfer(); $this->dispatch(self::AFTER_UPLOAD, $eventData); if ($this->stopped) { return null; } else { $result = $this->complete(); $this->dispatch(self::AFTER_COMPLETE, $eventData); } } catch (\Exception $e) { throw new MultipartUploadException($this->state, $e); } return $result; } /** * Get an array used for event notifications * * @param OperationCommand $command Command to include in event data * * @return array */ protected function getEventData(OperationCommand $command = null) { $data = array( 'transfer' => $this, 'source' => $this->source, 'options' => $this->options, 'client' => $this->client, 'part_size' => $this->partSize, 'state' => $this->state ); if ($command) { $data['command'] = $command; } return $data; } /** * Hook to initialize the transfer */ protected function init() {} /** * Determine the upload part size based on the size of the source data and * taking into account the acceptable minimum and maximum part sizes. * * @return int The part size */ abstract protected function calculatePartSize(); /** * Complete the multipart upload * * @return Model Returns the result of the complete multipart upload command */ abstract protected function complete(); /** * Hook to implement in subclasses to perform the actual transfer */ abstract protected function transfer(); /** * Fetches the abort command fom the concrete implementation * * @return OperationCommand */ abstract protected function getAbortCommand(); }