S3   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 190
Duplicated Lines 4.21 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 26
lcom 1
cbo 4
dl 8
loc 190
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 8 29 7
A getClient() 0 4 1
A upload() 0 19 2
A download() 0 11 2
A copy() 0 14 2
A delete() 0 13 2
A deleteRecursive() 0 17 5
A move() 0 9 3
A fileExists() 0 4 1
A getFileList() 0 7 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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