Skip to content

Commit 0a08f8e

Browse files
committed
PHPLIB-1323 Implement unlink for GridFS stream wrapper
1 parent 8470f88 commit 0a08f8e

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
@@ -48,6 +48,7 @@ Supported stream functions:
4848
- :php:`filesize() <filesize>`
4949
- :php:`file() <file>`
5050
- :php:`fopen() <fopen>` (with "r", "rb", "w", and "wb" modes)
51+
- :php:`unlink() <unlink>` (remove all revisions of a file)
5152

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

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

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

9093
.. code-block:: none

src/GridFS/StreamWrapper.php

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

300+
public function unlink(string $path): bool
301+
{
302+
try {
303+
$this->stream_open($path, 'w', 0, $openedPath);
304+
} catch (FileNotFoundException $e) {
305+
return false;
306+
}
307+
308+
assert($this->stream instanceof WritableStream);
309+
310+
return $this->stream->delete() > 0;
311+
}
312+
300313
/** @return false|array */
301314
public function url_stat(string $path, int $flags)
302315
{

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
@@ -28,6 +28,7 @@
2828
use function stream_context_create;
2929
use function stream_get_contents;
3030
use function time;
31+
use function unlink;
3132
use function usleep;
3233

3334
use const SEEK_CUR;
@@ -363,4 +364,18 @@ public function testCopy(): void
363364
$this->assertSame('foobar', file_get_contents($path . '.copy'));
364365
$this->assertSame('foobar', file_get_contents($path));
365366
}
367+
368+
public function testUnlinkDeleteAllRevisions(): void
369+
{
370+
$this->bucket->registerGlobalStreamWrapperAlias('bucket');
371+
$path = 'gridfs://bucket/path/to/filename';
372+
373+
file_put_contents($path, 'version 0');
374+
file_put_contents($path, 'version 1');
375+
376+
$result = unlink($path);
377+
378+
$this->assertTrue($result);
379+
$this->assertFalse(file_exists($path));
380+
}
366381
}

0 commit comments

Comments
 (0)