S3ContentsFileBehaviorTrait::s3ParamCheck()   B
last analyzed

Complexity

Conditions 9
Paths 9

Size

Total Lines 26

Duplication

Lines 10
Ratio 38.46 %

Importance

Changes 0
Metric Value
dl 10
loc 26
rs 8.0555
c 0
b 0
f 0
cc 9
nc 9
nop 0
1
<?php
2
3
namespace ContentsFile\Model\Behavior\Traits;
4
5
use Cake\Core\Configure;
6
use Cake\I18n\Time;
7
use Cake\Network\Exception\InternalErrorException;
8
use Cake\ORM\TableRegistry;
9
use Cake\Utility\Security;
10
use ContentsFile\Aws\S3;
11
use Symfony\Component\Filesystem\Filesystem;
12
use Symfony\Component\Finder\Finder;
13
14
/**
15
 * S3ContentsFileBehaviorTrait
16
 * 通常のファイルアップ系の処理
17
 * メソッド名の先頭に必ずs3を付けること
18
 */
19
trait S3ContentsFileBehaviorTrait
20
{
21
22
    /**
23
     * s3ParamCheck
24
     * 通常の設定値チェック
25
     * @author hagiwara
26
     * @return void
27
     */
28
    private function s3ParamCheck(): void
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
29
    {
30
        // S3に必要な設定がそろっているかチェックする
31
        $s3Setting = Configure::read('ContentsFile.Setting.S3');
32 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...
33
            !is_array($s3Setting) ||
34
            !array_key_exists('bucket', $s3Setting) ||
35
            !array_key_exists('tmpDir', $s3Setting) ||
36
            !array_key_exists('fileDir', $s3Setting) ||
37
            !array_key_exists('workingDir', $s3Setting)
38
39
        ) {
40
            throw new InternalErrorException('contentsFileS3Config paramater shortage');
41
        }
42
43
        // /が最後についていない場合はつける
44
        if (!preg_match('#/$#', $s3Setting['tmpDir'])) {
45
            Configure::write('ContentsFile.Setting.S3.tmpDir', $s3Setting['tmpDir'] . '/');
46
        }
47
        if (!preg_match('#/$#', $s3Setting['fileDir'])) {
48
            Configure::write('ContentsFile.Setting.S3.fileDir', $s3Setting['fileDir'] . '/');
49
        }
50
        if (!preg_match('#/$#', $s3Setting['workingDir'])) {
51
            Configure::write('ContentsFile.Setting.S3.workingDir', $s3Setting['workingDir'] . '/');
52
        }
53
    }
54
55
    /**
56
     * s3FileSave
57
     * ファイルをS3に保存
58
     * @author hagiwara
59
     * @param array $fileInfo
60
     * @param array $fieldSettings
61
     * @param array $attachmentSaveData
62
     * @return bool
63
     */
64
    private function s3FileSave(array $fileInfo, array $fieldSettings, array $attachmentSaveData): bool
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
65
    {
66
        $S3 = new S3();
67
        $newFiledir = Configure::read('ContentsFile.Setting.S3.fileDir') . $attachmentSaveData['model'] . '/' . $attachmentSaveData['model_id'] . '/';
68 View Code Duplication
        if (Configure::read('ContentsFile.Setting.randomFile') === true) {
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...
69
            $newFilepath = $newFiledir . $attachmentSaveData['file_random_path'];
70
        } else {
71
            $newFilepath = $newFiledir . $fileInfo['field_name'];
72
        }
73
        if (Configure::read('ContentsFile.Setting.ext') === true) {
74
            $ext = (new \SplFileInfo($attachmentSaveData['file_name']))->getExtension();
75
            $newFilepath .= '.' . $ext;
76
        }
77
        $oldFilepath = Configure::read('ContentsFile.Setting.S3.tmpDir') . $fileInfo['tmp_file_name'];
78
79
        // 該当ファイルを消す
80
        // 失敗=ディレクトリが存在しないため、成功失敗判定は行わない。
81
        $this->s3FileDelete($attachmentSaveData['model'], $attachmentSaveData['model_id'], $fileInfo['field_name']);
82
83
        // tmpに挙がっているファイルを移
84
        if (!$S3->move($oldFilepath, $newFilepath)) {
85
            return false;
86
        }
87
88
89
        //リサイズ画像作成
90 View Code Duplication
        if (!empty($fieldSettings['resize'])) {
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...
91
            foreach ($fieldSettings['resize'] as $resizeSettings) {
92
                if (!$this->s3ImageResize($newFilepath, $resizeSettings)) {
93
                    return false;
94
                }
95
            }
96
        }
97
        return true;
98
    }
