Skip to content

Commit 69c9b63

Browse files
committed
PHPLIB-1323 Implement unlink for GridFS stream wrapper
1 parent 401bbd7 commit 69c9b63

File tree

4 files changed

+59
-0
lines changed

4 files changed

+59
-0
lines changed

docs/reference/method/MongoDBGridFSBucket-registerGlobalStreamWrapperAlias.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Supported stream functions:
4949
- :php:`file() <file>`
5050
- :php:`fopen() <fopen>` with "r", "rb", "w", and "wb" modes
5151
- :php:`rename() <rename>` rename all revisions of a file in the same bucket
52+
- :php:`unlink() <unlink>` (remove all revisions of a file)
5253

5354
In read mode, the stream context can contain the option ``gridfs['revision']``
5455
to specify the revision number of the file to read. If omitted, the most recent
@@ -86,6 +87,8 @@ Each call to these functions makes a request to the server.
8687

8788
echo file_get_contents('gridfs://mybucket/hello.txt');
8889

90+
unlink('gridfs://mybucket/hello.txt');
91+
8992
The output would then resemble:
9093

9194
.. code-block:: none

src/GridFS/StreamWrapper.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,19 @@ public function stream_write(string $data): int
324324
return $this->stream->writeBytes($data);
325325
}
326326

327+
public function unlink(string $path): bool
328+
{
329+
try {
330+
$this->stream_open($path, 'w', 0, $openedPath);
331+
} catch (FileNotFoundException $e) {
332+
return false;
333+
}
334+
335+
assert($this->stream instanceof WritableStream);
336+
337+
return $this->stream->delete() > 0;
338+
}
339+
327340
/** @return false|array */
328341
public function url_stat(string $path, int $flags)
329342
{

src/GridFS/WritableStream.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
use HashContext;
2121
use MongoDB\BSON\Binary;
22+
use MongoDB\BSON\Document;
2223
use MongoDB\BSON\ObjectId;
2324
use MongoDB\BSON\UTCDateTime;
2425
use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
@@ -173,6 +174,33 @@ public function close(): void
173174
$this->isClosed = true;
174175
}
175176

177+
/**
178+
* Delete all files and chunks associated with this stream filename.
179+
*
180+
* @return int The number of deleted files
181+
*/
182+
public function delete(): int
183+
{
184+
/** @var Document[] $revisions */
185+
$revisions = $this->collectionWrapper->findFiles(['filename' => $this->file['filename']], [
186+
'codec' => null,
187+
'typeMap' => ['root' => 'bson'],
188+
'projection' => ['_id' => 1],
189+
]);
190+
191+
$count = 0;
192+
193+
foreach ($revisions as $file) {
194+
$this->collectionWrapper->findFileById($file->get('_id'));
195+
$this->collectionWrapper->deleteFileAndChunksById($file->get('_id'));
196+
$count++;
197+
}
198+
199+
$this->abort();
200+
201+
return $count;
202+
}
203+
176204
/**
177205
* Return the stream's file document.
178206
*/

tests/GridFS/StreamWrapperFunctionalTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use function stream_context_create;
3030
use function stream_get_contents;
3131
use function time;
32+
use function unlink;
3233
use function usleep;
3334

3435
use const SEEK_CUR;
@@ -387,4 +388,18 @@ public function testRenamePathMismatch(): void
387388

388389
rename('gridfs://bucket/filename', 'gridfs://other/newname');
389390
}
391+
392+
public function testUnlinkAllRevisions(): void
393+
{
394+
$this->bucket->registerGlobalStreamWrapperAlias('bucket');
395+
$path = 'gridfs://bucket/path/to/filename';
396+
397+
file_put_contents($path, 'version 0');
398+
file_put_contents($path, 'version 1');
399+
400+
$result = unlink($path);
401+
402+
$this->assertTrue($result);
403+
$this->assertFalse(file_exists($path));
404+
}
390405
}

0 commit comments

Comments
 (0)