Search code examples
phpmongodblithium

How can I add handler to database query results in Lithium


I am using the Lithium framework version 1.1.1 in PHP 5.6 with MongoDB. I have updated MongoDB from 3.4 to 3.6 and this ended up requiring the PHP ini variable mongo.long_as_object be set to true for the aggregateCursor() methods to work properly in the legacy MongoDB driver for PHP. This version of Lithium does not yet support the newer MongoDB PHP module. This causes a problem with the way NumberLong values are handled in Lithium since they are converted to a MongoInt64 in PHP.

For example: When calling $results->data() on a DocumentSet, a BSON result such as { viewers: NumberLong(12345) } will decode to [ 'viewers' => [ 'value' => '12345' ] ]. Instead I need the PHP array to be [ 'viewers' => 12345 ].

If I add an appropriate handler directly in the lithium\data\entity\Document::_init method then everything works as I expect. For example:

$this->_handlers += [
    'MongoId' => function($value) { return (string) $value; },
    'MongoDate' => function($value) { return $value->sec; },
    'MongoInt64' => function($value) { return (int) $value->value; }
];

However, directly editing the Lithium library is likely not the best approach especially when upgrading the library to newer version as they are released. Is there a proper way to add this handler elsewhere? Such as in the Connections::add(...) method in the connections.php bootstrap file?


Solution

  • Unfortunately, handlers aren't directly configurable, however, they're not too hard to override. You can pass a classes key to Connections:add(), which allows you to extend one of the two classes where handlers are specified, i.e.:

    Connections::add([
        /* ... */,
        'classes' => [
            'entity' => 'my\data\Document'
            // -- or --
            'schema' => 'my\data\Schema'
        ]
    ]);
    

    From there, you can implement your custom class that extends the appropriate core class, adding extra handlers as appropriate. Also, a PR to add MongoInt64 support to Li3 core would be gratefully accepted. :-)