Passed
Push — main ( 986279...90b18d )
by Sugeng
04:00
created

ModelTrait   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 21
eloc 49
c 1
b 0
f 0
dl 0
loc 178
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A saveUploadedFile() 0 34 6
A removeFile() 0 21 3
A getPresignedUrlDuration() 0 3 1
A attributePaths() 0 3 1
A getFileUrl() 0 7 2
A getS3Component() 0 3 1
A getFilePresignedUrl() 0 9 2
A getAttributePath() 0 8 2
A isSuccessResponseStatus() 0 5 3
1
<?php
2
3
namespace diecoding\aws\s3\traits;
4
5
use Yii;
6
use yii\web\UploadedFile;
7
8
/**
9
 * Trait ModelTrait for Model
10
 * 
11
 * @package diecoding\aws\s3\traits
12
 */
13
trait ModelTrait
14
{
15
    /**
16
     * @return \diecoding\aws\s3\Service
0 ignored issues
show
Bug introduced by
The type diecoding\aws\s3\Service was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
     */
18
    public function getS3Component()
19
    {
20
        return Yii::$app->get('s3');
0 ignored issues
show
Bug Best Practice introduced by
The expression return Yii::app->get('s3') also could return the type mixed which is incompatible with the documented return type diecoding\aws\s3\Service.
Loading history...
21
    }
22
23
    /**
24
     * Save UploadedFile to AWS S3.
25
     * ! Important: This function uploads this model filename to keep consistency of the model.
26
     * 
27
     * @param UploadedFile $file Uploaded file to save
28
     * @param string $attribute Attribute name where the uploaded filename name will be saved
29
     * @param string $fileName Name which file will be saved. If empty will use the name from $file
30
     * @param bool $autoExtension `true` to automatically append or replace the extension to the file name. Default is `true`
31
     * 
32
     * @return string|false Uploaded full path of filename on success or `false` in failure.
33
     */
34
    public function saveUploadedFile(UploadedFile $file, $attribute, $fileName = '', $autoExtension = true)
35
    {
36
        if ($this->hasError && !$file instanceof UploadedFile) {
0 ignored issues
show
introduced by
$file is always a sub-type of yii\web\UploadedFile.
Loading history...
37
            return false;
38
        }
39
40
        if (empty($fileName)) {
41
            $fileName = $file->name;
42
        }
43
        if ($autoExtension) {
44
            $_file = (string) pathinfo($fileName, PATHINFO_FILENAME);
45
            $fileName = $_file . '.' . $file->extension;
46
        }
47
48
        $filePath = $this->getAttributePath($attribute) . $fileName;
49
50
        /** @var \Aws\ResultInterface $result */
51
        $result = $this->getS3Component()
52
            ->commands()
53
            ->upload(
54
                $filePath,
55
                $file->tempName
56
            )
57
            ->withContentType($file->type)
58
            ->execute();
59
60
        // Validate successful upload to S3
61
        if ($this->isSuccessResponseStatus($result)) {
62
            $this->{$attribute} = $fileName;
63
64
            return $fileName;
65
        }
66
67
        return false;
68
    }
69
70
    /**
71
     * Delete model file attribute from AWS S3.
72
     * 
73
     * @param string $attribute Attribute name which holds the filename
74
     * 
75
     * @return bool `true` on success or if file doesn't exist.
76
     */
77
    public function removeFile($attribute)
78
    {
79
        if (empty($this->{$attribute})) {
80
            // No file to remove
81
            return true;
82
        }
83
84
        $filePath = $this->getAttributePath($attribute) . $this->{$attribute};
85
        $result = $this->getS3Component()
86
            ->commands()
87
            ->delete($filePath)
88
            ->execute();
89
90
        // Validate successful removal from S3
91
        if ($this->isSuccessResponseStatus($result)) {
92
            $this->{$attribute} = null;
93
94
            return true;
95
        }
96
97
        return false;
98
    }
99
100
    /**
101
     * Retrieves the URL for a given model file attribute.
102
     * 
103
     * @param string $attribute Attribute name which holds the filename
104
     * 
105
     * @return string URL to access file
106
     */
107
    public function getFileUrl($attribute)
108
    {
109
        if (empty($this->{$attribute})) {
110
            return '';
111
        }
112
113
        return $this->getS3Component()->getUrl($this->getAttributePath($attribute) . $this->{$attribute});
114
    }
115
116
    /**
117
     * Retrieves the presigned URL for a given model file attribute.
118
     * 
119
     * @param string $attribute Attribute name which holds the filename
120
     * 
121
     * @return string Presigned URL to access file
122
     */
123
    public function getFilePresignedUrl($attribute)
124
    {
125
        if (empty($this->{$attribute})) {
126
            return '';
127
        }
128
129
        return $this->getS3Component()->getPresignedUrl(
130
            $this->getAttributePath($attribute) . $this->{$attribute},
131
            $this->getPresignedUrlDuration($attribute)
132
        );
133
    }
134
135
    /**
136
     * Retrieves the URL signature expiration.
137
     * 
138
     * @param string $attribute Attribute name which holds the duration
139
     * 
140
     * @return mixed URL expiration
141
     */
142
    public function getPresignedUrlDuration($attribute)
0 ignored issues
show
Unused Code introduced by
The parameter $attribute is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

142
    public function getPresignedUrlDuration(/** @scrutinizer ignore-unused */ $attribute)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
143
    {
144
        return '+30 minutes';
145
    }
146
147
    /**
148
     * List the paths on AWS S3 to each model file attribute.
149
     * It must be a Key-Value array, where Key is the attribute name and Value is the base path for the file in S3.
150
     * Override this method for saving each attribute in its own "folder".
151
     * 
152
     * @return array Key-Value of attributes and its paths.
153
     */
154
    public function attributePaths()
155
    {
156
        return [];
157
    }
158
159
    /**
160
     * Retrieves the base path on AWS S3 for a given attribute.
161
     * @see attributePaths()
162
     * 
163
     * @param string $attribute Attribute to get its path
164
     * 
165
     * @return string The path where all file of that attribute should be stored. Returns empty string if the attribute isn't in the list.
166
     */
167
    public function getAttributePath($attribute)
168
    {
169
        $paths = $this->attributePaths();
170
        if (array_key_exists($attribute, $paths)) {
171
            return $paths[$attribute];
172
        }
173
174
        return '';
175
    }
176
177
    /**
178
     * Check for valid status code from the AWS S3 response.
179
     * Success responses will be considered status codes is 2**.
180
     * Override function for custom validations.
181
     * 
182
     * @param \Aws\ResultInterface $response AWS S3 response containing the status code
183
     * 
184
     * @return bool whether this response is successful.
185
     */
186
    public function isSuccessResponseStatus($response)
187
    {
188
        return !empty($response->get('@metadata')['statusCode']) &&
189
            $response->get('@metadata')['statusCode'] >= 200 &&
190
            $response->get('@metadata')['statusCode'] < 300;
191
    }
192
}
193