Skip to content

Commit ed8d596

Browse files
authored
Merge pull request #35 from tinect/addPrefixPath
feat: add prefixPath
2 parents 2d4c4b3 + b25d2c0 commit ed8d596

File tree

2 files changed

+185
-4
lines changed

2 files changed

+185
-4
lines changed

src/BunnyCDNAdapter.php

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,21 @@ class BunnyCDNAdapter implements FilesystemAdapter
4040
*/
4141
private BunnyCDNClient $client;
4242

43+
/**
44+
* @var string
45+
*/
46+
private string $prefixPath;
47+
4348
/**
4449
* @param BunnyCDNClient $client
4550
* @param string $pullzone_url
51+
* @param string $prefixPath
4652
*/
47-
public function __construct(BunnyCDNClient $client, string $pullzone_url = '')
53+
public function __construct(BunnyCDNClient $client, string $pullzone_url = '', string $prefixPath = '')
4854
{
4955
$this->client = $client;
5056
$this->pullzone_url = $pullzone_url;
57+
$this->prefixPath = rtrim($prefixPath, '/');
5158
}
5259

5360
/**
@@ -58,6 +65,9 @@ public function __construct(BunnyCDNClient $client, string $pullzone_url = '')
5865
*/
5966
public function copy($source, $destination, Config $config): void
6067
{
68+
$this->prependPrefix($source);
69+
$this->prependPrefix($destination);
70+
6171
try {
6272
$this->write($destination, $this->read($source), new Config());
6373
// @codeCoverageIgnoreStart
@@ -74,6 +84,8 @@ public function copy($source, $destination, Config $config): void
7484
*/
7585
public function write($path, $contents, Config $config): void
7686
{
87+
$this->prependPrefix($path);
88+
7789
try {
7890
$this->client->upload($path, $contents);
7991
// @codeCoverageIgnoreStart
@@ -89,6 +101,8 @@ public function write($path, $contents, Config $config): void
89101
*/
90102
public function read($path): string
91103
{
104+
$this->prependPrefix($path);
105+
92106
try {
93107
return $this->client->download($path);
94108
// @codeCoverageIgnoreStart
@@ -105,6 +119,8 @@ public function read($path): string
105119
*/
106120
public function listContents(string $path = '', bool $deep = false): iterable
107121
{
122+
$this->prependPrefix($path);
123+
108124
try {
109125
$entries = $this->client->list($path);
110126
// @codeCoverageIgnoreStart
@@ -188,6 +204,8 @@ private function extractExtraMetadata(array $bunny_file_array): array
188204
*/
189205
public function detectMimeType(string $path): string
190206
{
207+
$this->prependPrefix($path);
208+
191209
try {
192210
$detector = new FinfoMimeTypeDetector();
193211
$mimeType = $detector->detectMimeTypeFromPath($path);
@@ -210,6 +228,8 @@ public function detectMimeType(string $path): string
210228
*/
211229
public function writeStream($path, $contents, Config $config): void
212230
{
231+
$this->prependPrefix($path);
232+
213233
$this->write($path, stream_get_contents($contents), $config);
214234
}
215235

@@ -236,6 +256,8 @@ public function readStream($path)
236256
*/
237257
public function deleteDirectory(string $path): void
238258
{
259+
$this->prependPrefix($path);
260+
239261
try {
240262
$this->client->delete(
241263
rtrim($path, '/').'/'
@@ -253,6 +275,8 @@ public function deleteDirectory(string $path): void
253275
*/
254276
public function createDirectory(string $path, Config $config): void
255277
{
278+
$this->prependPrefix($path);
279+
256280
try {
257281
$this->client->make_directory($path);
258282
// @codeCoverageIgnoreStart
@@ -272,6 +296,8 @@ public function createDirectory(string $path, Config $config): void
272296
*/
273297
public function setVisibility(string $path, string $visibility): void
274298
{
299+
$this->prependPrefix($path);
300+
275301
throw UnableToSetVisibility::atLocation($path, 'BunnyCDN does not support visibility');
276302
}
277303

@@ -280,6 +306,8 @@ public function setVisibility(string $path, string $visibility): void
280306
*/
281307
public function visibility(string $path): FileAttributes
282308
{
309+
$this->prependPrefix($path);
310+
283311
try {
284312
return new FileAttributes($this->getObject($path)->path(), null, $this->pullzone_url ? 'public' : 'private');
285313
} catch (UnableToReadFile|TypeError $e) {
@@ -295,6 +323,8 @@ public function visibility(string $path): FileAttributes
295323
*/
296324
public function mimeType(string $path): FileAttributes
297325
{
326+
$this->prependPrefix($path);
327+
298328
try {
299329
$object = $this->getObject($path);
300330

@@ -333,6 +363,8 @@ public function mimeType(string $path): FileAttributes
333363
*/
334364
protected function getObject(string $path = ''): StorageAttributes
335365
{
366+
$this->prependPrefix($path);
367+
336368
$directory = pathinfo($path, PATHINFO_DIRNAME);
337369
$list = (new DirectoryListing($this->listContents($directory)))
338370
->filter(function (StorageAttributes $item) use ($path) {
@@ -358,6 +390,8 @@ protected function getObject(string $path = ''): StorageAttributes
358390
*/
359391
public function lastModified(string $path): FileAttributes
360392
{
393+
$this->prependPrefix($path);
394+
361395
try {
362396
return $this->getObject($path);
363397
} catch (UnableToReadFile $e) {
@@ -373,6 +407,8 @@ public function lastModified(string $path): FileAttributes
373407
*/
374408
public function fileSize(string $path): FileAttributes
375409
{
410+
$this->prependPrefix($path);
411+
376412
try {
377413
return $this->getObject($path);
378414
} catch (UnableToReadFile $e) {
@@ -388,6 +424,9 @@ public function fileSize(string $path): FileAttributes
388424
*/
389425
public function move(string $source, string $destination, Config $config): void
390426
{
427+
$this->prependPrefix($source);
428+
$this->prependPrefix($destination);
429+
391430
try {
392431
$this->write($destination, $this->read($source), new Config());
393432
$this->delete($source);
@@ -402,6 +441,8 @@ public function move(string $source, string $destination, Config $config): void
402441
*/
403442
public function delete($path): void
404443
{
444+
$this->prependPrefix($path);
445+
405446
try {
406447
$this->client->delete($path);
407448
// @codeCoverageIgnoreStart
@@ -427,6 +468,8 @@ public function directoryExists(string $path): bool
427468
*/
428469
public function fileExists(string $path): bool
429470
{
471+
$this->prependPrefix($path);
472+
430473
$list = new DirectoryListing($this->listContents(
431474
Util::splitPathIntoDirectoryAndFile($path)['dir']
432475
));
@@ -459,4 +502,21 @@ private static function parse_bunny_timestamp(string $timestamp): int
459502
{
460503
return (date_create_from_format('Y-m-d\TH:i:s.u', $timestamp) ?: date_create_from_format('Y-m-d\TH:i:s', $timestamp))->getTimestamp();
461504
}
505+
506+
private function prependPrefix(string &$path): void
507+
{
508+
if ($this->prefixPath === '') {
509+
return;
510+
}
511+
512+
if ($path === $this->prefixPath) {
513+
return;
514+
}
515+
516+
if (\str_starts_with($path, $this->prefixPath.'/')) {
517+
return;
518+
}
519+
520+
$path = $this->prefixPath.'/'.$path;
521+
}
462522
}

tests/FlysystemTestSuite.php

Lines changed: 124 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,21 @@ class FlysystemTestSuite extends FilesystemAdapterTestCase
2323
{
2424
const STORAGE_ZONE = 'testing_storage_zone';
2525

26+
/**
27+
* @var FilesystemAdapter|null
28+
*/
29+
protected static ?FilesystemAdapter $prefixAdapter = null;
30+
31+
/**
32+
* @var BunnyCDNClient|null
33+
*/
34+
protected static ?BunnyCDNClient $bunnyCDNClient = null;
35+
36+
/**
37+
* @var string|null
38+
*/
39+
protected static ?string $prefixPath = null;
40+
2641
/**
2742
* Used for testing protected methods
2843
*
@@ -37,8 +52,26 @@ public static function callMethod($obj, $name, array $args)
3752
return $method->invokeArgs($obj, $args);
3853
}
3954

40-
public static function createFilesystemAdapter(): FilesystemAdapter
55+
public static function setUpBeforeClass(): void
56+
{
57+
static::$prefixPath = 'test'.bin2hex(random_bytes(10));
58+
}
59+
60+
public function prefixAdapter(): FilesystemAdapter
4161
{
62+
if (! static::$prefixAdapter instanceof FilesystemAdapter) {
63+
static::$prefixAdapter = static::createFilesystemAdapter(static::$prefixPath);
64+
}
65+
66+
return static::$prefixAdapter;
67+
}
68+
69+
private static function bunnyCDNClient(): BunnyCDNClient
70+
{
71+
if (static::$bunnyCDNClient instanceof BunnyCDNClient) {
72+
return static::$bunnyCDNClient;
73+
}
74+
4275
$filesystem = new Filesystem(new InMemoryFilesystemAdapter());
4376

4477
$mock_client = Mockery::mock(new BunnyCDNClient(self::STORAGE_ZONE, 'api-key'));
@@ -68,15 +101,103 @@ public static function createFilesystemAdapter(): FilesystemAdapter
68101
});
69102

70103
$mock_client->shouldReceive('make_directory')->andReturnUsing(function ($path) use ($filesystem) {
71-
return $filesystem->createDirectory($path);
104+
$filesystem->createDirectory($path);
72105
});
73106

74107
$mock_client->shouldReceive('delete')->andReturnUsing(function ($path) use ($filesystem) {
75108
$filesystem->deleteDirectory($path);
76109
$filesystem->delete($path);
77110
});
78111

79-
return new BunnyCDNAdapter($mock_client);
112+
static::$bunnyCDNClient = $mock_client;
113+
114+
return static::$bunnyCDNClient;
115+
}
116+
117+
public static function createFilesystemAdapter(string $prefixPath = ''): FilesystemAdapter
118+
{
119+
return new BunnyCDNAdapter(static::bunnyCDNClient(), '', $prefixPath);
120+
}
121+
122+
/**
123+
* @test
124+
*/
125+
public function prefix_path(): void
126+
{
127+
$this->runScenario(function () {
128+
$adapter = $this->adapter();
129+
$prefixPathAdapter = $this->prefixAdapter();
130+
131+
self::assertNotEmpty(
132+
static::$prefixPath
133+
);
134+
135+
self::assertIsString(
136+
static::$prefixPath
137+
);
138+
139+
$content = 'this is test';
140+
$prefixPathAdapter->write(
141+
'source.file.svg',
142+
$content,
143+
new Config([Config::OPTION_VISIBILITY => Visibility::PUBLIC])
144+
);
145+
146+
self::assertTrue($prefixPathAdapter->fileExists(
147+
'source.file.svg'
148+
));
149+
150+
self::assertTrue($adapter->directoryExists(
151+
static::$prefixPath
152+
));
153+
154+
self::assertTrue($adapter->fileExists(
155+
static::$prefixPath.'/source.file.svg'
156+
));
157+
158+
$prefixPathAdapter->copy(
159+
'source.file.svg',
160+
'source.copy.file.svg',
161+
new Config([Config::OPTION_VISIBILITY => Visibility::PUBLIC])
162+
);
163+
164+
self::assertTrue($adapter->fileExists(
165+
static::$prefixPath.'/source.copy.file.svg'
166+
));
167+
168+
self::assertTrue($prefixPathAdapter->fileExists(
169+
'source.copy.file.svg'
170+
));
171+
172+
$prefixPathAdapter->delete(
173+
'source.copy.file.svg'
174+
);
175+
176+
$this->assertEquals($content, $prefixPathAdapter->read('source.file.svg'));
177+
178+
$this->assertEquals(
179+
$prefixPathAdapter->read('source.file.svg'),
180+
$adapter->read(static::$prefixPath.'/source.file.svg')
181+
);
182+
183+
$this->assertSame(
184+
'image/svg+xml',
185+
$prefixPathAdapter->mimeType('source.file.svg')->mimeType()
186+
);
187+
188+
$this->assertEquals(
189+
$prefixPathAdapter->mimeType('source.file.svg')->mimeType(),
190+
$adapter->mimeType(static::$prefixPath.'/source.file.svg')->mimeType()
191+
);
192+
193+
$prefixPathAdapter->delete(
194+
'source.file.svg'
195+
);
196+
197+
self::assertFalse($prefixPathAdapter->fileExists(
198+
'source.file.svg'
199+
));
200+
});
80201
}
81202

82203
/**

0 commit comments

Comments
 (0)