Skip to content

Commit 8564cc0

Browse files
committed
Add ModelTrait
1 parent 839ea27 commit 8564cc0

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed

src/traits/ModelTrait.php

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
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
17+
*/
18+
public function getS3Component()
19+
{
20+
return Yii::$app->get('s3');
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 $updateExtension `true` to automatically append 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 = '', $updateExtension = true)
35+
{
36+
if ($this->hasError && !$file instanceof UploadedFile) {
37+
return false;
38+
}
39+
40+
if (empty($fileName)) {
41+
$fileName = $file->name;
42+
}
43+
if ($updateExtension) {
44+
$fileName .= '.' . $file->extension;
45+
}
46+
47+
$filePath = $this->getAttributePath($attribute) . $fileName;
48+
49+
/** @var \Aws\ResultInterface $result */
50+
$result = $this->getS3Component()
51+
->commands()
52+
->upload(
53+
$filePath,
54+
$file->tempName
55+
)
56+
->withContentType($file->type)
57+
->execute();
58+
59+
// Validate successful upload to S3
60+
if ($this->isSuccessResponseStatus($result)) {
61+
$this->{$attribute} = $fileName;
62+
63+
return $fileName;
64+
}
65+
66+
return false;
67+
}
68+
69+
/**
70+
* Delete model file attribute from AWS S3.
71+
*
72+
* @param string $attribute Attribute name which holds the filename
73+
*
74+
* @return bool `true` on success or if file doesn't exist.
75+
*/
76+
public function removeFile($attribute)
77+
{
78+
if (empty($this->{$attribute})) {
79+
// No file to remove
80+
return true;
81+
}
82+
83+
$filePath = $this->getAttributePath($attribute) . $this->{$attribute};
84+
$result = $this->getS3Component()
85+
->commands()
86+
->delete($filePath)
87+
->execute();
88+
89+
// Validate successful removal from S3
90+
if ($this->isSuccessResponseStatus($result)) {
91+
$this->{$attribute} = null;
92+
93+
return true;
94+
}
95+
96+
return false;
97+
}
98+
99+
/**
100+
* Retrieves the URL for a given model file attribute.
101+
*
102+
* @param string $attribute Attribute name which holds the filename
103+
*
104+
* @return string URL to access file
105+
*/
106+
public function getFileUrl($attribute)
107+
{
108+
if (empty($this->{$attribute})) {
109+
return '';
110+
}
111+
112+
return $this->getS3Component()->getUrl($this->getAttributePath($attribute) . $this->{$attribute});
113+
}
114+
115+
/**
116+
* Retrieves the presigned URL for a given model file attribute.
117+
*
118+
* @param string $attribute Attribute name which holds the filename
119+
*
120+
* @return string Presigned URL to access file
121+
*/
122+
public function getFilePresignedUrl($attribute)
123+
{
124+
if (empty($this->{$attribute})) {
125+
return '';
126+
}
127+
128+
return $this->getS3Component()->getPresignedUrl(
129+
$this->getAttributePath($attribute) . $this->{$attribute},
130+
$this->getPresignedUrlDuration()
131+
);
132+
}
133+
134+
/**
135+
* Retrieves the URL signature expiration.
136+
*
137+
* @return mixed URL expiration
138+
*/
139+
protected function getPresignedUrlDuration()
140+
{
141+
return '+30 minutes';
142+
}
143+
144+
/**
145+
* Retrieves the base path on AWS S3 for a given attribute.
146+
* @see attributePaths()
147+
*
148+
* @param string $attribute Attribute to get its path
149+
*
150+
* @return string The path where all file of that attribute should be stored. Returns empty string if the attribute isn't in the list.
151+
*/
152+
protected function getAttributePath($attribute)
153+
{
154+
$paths = $this->attributePaths();
155+
if (array_key_exists($attribute, $paths)) {
156+
return $paths[$attribute];
157+
}
158+
159+
return '';
160+
}
161+
162+
/**
163+
* List the paths on AWS S3 to each model file attribute.
164+
* It must be a Key-Value array, where Key is the attribute name and Value is the base path for the file in S3.
165+
* Override this method for saving each attribute in its own "folder".
166+
*
167+
* @return array Key-Value of attributes and its paths.
168+
*/
169+
protected function attributePaths()
170+
{
171+
return [];
172+
}
173+
174+
/**
175+
* Check for valid status code from the AWS S3 response.
176+
* Success responses will be considered status codes is 2**.
177+
* Override function for custom validations.
178+
*
179+
* @param \Aws\ResultInterface $response AWS S3 response containing the status code
180+
*
181+
* @return bool whether this response is successful.
182+
*/
183+
protected function isSuccessResponseStatus($response)
184+
{
185+
return !empty($response->get('@metadata')['statusCode']) &&
186+
$response->get('@metadata')['statusCode'] >= 200 &&
187+
$response->get('@metadata')['statusCode'] < 300;
188+
}
189+
}

0 commit comments

Comments
 (0)