From bc73a2481c2e8974c684e642572643f5de2dff2d Mon Sep 17 00:00:00 2001 From: Paul Klimov <klimov.paul@gmail.com> Date: Sat, 8 Mar 2014 15:19:46 +0200 Subject: [PATCH] MongoDB log fixed to handle Mongo objects correctly --- extensions/mongodb/Collection.php | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- tests/unit/extensions/mongodb/CollectionTest.php | 24 ++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/extensions/mongodb/Collection.php b/extensions/mongodb/Collection.php index feea31e..3a5a910 100644 --- a/extensions/mongodb/Collection.php +++ b/extensions/mongodb/Collection.php @@ -107,12 +107,70 @@ class Collection extends Object { $parts = []; foreach ($arguments as $argument) { - $parts[] = is_scalar($argument) ? $argument : Json::encode($argument); + $parts[] = is_scalar($argument) ? $argument : $this->encodeLogData($argument); } return $this->getFullName() . '.' . $command . '(' . implode(', ', $parts) . ')'; } /** + * Encodes complex log data into JSON format string. + * @param mixed $data raw data. + * @return string encoded data string. + */ + protected function encodeLogData($data) + { + return json_encode($this->processLogData($data)); + } + + /** + * Pre-processes the log data before sending it to `json_encode()`. + * @param mixed $data raw data. + * @return mixed the processed data. + */ + protected function processLogData($data) + { + if (is_object($data)) { + if ($data instanceof \MongoId || + $data instanceof \MongoRegex || + $data instanceof \MongoDate || + $data instanceof \MongoInt32 || + $data instanceof \MongoInt64 || + $data instanceof \MongoTimestamp + ) { + $data = get_class($data) . '(' . $data->__toString() . ')'; + } elseif ($data instanceof \MongoCode) { + $data = 'MongoCode( ' . $data->__toString() . ' )'; + } elseif ($data instanceof \MongoBinData) { + $data = 'MongoBinData(...)'; + } elseif ($data instanceof \MongoDBRef) { + $data = 'MongoDBRef(...)'; + } elseif ($data instanceof \MongoMinKey || $data instanceof \MongoMaxKey) { + $data = get_class($data); + } else { + $result = []; + foreach ($data as $name => $value) { + $result[$name] = $value; + } + $data = $result; + } + + if ($data === []) { + return new \stdClass(); + } + } + + if (is_array($data)) { + foreach ($data as $key => $value) { + if (is_array($value) || is_object($value)) { + $data[$key] = $this->processLogData($value); + } + } + } + + return $data; + } + + /** * Drops this collection. * @throws Exception on failure. * @return boolean whether the operation successful. diff --git a/tests/unit/extensions/mongodb/CollectionTest.php b/tests/unit/extensions/mongodb/CollectionTest.php index d685d2e..cfafd7c 100644 --- a/tests/unit/extensions/mongodb/CollectionTest.php +++ b/tests/unit/extensions/mongodb/CollectionTest.php @@ -420,6 +420,10 @@ class CollectionTest extends MongoDbTestCase $this->assertCount(2, $result); } + /** + * @depends testInsert + * @depends testFind + */ public function testFindByNotObjectId() { $collection = $this->getConnection()->getCollection('customer'); @@ -439,4 +443,24 @@ class CollectionTest extends MongoDbTestCase $this->assertTrue($cursor instanceof \MongoCursor); $this->assertEquals(0, $cursor->count()); } + + /** + * @depends testInsert + * + * @see https://github.com/yiisoft/yii2/issues/2548 + */ + public function testInsertMongoBin() + { + $collection = $this->getConnection()->getCollection('customer'); + + $fileName = realpath(__DIR__ . '/../../../../extensions/gii/assets/logo.png'); + $data = [ + 'name' => 'customer 1', + 'address' => 'customer 1 address', + 'binData' => new \MongoBinData(file_get_contents($fileName), 2), + ]; + $id = $collection->insert($data); + $this->assertTrue($id instanceof \MongoId); + $this->assertNotEmpty($id->__toString()); + } } \ No newline at end of file -- libgit2 0.27.1