99
100
    /**
101
     * s3FileDelete
102
     * S3のファイル削除
103
     * @author hagiwara
104
     * @param string $modelName
105
     * @param integer $modelId
106
     * @param string $field
107
     * @return bool
108
     */
109
    private function s3FileDelete(string $modelName, int $modelId, string $field): bool
110
    {
111
        //attachementからデータを取得
112
        $attachmentModel = TableRegistry::getTableLocator()->get('Attachments');
113
        $attachmentData = $attachmentModel->find('all')
114
            ->where(['model' => $modelName])
115
            ->where(['model_id' => $modelId])
116
            ->where(['field_name' => $field])
117
            ->first()
118
        ;
119
        // 削除するべきファイルがない
120
        if (empty($attachmentData)) {
121
            return false;
122
        }
123 View Code Duplication
        if (Configure::read('ContentsFile.Setting.randomFile') === true && $attachmentData->file_random_path != '') {
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...
124
            $deleteField = $attachmentData->file_random_path;
125
        } else {
126
            $deleteField = $attachmentData->field_name;
127
        }
128
129
       $S3 = new S3();
130
        // リサイズのディレクトリ
131
        $resizeDir = Configure::read('ContentsFile.Setting.S3.fileDir') . $modelName . '/' . $modelId . '/' . 'contents_file_resize_' . $deleteField . '/';
132
        if (!$S3->deleteRecursive($resizeDir)) {
133
            return false;
134
        }
135
136
        // 大元のファイル
137
        $deleteFile = Configure::read('ContentsFile.Setting.S3.fileDir') . $modelName . '/' . $modelId . '/' . $deleteField;
138
        if (Configure::read('ContentsFile.Setting.ext') === true) {
139
            $ext = (new \SplFileInfo($attachmentData->file_name))->getExtension();
140
            $deleteFile .= '.' . $ext;
141
        }
142
        if (!$S3->delete($deleteFile)) {
143
            return false;
144
        }
145
        return true;
146
    }
147
148
    /**
149
     * s3ImageResize
150
     * 画像のリサイズ処理(S3用)
151
     * @author hagiwara
152
     * @param string $filepath
153
     * @param array $resize
154
     * @return string
155
     */
156
    public function s3ImageResize(string $filepath, array $resize): string
157
    {
158
        $imagepathinfo = $this->getPathinfo($filepath, $resize);
0 ignored issues
show
Bug introduced by
It seems like getPathinfo() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
159
        $S3 = new S3();
160
        // Exception = 存在していない場合
161
        $tmpFileName = Security::hash(rand() . Time::now()->i18nFormat('YYYY/MM/dd HH:ii:ss'));
162
        $tmpPath = Configure::read('ContentsFile.Setting.S3.workingDir') . $tmpFileName;
163
        // ベースのファイルを取得
164
        $baseObject = $S3->download($filepath);
165
        $fp = fopen($tmpPath, 'w');
166
        fwrite($fp, $baseObject['Body']);
167
        fclose($fp);
168
        if (!$this->imageResize($tmpPath, $resize)) {
0 ignored issues
show
Bug introduced by
The method imageResize() does not exist on ContentsFile\Model\Behav...ntentsFileBehaviorTrait. Did you maybe mean s3ImageResize()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
169
            //失敗時はそのままのパスを返す(画像以外の可能性あり)
170
            unlink($tmpPath);
171
            return $filepath;
172
        }
173
174
        $resizeFileDir = Configure::read('ContentsFile.Setting.S3.workingDir') . 'contents_file_resize_' . $tmpFileName;
175
176
        // 一つのはず
177
        $resizeImg = '';
178
        $finder = new Finder();
179
        $finder->in([$resizeFileDir]);
180
        foreach ($finder as $a) {
181
            $resizeImg = $a->getRealPath();
182
        }
183
184
        // リサイズ画像をアップロード
185
        $S3->upload($resizeImg, $imagepathinfo['resize_filepath']);
186
187
        // tmpディレクトリの不要なディレクトリ/ファイルを削除
188
        $filesystem = new Filesystem();
189
        $filesystem->remove($resizeFileDir);
190
191
        unlink($tmpPath);
192
        return $imagepathinfo['resize_filepath'];
193
    }
194
195
}
196