@@ -23,6 +23,11 @@ class Bucket
23
23
{
24
24
private static $ defaultBucketName = 'fs ' ;
25
25
private static $ defaultChunkSizeBytes = 261120 ;
26
+ private static $ defaultTypeMap = [
27
+ 'array ' => 'MongoDB\Model\BSONArray ' ,
28
+ 'document ' => 'MongoDB\Model\BSONDocument ' ,
29
+ 'root ' => 'MongoDB\Model\BSONDocument ' ,
30
+ ];
26
31
private static $ streamWrapperProtocol = 'gridfs ' ;
27
32
28
33
private $ collectionWrapper ;
@@ -32,6 +37,7 @@ class Bucket
32
37
private $ chunkSizeBytes ;
33
38
private $ readConcern ;
34
39
private $ readPreference ;
40
+ private $ typeMap ;
35
41
private $ writeConcern ;
36
42
37
43
/**
@@ -49,6 +55,8 @@ class Bucket
49
55
*
50
56
* * readPreference (MongoDB\Driver\ReadPreference): Read preference.
51
57
*
58
+ * * typeMap (array): Default type map for cursors and BSON documents.
59
+ *
52
60
* * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
53
61
*
54
62
* @param Manager $manager Manager instance from the driver
@@ -79,6 +87,10 @@ public function __construct(Manager $manager, $databaseName, array $options = []
79
87
throw InvalidArgumentException::invalidType ('"readPreference" option ' , $ options ['readPreference ' ], 'MongoDB\Driver\ReadPreference ' );
80
88
}
81
89
90
+ if (isset ($ options ['typeMap ' ]) && ! is_array ($ options ['typeMap ' ])) {
91
+ throw InvalidArgumentException::invalidType ('"typeMap" option ' , $ options ['typeMap ' ], 'array ' );
92
+ }
93
+
82
94
if (isset ($ options ['writeConcern ' ]) && ! $ options ['writeConcern ' ] instanceof WriteConcern) {
83
95
throw InvalidArgumentException::invalidType ('"writeConcern" option ' , $ options ['writeConcern ' ], 'MongoDB\Driver\WriteConcern ' );
84
96
}
@@ -89,9 +101,10 @@ public function __construct(Manager $manager, $databaseName, array $options = []
89
101
$ this ->chunkSizeBytes = $ options ['chunkSizeBytes ' ];
90
102
$ this ->readConcern = isset ($ options ['readConcern ' ]) ? $ options ['readConcern ' ] : $ this ->manager ->getReadConcern ();
91
103
$ this ->readPreference = isset ($ options ['readPreference ' ]) ? $ options ['readPreference ' ] : $ this ->manager ->getReadPreference ();
104
+ $ this ->typeMap = isset ($ options ['typeMap ' ]) ? $ options ['typeMap ' ] : self ::$ defaultTypeMap ;
92
105
$ this ->writeConcern = isset ($ options ['writeConcern ' ]) ? $ options ['writeConcern ' ] : $ this ->manager ->getWriteConcern ();
93
106
94
- $ collectionOptions = array_intersect_key ($ options , ['readConcern ' => 1 , 'readPreference ' => 1 , 'writeConcern ' => 1 ]);
107
+ $ collectionOptions = array_intersect_key ($ options , ['readConcern ' => 1 , 'readPreference ' => 1 , 'typeMap ' => 1 , ' writeConcern ' => 1 ]);
95
108
96
109
$ this ->collectionWrapper = new CollectionWrapper ($ manager , $ databaseName , $ options ['bucketName ' ], $ collectionOptions );
97
110
$ this ->registerStreamWrapper ();
@@ -112,6 +125,7 @@ public function __debugInfo()
112
125
'chunkSizeBytes ' => $ this ->chunkSizeBytes ,
113
126
'readConcern ' => $ this ->readConcern ,
114
127
'readPreference ' => $ this ->readPreference ,
128
+ 'typeMap ' => $ this ->typeMap ,
115
129
'writeConcern ' => $ this ->writeConcern ,
116
130
];
117
131
}
@@ -233,22 +247,15 @@ public function getDatabaseName()
233
247
* Gets the file document of the GridFS file associated with a stream.
234
248
*
235
249
* @param resource $stream GridFS stream
236
- * @return stdClass
250
+ * @return array|object
237
251
* @throws InvalidArgumentException
238
252
*/
239
253
public function getFileDocumentForStream ($ stream )
240
254
{
241
- if ( ! is_resource ($ stream ) || get_resource_type ($ stream ) != "stream " ) {
242
- throw InvalidArgumentException::invalidType ('$stream ' , $ stream , 'resource ' );
243
- }
255
+ $ file = $ this ->getRawFileDocumentForStream ($ stream );
244
256
245
- $ metadata = stream_get_meta_data ($ stream );
246
-
247
- if (!$ metadata ['wrapper_data ' ] instanceof StreamWrapper) {
248
- throw InvalidArgumentException::invalidType ('$stream wrapper data ' , $ metadata ['wrapper_data ' ], 'MongoDB\Driver\GridFS\StreamWrapper ' );
249
- }
250
-
251
- return $ metadata ['wrapper_data ' ]->getFile ();
257
+ // Filter the raw document through the specified type map
258
+ return \MongoDB \BSON \toPHP (\MongoDB \BSON \fromPHP ($ file ), $ this ->typeMap );
252
259
}
253
260
254
261
/**
@@ -261,7 +268,13 @@ public function getFileDocumentForStream($stream)
261
268
*/
262
269
public function getFileIdForStream ($ stream )
263
270
{
264
- $ file = $ this ->getFileDocumentForStream ($ stream );
271
+ $ file = $ this ->getRawFileDocumentForStream ($ stream );
272
+
273
+ /* Filter the raw document through the specified type map, but override
274
+ * the root type so we can reliably access the ID.
275
+ */
276
+ $ typeMap = ['root ' => 'stdClass ' ] + $ this ->typeMap ;
277
+ $ file = \MongoDB \BSON \toPHP (\MongoDB \BSON \fromPHP ($ file ), $ typeMap );
265
278
266
279
if ( ! isset ($ file ->_id ) && ! property_exists ($ file , '_id ' )) {
267
280
throw new CorruptFileException ('file._id does not exist ' );
@@ -466,6 +479,31 @@ private function getFilesNamespace()
466
479
return sprintf ('%s.%s.files ' , $ this ->databaseName , $ this ->bucketName );
467
480
}
468
481
482
+ /**
483
+ * Gets the file document of the GridFS file associated with a stream.
484
+ *
485
+ * This returns the raw document from the StreamWrapper, which does not
486
+ * respect the Bucket's type map.
487
+ *
488
+ * @param resource $stream GridFS stream
489
+ * @return stdClass
490
+ * @throws InvalidArgumentException
491
+ */
492
+ private function getRawFileDocumentForStream ($ stream )
493
+ {
494
+ if ( ! is_resource ($ stream ) || get_resource_type ($ stream ) != "stream " ) {
495
+ throw InvalidArgumentException::invalidType ('$stream ' , $ stream , 'resource ' );
496
+ }
497
+
498
+ $ metadata = stream_get_meta_data ($ stream );
499
+
500
+ if (!$ metadata ['wrapper_data ' ] instanceof StreamWrapper) {
501
+ throw InvalidArgumentException::invalidType ('$stream wrapper data ' , $ metadata ['wrapper_data ' ], 'MongoDB\Driver\GridFS\StreamWrapper ' );
502
+ }
503
+
504
+ return $ metadata ['wrapper_data ' ]->getFile ();
505
+ }
506
+
469
507
/**
470
508
* Opens a readable stream for the GridFS file.
471
509
*
0 commit comments