Skip to content

Commit 2f76c46

Browse files
author
Will Banfield
committed
PHPLIB-154: implement downloadByName
1 parent c787545 commit 2f76c46

File tree

5 files changed

+75
-7
lines changed

5 files changed

+75
-7
lines changed

src/GridFS/Bucket.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,19 @@ private function isFilesCollectionEmpty()
171171
'projection' => ['_id' => 1],
172172
]);
173173
}
174+
public function findFileRevision($filename, $revision)
175+
{
176+
if ($revision < 0) {
177+
$skip = abs($revision) -1;
178+
$sortOrder = -1;
179+
} else {
180+
$skip = $revision;
181+
$sortOrder = 1;
182+
}
183+
$file = $this->filesCollection->findOne(["filename"=> $filename], ["sort" => ["uploadDate"=> $sortOrder], "limit"=>1, "skip" => $skip]);
184+
if(is_null($file)) {
185+
throw new \MongoDB\Exception\GridFSFileNotFoundException($filename, $this->getBucketName(), $this->getDatabaseName());;
186+
}
187+
return $file;
188+
}
174189
}

src/GridFS/BucketReadWriter.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,33 @@ public function delete(\MongoDB\BSON\ObjectId $id)
8484

8585
$this->bucket->getFilesCollection()->deleteOne(['_id' => $id], $options);
8686
}
87+
/**
88+
* Open a stream to download a file from the GridFS bucket. Searches for the file by the specified name then returns a stream to the specified file
89+
* @param string $filename name of the file to download
90+
* @param int $revision the revision of the file to download
91+
* @throws GridFSFileNotFoundException
92+
*/
93+
public function openDownloadStreamByName($filename, $revision = -1)
94+
{
95+
$file = $this->bucket->findFileRevision($filename, $revision);
96+
$options = ['bucket' => $this->bucket,
97+
'file' => $file
98+
];
99+
$context = stream_context_create(['gridfs' => $options]);
100+
return fopen(sprintf('gridfs://%s/%s', $this->bucket->getDatabaseName(), $filename), 'r', false, $context);
101+
}
102+
/**
103+
* Download a file from the GridFS bucket by name. Searches for the file by the specified name then loads data into the stream
104+
*
105+
* @param string $filename name of the file to download
106+
* @param int $revision the revision of the file to download
107+
* @throws GridFSFileNotFoundException
108+
*/
109+
public function downloadToStreamByName($filename, $destination, $revision=-1)
110+
{
111+
$file = $this->bucket->findFileRevision($filename, $revision);
112+
$gridFsStream = new GridFsDownload($this->bucket, null, $file);
113+
$gridFsStream->downloadToStream($destination);
114+
}
115+
87116
}

src/GridFS/GridFsDownload.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,17 @@ class GridFsDownload extends GridFsStream
4040
*/
4141
public function __construct(
4242
Bucket $bucket,
43-
ObjectId $objectId
43+
$objectId,
44+
$file = null
4445
)
4546
{
46-
$this->file = $bucket->getFilesCollection()->findOne(['_id' => $objectId]);
47-
if (is_null($this->file)) {
48-
throw new \MongoDB\Exception\GridFSFileNotFoundException($objectId, $bucket->getBucketName(), $bucket->getDatabaseName());
47+
if(!is_null($file)) {
48+
$this->file = $file;
49+
} else {
50+
$this->file = $bucket->getFilesCollection()->findOne(['_id' => $objectId]);
51+
if (is_null($this->file)) {
52+
throw new \MongoDB\Exception\GridFSFileNotFoundException($objectId, $bucket->getBucketName(), $bucket->getDatabaseName());
53+
}
4954
}
5055
if ($this->file->length > 0) {
5156
$cursor = $bucket->getChunksCollection()->find(['files_id' => $this->file->_id], ['sort' => ['n' => 1]]);

src/GridFS/StreamWrapper.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,15 @@ public function openWriteStream() {
7272
$this->gridFsStream = new GridFsUpload($this->bucket, $this->identifier, $options);
7373
return true;
7474
}
75+
7576
public function openReadStream() {
76-
$objectId = new \MongoDB\BSON\ObjectId($this->identifier);
77-
$this->gridFsStream = new GridFsDownload($this->bucket, $objectId);
77+
$context = stream_context_get_options($this->context);
78+
if(isset($context['gridfs']['file'])){
79+
$this->gridFsStream = new GridFsDownload($this->bucket, null, $context['gridfs']['file']);
80+
} else {
81+
$objectId = new \MongoDB\BSON\ObjectId($this->identifier);
82+
$this->gridFsStream = new GridFsDownload($this->bucket, $objectId);
83+
}
7884
return true;
7985
}
8086
}

tests/GridFS/SpecificationTests.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public function testSpecificationTests($testJson)
9191

9292
public function provideSpecificationTests()
9393
{
94-
$testPath=getcwd().'/tests/GridFS/Specification/tests/delete.json';
94+
$testPath=getcwd().'/tests/GridFS/Specification/tests/download_by_name.json';
9595

9696
$testArgs = [];
9797
foreach(glob($testPath) as $filename) {
@@ -237,6 +237,19 @@ function deleteCommand($args)
237237
}
238238
function download_by_nameCommand($args)
239239
{
240+
$args = $this->fixTypes($args, false);
241+
$streamWrapper = new \MongoDB\GridFS\StreamWrapper();
242+
$streamWrapper->register($this->manager);
243+
$stream = fopen('php://temp', 'w+');
244+
if(isset($args['options']['revision'])) {
245+
$this->bucketReadWriter->downloadToStreamByName($args['filename'], $stream, $args['options']['revision']);
246+
} else {
247+
$this->bucketReadWriter->downloadToStreamByName($args['filename'], $stream);
248+
}
249+
rewind($stream);
250+
$result = stream_get_contents($stream);
251+
fclose($stream);
252+
return $result;
240253

241254
}
242255
}

0 commit comments

Comments
 (0)