Completed
Push — master ( 343c0b...ad806c )
by Sebastian
08:09
created

AmazonS3v3::uploadMultiPart()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 8
c 1
b 0
f 0
rs 9.4285
cc 1
eloc 5
nc 1
nop 2
1
<?php
2
namespace phpbu\App\Backup\Sync;
3
4
use Aws\S3\S3Client;
5
use Aws\S3\MultipartUploader;
6
use phpbu\App\Result;
7
use phpbu\App\Backup\Sync;
8
use phpbu\App\Backup\Target;
9
10
/**
11
 * Amazon S3 Sync
12
 *
13
 * @package    phpbu
14
 * @subpackage Backup
15
 * @author     Sebastian Feldmann <[email protected]>
16
 * @copyright  Sebastian Feldmann <[email protected]>
17
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
18
 * @link       http://phpbu.de/
19
 * @since      Class available since Release 3.0.0
20
 */
21
class AmazonS3v3 extends AmazonS3
22
{
23
    /**
24
     * Execute the sync.
25
     *
26
     * @see    \phpbu\App\Backup\Sync::sync()
27
     * @param  \phpbu\App\Backup\Target $target
28
     * @param  \phpbu\App\Result        $result
29
     * @throws \phpbu\App\Backup\Sync\Exception
30
     */
31
    public function sync(Target $target, Result $result)
32
    {
33
        $s3 = new S3Client([
34
            'region'  => $this->region,
35
            'version' => '2006-03-01',
36
            'credentials' => [
37
                'key'    => $this->key,
38
                'secret' => $this->secret,
39
            ]
40
        ]);
41
42
        try {
43
            if ($this->useMultiPartUpload($target)) {
44
                $this->uploadMultiPart($target, $s3);
45
            } else {
46
                $this->uploadStream($target, $s3);
47
            }
48
        } catch (\Exception $e) {
49
            throw new Exception($e->getMessage(), null, $e);
50
        }
51
        $result->debug('upload: done');
52
    }
53
54
    /**
55
     * Upload via stream wrapper.
56
     *
57
     * @param  \phpbu\App\Backup\Target $target
58
     * @param  \Aws\S3\S3Client         $s3
59
     * @throws \phpbu\App\Backup\Sync\Exception
60
     */
61
    private function uploadStream(Target $target, S3Client $s3)
62
    {
63
        $s3->registerStreamWrapper();
64
        $source = $this->getFileHandle($target->getPathname(), 'r');
65
        $stream = $this->getFileHandle('s3://' . $this->bucket . '/' . $this->getUploadPath($target), 'w');
66
        while(!feof($source)) {
67
            fwrite($stream, fread($source, 4096));
68
        }
69
        fclose($stream);
70
    }
71
72
    /**
73
     * Upload via multi part.
74
     *
75
     * @param \phpbu\App\Backup\Target $target
76
     * @param \Aws\S3\S3Client         $s3
77
     * @param \Aws\Exception\MultipartUploadException
78
     */
79
    private function uploadMultiPart(Target $target, S3Client $s3)
80
    {
81
        $uploader = new MultipartUploader($s3, $target->getPathname(), [
82
            'bucket' => $this->bucket,
83
            'key'    => $this->getUploadPath($target),
84
        ]);
85
        $uploader->upload();
86
    }
87
88
    /**
89
     * Open stream and validate it.
90
     *
91
     * @param  string $path
92
     * @param  string $mode
93
     * @return resource
94
     * @throws \phpbu\App\Backup\Sync\Exception
95
     */
96
    private function getFileHandle($path, $mode)
97
    {
98
        $handle = fopen($path, $mode);
99
        if (!is_resource($handle)) {
100
            throw new Exception('fopen failed: could not open stream ' . $path);
101
        }
102
        return $handle;
103
    }
104
105
    /**
106
     * Get the s3 upload path
107
     *
108
     * @param \phpbu\App\Backup\Target $target
109
     * @return string
110
     */
111
    public function getUploadPath(Target $target)
112
    {
113
        // remove leading slash
114
        return (substr($this->path, 0, 1) == '/' ? substr($this->path, 1) : $this->path)
115
               . (substr($this->path, -1, 1) == '/' ? '' : '/')
116
               . $target->getFilename();
117
    }
118
}
119