Completed
Push — master ( 2825b9...504b57 )
by satoru
07:25 queued 05:25
created

S3::upload()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 11
nc 2
nop 2
1
<?php
2
3
namespace ContentsFile\Aws;
4
5
use Aws\Sdk;
6
use Cake\Core\Configure;
7
use Cake\Network\Exception\InternalErrorException;
8
use Cake\Network\Exception\NotFoundException;
9
10
/**
11
 * S3
12
 * AWS SDKのS3関係の処理
13
 * @author hagiwara
14
 */
15
class S3
16
{
17
    private $client;
18
19
    /**
20
     * __construct
21
     * @author hagiwara
22
     */
23
    public function __construct()
24
    {
25
        // S3に必要な設定がそろっているかチェックする
26
        $S3Setting = Configure::read('ContentsFile.Setting.S3');
27 View Code Duplication
        if (
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
28
            !is_array($S3Setting) ||
29
            !array_key_exists('key', $S3Setting) ||
30
            !array_key_exists('secret', $S3Setting) ||
31
            !array_key_exists('bucket', $S3Setting) ||
32
            !array_key_exists('tmpDir', $S3Setting) ||
33
            !array_key_exists('fileDir', $S3Setting)
34
        ) {
35
            throw new InternalErrorException('contentsFileS3Config paramater shortage');
36
        }
37
        // S3に接続するためのクライアントを用意します。
38
        $key    = Configure::read('ContentsFile.Setting.S3.key');
39
        $secret = Configure::read('ContentsFile.Setting.S3.secret');
40
        $sdk = new Sdk([
41
            'credentials' => array(
42
                'key'=> $key,
43
                'secret' => $secret,
44
            ),
45
            'version' => 'latest',
46
            'region'  => 'ap-northeast-1'
47
        ]);
48
        $this->client = $sdk->createS3();
49
    }
50
51
    /**
52
     * getClient
53
     * clientを取得
54
     * @author hagiwara
55
     */
56
    public function getClient()
57
    {
58
        return $this->client;
59
    }
60
61
    /**
62
     * upload
63
     * S3へのファイルアップロード
64
     * @author hagiwara
65
     */
66
    public function upload($filepath, $filename)
67
    {
68
        // アップロードするべきファイルがない場合
69
        if (!file_exists($filepath)) {
70
            throw new InternalErrorException('upload file not found');
71
        }
72
        $bucketName = Configure::read('ContentsFile.Setting.S3.bucket');
73
        $mimetype = mime_content_type($filepath);
74
75
        // ファイルのアップロード
76
        $data = file_get_contents($filepath);
77
78
        return $this->client->putObject([
79
            'Bucket' => $bucketName,
80
            'Key' => $filename,
81
            'Body' => $data,
82
            'ContentType' => $mimetype
83
        ]);
84
    }
85
86
    /**
87
     * upload
88
     * S3からのファイルダウンロード
89
     * @author hagiwara
90
     */
91
    public function download($filename)
92
    {
93
        // ファイルが存在しない場合は404
94
        if (!$this->fileExists($filename)) {
95
            throw new NotFoundException('404 error');
96
        }
97
        return $this->client->getObject([
98
            'Bucket' => Configure::read('ContentsFile.Setting.S3.bucket'),
99
            'Key' => $filename
100
        ]);
101
    }
102
103
    /**
104
     * copy
105
     * S3上でのファイルコピー
106
     * @author hagiwara
107
     */
108
    public function copy($oldFilename, $newFilename)
109
    {
110
        // ファイルが存在しない
111
        if (!$this->fileExists($oldFilename)) {
112
            return false;
113
        }
114
        // 権限不足のExceptionはそのまま出す
115
        $this->client->copyObject(array(
116
            'Bucket' => Configure::read('ContentsFile.Setting.S3.bucket'),
117
            'Key'        => $newFilename,
118
            'CopySource' => Configure::read('ContentsFile.Setting.S3.bucket') . '/' . $oldFilename,
119
        ));
120
        return true;
121
    }
122
123
    /**
124
     * delete
125
     * S3上でのファイル削除
126
     * @author hagiwara
127
     */
128
    public function delete($filename)
129
    {
130
        // 削除するファイルが存在しない
131
        if (!$this->fileExists($filename)) {
132
            return false;
133
        }
134
        // 権限不足のExceptionはそのまま出す
135
        $this->client->deleteObject(array(
136
            'Bucket' => Configure::read('ContentsFile.Setting.S3.bucket'),
137
            'Key' => $filename,
138
        ));
139
        return true;
140
    }
141
142
    /**
143
     * deleteRecursive
144
     * S3上でのファイル削除(再帰的)
145
     * @author hagiwara
146
     */
147
    public function deleteRecursive($dirname)
148
    {
149
        // $dirnameで消す単位は最低でもIDなので文字列内に数値のディレクトリがあることをチェックする
150
        if (!preg_match('#/[0-9]+/#', $dirname)) {
151
            return false;
152
        }
153
        $deleteFileLists = $this->getFileList($dirname);
154
155
        if (!empty($deleteFileLists)) {
156
            foreach ($deleteFileLists as $deleteDirInfo) {
157
                if (!$this->delete($deleteDirInfo['Key'])) {
158
                    return false;
159
                }
160
            }
161
        }
162
        return true;
163
    }
164
165
    /**
166
     * move
167
     * S3上でのファイル移動(コピー&削除)
168
     * @author hagiwara
169
     */
170
    public function move($oldFilename, $newFilename)
171
    {
172
        // 移動するファイルが存在しない
173
        if (!$this->fileExists($oldFilename)) {
174
            return false;
175
        }
176
        // 失敗時はException
177
        return $this->copy($oldFilename, $newFilename) && $this->delete($oldFilename);
178
    }
179
180
    /**
181
     * fileExists
182
     * S3上でのファイルの存在チェック(ディレクトリ存在チェックも兼)
183
     * @author hagiwara
184
     */
185
    public function fileExists($filename)
186
    {
187
        return !empty($this->getFileList($filename));
188
    }
189
190
    /**
191
     * getFileList
192
     * 特定ディレクトリ内のfileの一覧取得
193
     * @author hagiwara
194
     */
195
    public function getFileList($dirname)
196
    {
197
        return $this->client->listObjects(array(
198
            'Bucket' => Configure::read('ContentsFile.Setting.S3.bucket'),
199
            'Prefix' => $dirname
200
        ))->get('Contents');
201
    }
202
}
203