These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | namespace League\Flysystem\AwsS3V3; |
||
6 | |||
7 | use Aws\Result; |
||
8 | use Aws\S3\S3Client; |
||
9 | use Aws\S3\S3ClientInterface; |
||
10 | use Exception; |
||
11 | use Generator; |
||
12 | use League\Flysystem\AdapterTestUtilities\FilesystemAdapterTestCase; |
||
13 | use League\Flysystem\Config; |
||
14 | use League\Flysystem\FileAttributes; |
||
15 | use League\Flysystem\FilesystemAdapter; |
||
16 | use League\Flysystem\StorageAttributes; |
||
17 | use League\Flysystem\UnableToCheckFileExistence; |
||
18 | use League\Flysystem\UnableToDeleteFile; |
||
19 | use League\Flysystem\UnableToMoveFile; |
||
20 | use League\Flysystem\UnableToRetrieveMetadata; |
||
21 | use League\Flysystem\UnableToWriteFile; |
||
22 | use RuntimeException; |
||
23 | |||
24 | /** |
||
25 | * @group aws |
||
26 | */ |
||
27 | class AwsS3V3AdapterTest extends FilesystemAdapterTestCase |
||
28 | { |
||
29 | /** |
||
30 | * @var bool |
||
31 | */ |
||
32 | private $shouldCleanUp = false; |
||
33 | |||
34 | /** |
||
35 | * @var string |
||
36 | */ |
||
37 | private static $adapterPrefix = 'test-prefix'; |
||
38 | |||
39 | /** |
||
40 | * @var S3ClientInterface|null |
||
41 | */ |
||
42 | private static $s3Client; |
||
43 | |||
44 | /** |
||
45 | * @var S3ClientStub |
||
46 | */ |
||
47 | private static $stubS3Client; |
||
48 | |||
49 | public static function setUpBeforeClass(): void |
||
50 | { |
||
51 | static::$adapterPrefix = 'ci/' . bin2hex(random_bytes(10)); |
||
0 ignored issues
–
show
|
|||
52 | } |
||
53 | |||
54 | protected function tearDown(): void |
||
55 | { |
||
56 | if ( ! $this->shouldCleanUp) { |
||
57 | return; |
||
58 | } |
||
59 | |||
60 | $adapter = $this->adapter(); |
||
61 | $adapter->deleteDirectory('/'); |
||
62 | /** @var StorageAttributes[] $listing */ |
||
63 | $listing = $adapter->listContents('', false); |
||
64 | |||
65 | foreach ($listing as $item) { |
||
66 | if ($item->isFile()) { |
||
67 | $adapter->delete($item->path()); |
||
68 | } else { |
||
69 | $adapter->deleteDirectory($item->path()); |
||
70 | } |
||
71 | } |
||
72 | |||
73 | self::$adapter = null; |
||
74 | } |
||
75 | |||
76 | private static function s3Client(): S3ClientInterface |
||
77 | { |
||
78 | if (static::$s3Client instanceof S3ClientInterface) { |
||
0 ignored issues
–
show
Since
$s3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $s3Client to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() |
|||
79 | return static::$s3Client; |
||
0 ignored issues
–
show
Since
$s3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $s3Client to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() |
|||
80 | } |
||
81 | |||
82 | $key = getenv('FLYSYSTEM_AWS_S3_KEY'); |
||
83 | $secret = getenv('FLYSYSTEM_AWS_S3_SECRET'); |
||
84 | $bucket = getenv('FLYSYSTEM_AWS_S3_BUCKET'); |
||
85 | $region = getenv('FLYSYSTEM_AWS_S3_REGION') ?: 'eu-central-1'; |
||
86 | |||
87 | if ( ! $key || ! $secret || ! $bucket) { |
||
88 | self::markTestSkipped('No AWS credentials present for testing.'); |
||
89 | } |
||
90 | |||
91 | $options = ['version' => 'latest', 'credentials' => compact('key', 'secret'), 'region' => $region]; |
||
92 | |||
93 | return static::$s3Client = new S3Client($options); |
||
0 ignored issues
–
show
Since
$s3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $s3Client to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() |
|||
94 | } |
||
95 | |||
96 | /** |
||
97 | * @test |
||
98 | */ |
||
99 | public function writing_with_a_specific_mime_type(): void |
||
100 | { |
||
101 | $adapter = $this->adapter(); |
||
102 | $adapter->write('some/path.txt', 'contents', new Config(['ContentType' => 'text/plain+special'])); |
||
103 | $mimeType = $adapter->mimeType('some/path.txt')->mimeType(); |
||
104 | $this->assertEquals('text/plain+special', $mimeType); |
||
105 | } |
||
106 | |||
107 | /** |
||
108 | * @test |
||
109 | */ |
||
110 | public function listing_contents_recursive(): void |
||
111 | { |
||
112 | $adapter = $this->adapter(); |
||
113 | $adapter->write('something/0/here.txt', 'contents', new Config()); |
||
114 | $adapter->write('something/1/also/here.txt', 'contents', new Config()); |
||
115 | |||
116 | $contents = iterator_to_array($adapter->listContents('', true)); |
||
117 | |||
118 | $this->assertCount(2, $contents); |
||
119 | $this->assertContainsOnlyInstancesOf(FileAttributes::class, $contents); |
||
120 | /** @var FileAttributes $file */ |
||
121 | $file = $contents[0]; |
||
122 | $this->assertEquals('something/0/here.txt', $file->path()); |
||
123 | /** @var FileAttributes $file */ |
||
124 | $file = $contents[1]; |
||
125 | $this->assertEquals('something/1/also/here.txt', $file->path()); |
||
126 | } |
||
127 | |||
128 | /** |
||
129 | * @test |
||
130 | */ |
||
131 | View Code Duplication | public function failing_to_delete_while_moving(): void |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
132 | { |
||
133 | $adapter = $this->adapter(); |
||
134 | $adapter->write('source.txt', 'contents to be copied', new Config()); |
||
135 | static::$stubS3Client->failOnNextCopy(); |
||
0 ignored issues
–
show
Since
$stubS3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $stubS3Client to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() |
|||
136 | |||
137 | $this->expectException(UnableToMoveFile::class); |
||
138 | |||
139 | $adapter->move('source.txt', 'destination.txt', new Config()); |
||
140 | } |
||
141 | |||
142 | |||
143 | |||
144 | /** |
||
145 | * @test |
||
146 | */ |
||
147 | View Code Duplication | public function failing_to_write_a_file(): void |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
148 | { |
||
149 | $adapter = $this->adapter(); |
||
150 | static::$stubS3Client->throwDuringUpload(new RuntimeException('Oh no')); |
||
0 ignored issues
–
show
Since
$stubS3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $stubS3Client to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() |
|||
151 | |||
152 | $this->expectException(UnableToWriteFile::class); |
||
153 | |||
154 | $adapter->write('path.txt', 'contents', new Config()); |
||
155 | } |
||
156 | |||
157 | /** |
||
158 | * @test |
||
159 | */ |
||
160 | public function failing_to_delete_a_file(): void |
||
161 | { |
||
162 | $adapter = $this->adapter(); |
||
163 | static::$stubS3Client->throwExceptionWhenExecutingCommand('DeleteObject'); |
||
0 ignored issues
–
show
Since
$stubS3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $stubS3Client to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() |
|||
164 | |||
165 | $this->expectException(UnableToDeleteFile::class); |
||
166 | |||
167 | $adapter->delete('path.txt'); |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * @test |
||
172 | */ |
||
173 | public function fetching_unknown_mime_type_of_a_file(): void |
||
174 | { |
||
175 | $this->adapter(); |
||
176 | $result = new Result([ |
||
177 | 'Key' => static::$adapterPrefix . '/unknown-mime-type.md5', |
||
0 ignored issues
–
show
Since
$adapterPrefix is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $adapterPrefix to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() |
|||
178 | ]); |
||
179 | static::$stubS3Client->stageResultForCommand('HeadObject', $result); |
||
0 ignored issues
–
show
Since
$stubS3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $stubS3Client to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() |
|||
180 | |||
181 | parent::fetching_unknown_mime_type_of_a_file(); |
||
182 | } |
||
183 | |||
184 | /** |
||
185 | * @test |
||
186 | * @dataProvider dpFailingMetadataGetters |
||
187 | */ |
||
188 | public function failing_to_retrieve_metadata(Exception $exception, string $getterName): void |
||
189 | { |
||
190 | $adapter = $this->adapter(); |
||
191 | $result = new Result([ |
||
192 | 'Key' => static::$adapterPrefix . '/filename.txt', |
||
0 ignored issues
–
show
Since
$adapterPrefix is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $adapterPrefix to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() |
|||
193 | ]); |
||
194 | static::$stubS3Client->stageResultForCommand('HeadObject', $result); |
||
0 ignored issues
–
show
Since
$stubS3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $stubS3Client to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() |
|||
195 | |||
196 | $this->expectExceptionObject($exception); |
||
197 | |||
198 | $adapter->{$getterName}('filename.txt'); |
||
199 | } |
||
200 | |||
201 | public function dpFailingMetadataGetters(): iterable |
||
202 | { |
||
203 | yield "mimeType" => [UnableToRetrieveMetadata::mimeType('filename.txt'), 'mimeType']; |
||
204 | yield "lastModified" => [UnableToRetrieveMetadata::lastModified('filename.txt'), 'lastModified']; |
||
205 | yield "fileSize" => [UnableToRetrieveMetadata::fileSize('filename.txt'), 'fileSize']; |
||
206 | } |
||
207 | |||
208 | /** |
||
209 | * @test |
||
210 | */ |
||
211 | public function failing_to_check_for_file_existence(): void |
||
212 | { |
||
213 | $adapter = $this->adapter(); |
||
214 | |||
215 | static::$stubS3Client->throw500ExceptionWhenExecutingCommand('HeadObject'); |
||
0 ignored issues
–
show
Since
$stubS3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $stubS3Client to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() |
|||
216 | |||
217 | $this->expectException(UnableToCheckFileExistence::class); |
||
218 | |||
219 | $adapter->fileExists('something-that-does-exist.txt'); |
||
220 | } |
||
221 | |||
222 | /** |
||
223 | * @test |
||
224 | * @dataProvider casesWhereHttpStreamingInfluencesSeekability |
||
225 | */ |
||
226 | public function streaming_reads_are_not_seekable_and_non_streaming_are(bool $streaming, bool $seekable): void |
||
227 | { |
||
228 | if (getenv('COMPOSER_OPTS') === '--prefer-lowest') { |
||
229 | $this->markTestSkipped('The SDK does not support streaming in low versions.'); |
||
230 | } |
||
231 | |||
232 | $adapter = $this->useAdapter($this->createFilesystemAdapter($streaming)); |
||
233 | $this->givenWeHaveAnExistingFile('path.txt'); |
||
234 | |||
235 | $resource = $adapter->readStream('path.txt'); |
||
236 | $metadata = stream_get_meta_data($resource); |
||
237 | fclose($resource); |
||
238 | |||
239 | $this->assertEquals($seekable, $metadata['seekable']); |
||
240 | } |
||
241 | |||
242 | public function casesWhereHttpStreamingInfluencesSeekability(): Generator |
||
243 | { |
||
244 | yield "not streaming reads have seekable stream" => [false, true]; |
||
245 | yield "streaming reads have non-seekable stream" => [true, false]; |
||
246 | } |
||
247 | |||
248 | /** |
||
249 | * @test |
||
250 | * @dataProvider casesWhereHttpStreamingInfluencesSeekability |
||
251 | */ |
||
252 | public function configuring_http_streaming_via_options(bool $streaming): void |
||
253 | { |
||
254 | $adapter = $this->useAdapter($this->createFilesystemAdapter($streaming, ['@http' => ['stream' => false]])); |
||
255 | $this->givenWeHaveAnExistingFile('path.txt'); |
||
256 | |||
257 | $resource = $adapter->readStream('path.txt'); |
||
258 | $metadata = stream_get_meta_data($resource); |
||
259 | fclose($resource); |
||
260 | |||
261 | $this->assertTrue($metadata['seekable']); |
||
262 | } |
||
263 | |||
264 | /** |
||
265 | * @test |
||
266 | */ |
||
267 | public function moving_with_updated_metadata(): void |
||
268 | { |
||
269 | $adapter = $this->adapter(); |
||
270 | $adapter->write('source.txt', 'contents to be moved', new Config(['ContentType' => 'text/plain'])); |
||
271 | $mimeTypeSource = $adapter->mimeType('source.txt')->mimeType(); |
||
272 | $this->assertSame('text/plain', $mimeTypeSource); |
||
273 | |||
274 | $adapter->move('source.txt', 'destination.txt', new Config( |
||
275 | ['ContentType' => 'text/plain+special', 'MetadataDirective' => 'REPLACE'] |
||
276 | )); |
||
277 | $mimeTypeDestination = $adapter->mimeType('destination.txt')->mimeType(); |
||
278 | $this->assertSame('text/plain+special', $mimeTypeDestination); |
||
279 | } |
||
280 | |||
281 | protected static function createFilesystemAdapter(bool $streaming = true, array $options = []): FilesystemAdapter |
||
282 | { |
||
283 | static::$stubS3Client = new S3ClientStub(static::s3Client()); |
||
0 ignored issues
–
show
Since
$stubS3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $stubS3Client to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() Since
s3Client() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self , or increase the visibility of s3Client() to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static function getTemperature() {
return "3422 °C";
}
public static function getSomeVariable()
{
return static::getTemperature();
}
} The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass {
private static function getTemperature() {
return "-182 °C";
}
}
print YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class YourClass
{
private static function getTemperature() {
return "3422 °C";
}
public static function getSomeVariable()
{
return self::getTemperature();
}
}
![]() |
|||
284 | /** @var string $bucket */ |
||
285 | $bucket = getenv('FLYSYSTEM_AWS_S3_BUCKET'); |
||
286 | $prefix = getenv('FLYSYSTEM_AWS_S3_PREFIX') ?: static::$adapterPrefix; |
||
0 ignored issues
–
show
Since
$adapterPrefix is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $adapterPrefix to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() |
|||
287 | |||
288 | return new AwsS3V3Adapter(static::$stubS3Client, $bucket, $prefix, null, null, $options, $streaming); |
||
0 ignored issues
–
show
Since
$stubS3Client is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self , or increasing the visibility of $stubS3Client to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
![]() |
|||
289 | } |
||
290 | } |
||
291 |
Let’s assume you have a class which uses late-static binding:
The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the
getSomeVariable()
on that sub-class, you will receive a runtime error:In the case above, it makes sense to update
SomeClass
to useself
instead: