Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/Storage/Device.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,14 @@ abstract public function deletePath(string $path): bool;
*/
abstract public function exists(string $path): bool;

/**
* Check if directory exists
*
* @param string $path
* @return bool
*/
abstract public function directoryExists(string $path): bool;

/**
* Returns given file path its size.
*
Expand Down
11 changes: 11 additions & 0 deletions src/Storage/Device/Local.php
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,17 @@ public function exists(string $path): bool
return \file_exists($path);
}

/**
* Check if directory exists
*
* @param string $path
* @return bool
*/
public function directoryExists(string $path): bool
{
return \is_dir($path);
}

/**
* Returns given file path its size.
*
Expand Down
24 changes: 24 additions & 0 deletions src/Storage/Device/S3.php
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,30 @@ public function exists(string $path): bool
return true;
}

/**
* Check if directory exists
*
* In S3, directories are virtual. We check if any objects exist with the given prefix.
*
* @param string $path
* @return bool
*/
public function directoryExists(string $path): bool
{
try {
// Ensure path ends with / for directory prefix search
$prefix = rtrim($path, '/').'/';
$prefix = ltrim($prefix, '/'); // S3 specific requirement that prefix should never contain a leading slash

$objects = $this->listObjects($prefix, 1); // Only need to check if at least one object exists

// Check if any objects exist with this prefix
return isset($objects['KeyCount']) && (int) $objects['KeyCount'] > 0;
} catch (\Throwable $th) {
return false;
}
}

/**
* Returns given file path its size.
*
Expand Down
19 changes: 19 additions & 0 deletions tests/Storage/Device/LocalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,25 @@ public function testFileExists()
$this->object->delete($this->object->getPath('text-for-test-exists.txt'));
}

public function testDirectoryExists()
{
// Test existing directory
$this->assertEquals(true, $this->object->directoryExists(__DIR__.'/../../resources/disk-a'));
$this->assertEquals(true, $this->object->directoryExists(__DIR__.'/../../resources/disk-b'));

// Test non-existing directory
$this->assertEquals(false, $this->object->directoryExists(__DIR__.'/../../resources/nonexistent'));

// Test creating and checking directory
$testDir = $this->object->getPath('test-directory');
$this->assertEquals(false, $this->object->directoryExists($testDir));
$this->assertEquals(true, $this->object->createDirectory($testDir));
$this->assertEquals(true, $this->object->directoryExists($testDir));

// Cleanup
rmdir($testDir);
}

public function testMove()
{
$this->assertEquals($this->object->write($this->object->getPath('text-for-move.txt'), 'Hello World'), true);
Expand Down
25 changes: 25 additions & 0 deletions tests/Storage/S3Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ abstract protected function getAdapterName(): string;
*/
abstract protected function getAdapterDescription(): string;

/**
* @return string
*/
abstract protected function getAdapterType(): string;

/**
* @var S3
*/
Expand Down Expand Up @@ -139,6 +144,26 @@ public function testFileExists()
$this->assertEquals(false, $this->object->exists($this->object->getPath('testing/kitten-5.jpg')));
}

public function testDirectoryExists()
{
// Test existing directory with files
$this->assertEquals(true, $this->object->directoryExists($this->object->getPath('testing')));
$this->assertEquals(true, $this->object->directoryExists($this->object->getPath('testing/')));

// Test non-existing directory
$this->assertEquals(false, $this->object->directoryExists($this->object->getPath('nonexistent')));
$this->assertEquals(false, $this->object->directoryExists($this->object->getPath('nonexistent/')));

// Test nested directory structure
$this->object->write($this->object->getPath('nested/deep/file.txt'), 'test content', 'text/plain');
$this->assertEquals(true, $this->object->directoryExists($this->object->getPath('nested')));
$this->assertEquals(true, $this->object->directoryExists($this->object->getPath('nested/deep')));
$this->assertEquals(false, $this->object->directoryExists($this->object->getPath('nested/nonexistent')));

// Cleanup
$this->object->delete($this->object->getPath('nested/deep/file.txt'));
}

public function testMove()
{
$this->assertEquals(true, $this->object->write($this->object->getPath('text-for-move.txt'), 'Hello World', 'text/plain'));
Expand Down