-
Notifications
You must be signed in to change notification settings - Fork 265
Description
Hi,
I'm working on a lightweight "Entity" system that simplifies access to data between, for example, two collections.
In the code below, I would like my User
class to allow me to retrieve informations from the user's group.
First, data in DB:
// One document in "group" collection:
{
_id: 1234,
name: 'My group'
}
// One document in "user" collection:
{
_id: 1230,
firstName: 'Joe',
lastName: 'Robert',
group: 1234
}
Now, PHP (pseudo)code:
use MongoDB\Model\BSONDocument;
class User extends BSONDocument
{
/**
* @return Database
*/
protected function getDB(){
/**
* NEED TO IMPLEMENT THIS
*/
}
public function getGroup(){
$groupId = $this[ 'group' ];
return $this
->getDB()
->selectCollection('group')
->findOne([
'_id' => $groupId
])
;
}
}
// Usage example:
$usersCursor = $collection->find();
$usersCursor->setTypeMap([
'root' => User::class,
'document' => 'array',
'array' => 'array',
]);
foreach($usersCursor as $user){
$groupInformations = $user->getGroup();
$username = $user['firstName'];
// ...
}
In this example I need the Database
, but in reality it relates to any data that can be used in the document.
For now, I investigated 2 methods:
1 - Static references
Something like:
class User extends BSONDocument
{
private static $db;
public static function setDB(Database $db){
self::$db = $db;
}
/**
* @return Database
*/
protected function getDB(){
return self::$db;
}
//...
}
I find that this implementation is not clean.
And above all, in this example, if I request users on two different databases, I will have conflicts, it seems chaotic.
2 - Extends / wrap EVERYTHING
Extending MongoDB\Collection
, override all methods that return BSONDocument
, intercept the return of a document to hydrate it.
When a method (for example ::find
) returns a \MongoDB\Driver\Cursor
, it will have to be wrapped in a custom cursor, because:
final class Cursor implements \Traversable
This could be a problem if a third-party library requires a \MongoDB\Driver\Cursor
and nothing else.
Discussion
Why ::setTypeMap
could not use a callback
or a factory class that implements BSONDocumentFactory
for example ?
The returned result would be just completed with a call to bsonUnserialize
.
Maybe I forgot something?
In my example I need a Database
, but, again, this might be needed with any kind of data.
For now I'm thinking about the implementation of the second solution, it's a big deal!
Otherwise, if someone has another solution or a library that provides that, I would be grateful.
Thank you for reading so far! :)