From c6d999b29e8226c89fd2e9b2cf61f5e13499b9eb Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 1 Oct 2025 16:26:32 +0530 Subject: [PATCH 1/5] fix: exists method to check for dirs --- src/Storage/Device/S3.php | 20 ++++++++++++++++---- tests/Storage/Device/LocalTest.php | 30 ++++++++++++++++++++++++++++++ tests/Storage/S3Base.php | 26 ++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/src/Storage/Device/S3.php b/src/Storage/Device/S3.php index c21bb9cb..9faaeec3 100644 --- a/src/Storage/Device/S3.php +++ b/src/Storage/Device/S3.php @@ -616,7 +616,7 @@ public function deletePath(string $path): bool } /** - * Check if file exists + * Check if file or directory exists * * @param string $path * @return bool @@ -625,11 +625,23 @@ public function exists(string $path): bool { try { $this->getInfo($path); + + return true; } catch (\Throwable $th) { - return false; - } + try { + $prefix = $this->getRoot().'/'.ltrim($path, '/'); + if (! empty($path) && ! str_ends_with($prefix, '/')) { + $prefix .= '/'; + } - return true; + $objects = $this->listObjects($prefix, 1); + $count = (int) ($objects['KeyCount'] ?? 0); + + return $count > 0; + } catch (\Throwable $th2) { + return false; + } + } } /** diff --git a/tests/Storage/Device/LocalTest.php b/tests/Storage/Device/LocalTest.php index c3d91b23..124accec 100644 --- a/tests/Storage/Device/LocalTest.php +++ b/tests/Storage/Device/LocalTest.php @@ -84,6 +84,36 @@ public function testFileExists() $this->object->delete($this->object->getPath('text-for-test-exists.txt')); } + public function testDirectoryExists() + { + $this->assertEquals(false, $this->object->exists($this->object->getPath('nonexistent-directory'))); + $this->assertEquals(false, $this->object->exists($this->object->getPath('nonexistent-directory/'))); + + $testDir = $this->object->getPath('test-directory-exists'); + $this->assertTrue($this->object->createDirectory($testDir)); + $this->assertEquals(true, $this->object->exists($testDir)); + $this->assertEquals(true, $this->object->exists($testDir.'/')); + + $nestedDir = $testDir.'/nested/deep/structure'; + $this->assertTrue($this->object->createDirectory($nestedDir)); + $this->object->write($nestedDir.'/test.txt', 'Hello World'); + + $this->assertEquals(true, $this->object->exists($testDir.'/nested')); + $this->assertEquals(true, $this->object->exists($testDir.'/nested/')); + $this->assertEquals(true, $this->object->exists($testDir.'/nested/deep')); + $this->assertEquals(true, $this->object->exists($testDir.'/nested/deep/')); + $this->assertEquals(true, $this->object->exists($nestedDir)); + $this->assertEquals(true, $this->object->exists($nestedDir.'/')); + + $this->assertEquals(true, $this->object->exists($nestedDir.'/test.txt')); + + $this->object->delete($testDir, true); + + $this->assertEquals(false, $this->object->exists($testDir)); + $this->assertEquals(false, $this->object->exists($testDir.'/nested')); + $this->assertEquals(false, $this->object->exists($nestedDir)); + } + public function testMove() { $this->assertEquals($this->object->write($this->object->getPath('text-for-move.txt'), 'Hello World'), true); diff --git a/tests/Storage/S3Base.php b/tests/Storage/S3Base.php index 314cfe02..338537a3 100644 --- a/tests/Storage/S3Base.php +++ b/tests/Storage/S3Base.php @@ -20,6 +20,11 @@ abstract protected function getAdapterName(): string; */ abstract protected function getAdapterDescription(): string; + /** + * @return string + */ + abstract protected function getAdapterType(): string; + /** * @var S3 */ @@ -139,6 +144,27 @@ public function testFileExists() $this->assertEquals(false, $this->object->exists($this->object->getPath('testing/kitten-5.jpg'))); } + public function testDirectoryExists() + { + $this->assertEquals(true, $this->object->exists($this->object->getPath('testing/'))); + + $this->assertEquals(false, $this->object->exists($this->object->getPath('nonexistent/'))); + + $this->object->write($this->object->getPath('nested/deep/structure/test.txt'), 'Hello World', 'text/plain'); + + $this->assertEquals(true, $this->object->exists($this->object->getPath('nested'))); + $this->assertEquals(true, $this->object->exists($this->object->getPath('nested/deep'))); + $this->assertEquals(true, $this->object->exists($this->object->getPath('nested/deep/structure'))); + + $this->assertEquals(true, $this->object->exists($this->object->getPath('nested/deep/structure/test.txt'))); + + $this->object->delete($this->object->getPath('nested/deep/structure/test.txt')); + + $this->assertEquals(false, $this->object->exists($this->object->getPath('nested'))); + $this->assertEquals(false, $this->object->exists($this->object->getPath('nested/deep'))); + $this->assertEquals(false, $this->object->exists($this->object->getPath('nested/deep/structure'))); + } + public function testMove() { $this->assertEquals(true, $this->object->write($this->object->getPath('text-for-move.txt'), 'Hello World', 'text/plain')); From fb2f4209b92dfeacff216859c0781cdbea4a66be Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 1 Oct 2025 16:40:50 +0530 Subject: [PATCH 2/5] trigger ci From 6c8a5925606b141b2262642186575d157c4eee48 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 1 Oct 2025 17:14:58 +0530 Subject: [PATCH 3/5] fix: prefix --- src/Storage/Device/S3.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Storage/Device/S3.php b/src/Storage/Device/S3.php index 9faaeec3..0cf8ba41 100644 --- a/src/Storage/Device/S3.php +++ b/src/Storage/Device/S3.php @@ -630,10 +630,12 @@ public function exists(string $path): bool } catch (\Throwable $th) { try { $prefix = $this->getRoot().'/'.ltrim($path, '/'); + if (! empty($path) && ! str_ends_with($prefix, '/')) { $prefix .= '/'; } + $prefix = ltrim($prefix, '/'); $objects = $this->listObjects($prefix, 1); $count = (int) ($objects['KeyCount'] ?? 0); From 71a4fc3bafab5b43dde2890e4bcc1e63363e2005 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 1 Oct 2025 17:24:03 +0530 Subject: [PATCH 4/5] lint --- src/Storage/Device/S3.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Storage/Device/S3.php b/src/Storage/Device/S3.php index 0cf8ba41..ca703165 100644 --- a/src/Storage/Device/S3.php +++ b/src/Storage/Device/S3.php @@ -630,7 +630,7 @@ public function exists(string $path): bool } catch (\Throwable $th) { try { $prefix = $this->getRoot().'/'.ltrim($path, '/'); - + if (! empty($path) && ! str_ends_with($prefix, '/')) { $prefix .= '/'; } From 77e0cf218db6ad4db07228a7537182ad2989d49d Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Wed, 1 Oct 2025 17:41:07 +0530 Subject: [PATCH 5/5] fix: root check --- src/Storage/Device/S3.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Storage/Device/S3.php b/src/Storage/Device/S3.php index ca703165..cab37c82 100644 --- a/src/Storage/Device/S3.php +++ b/src/Storage/Device/S3.php @@ -629,13 +629,17 @@ public function exists(string $path): bool return true; } catch (\Throwable $th) { try { - $prefix = $this->getRoot().'/'.ltrim($path, '/'); + $root = $this->getRoot(); + if (str_starts_with($path, $root.'/') || str_starts_with($path, $root.'\\')) { + $prefix = $path; + } else { + $prefix = $root.'/'.ltrim($path, '/'); + } if (! empty($path) && ! str_ends_with($prefix, '/')) { $prefix .= '/'; } - $prefix = ltrim($prefix, '/'); $objects = $this->listObjects($prefix, 1); $count = (int) ($objects['KeyCount'] ?? 0);