From 27a1c63e26264135b2649c4781ffba640bd3251e Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Fri, 29 Nov 2013 20:55:41 +0200 Subject: [PATCH] Mongo "_id" processing advanced. --- extensions/mongo/ActiveRecord.php | 25 ++++++++++++++++++++++ extensions/mongo/Collection.php | 10 +++++++++ tests/unit/extensions/mongo/ActiveRelationTest.php | 4 ++-- tests/unit/extensions/mongo/QueryRunTest.php | 12 +++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/extensions/mongo/ActiveRecord.php b/extensions/mongo/ActiveRecord.php index 5e2d9bc..ddbfd2a 100644 --- a/extensions/mongo/ActiveRecord.php +++ b/extensions/mongo/ActiveRecord.php @@ -1157,4 +1157,29 @@ abstract class ActiveRecord extends Model throw new InvalidParamException(get_class($this) . ' has no relation named "' . $name . '".', 0, $e); } } + + /** + * Sets the element at the specified offset. + * This method is required by the SPL interface `ArrayAccess`. + * It is implicitly called when you use something like `$model[$offset] = $item;`. + * @param integer $offset the offset to set element + * @param mixed $item the element value + * @throws \Exception on failure + */ + public function offsetSet($offset, $item) + { + // Bypass relation owner restriction to 'yii\db\ActiveRecord' at [[yii\db\ActiveRelationTrait::findWith()]]: + try { + $relation = $this->getRelation($offset); + if (is_object($relation)) { + $this->populateRelation($offset, $item); + return; + } + } catch (InvalidParamException $e) { + // shut down exception : has getter, but not relation + } catch (UnknownMethodException $e) { + throw $e->getPrevious(); + } + parent::offsetSet($offset, $item); + } } \ No newline at end of file diff --git a/extensions/mongo/Collection.php b/extensions/mongo/Collection.php index 7959186..17a4329 100644 --- a/extensions/mongo/Collection.php +++ b/extensions/mongo/Collection.php @@ -267,8 +267,18 @@ class Collection extends Object $key = $this->normalizeConditionKeyword($key); if (strncmp('$', $key, 1) !== 0 && is_array($actualValue) && array_key_exists(0, $actualValue)) { // shortcut for IN condition + if ($key == '_id') { + foreach ($actualValue as &$actualValuePart) { + if (!is_object($actualValuePart)) { + $actualValuePart = new \MongoId($actualValuePart); + } + } + } $result[$key]['$in'] = $actualValue; } else { + if ($key == '_id' && !is_object($actualValue)) { + $actualValue = new \MongoId($actualValue); + } $result[$key] = $actualValue; } } diff --git a/tests/unit/extensions/mongo/ActiveRelationTest.php b/tests/unit/extensions/mongo/ActiveRelationTest.php index ae12d72..26cf63e 100644 --- a/tests/unit/extensions/mongo/ActiveRelationTest.php +++ b/tests/unit/extensions/mongo/ActiveRelationTest.php @@ -77,7 +77,7 @@ class ActiveRelationTest extends MongoTestCase $this->assertEquals(10, count($orders)); $this->assertTrue($orders[0]->isRelationPopulated('customer')); $this->assertTrue($orders[1]->isRelationPopulated('customer')); - $this->assertTrue($orders[0]->index instanceof ArticleIndex); - $this->assertTrue($orders[1]->index instanceof ArticleIndex); + $this->assertTrue($orders[0]->customer instanceof Customer); + $this->assertTrue($orders[1]->customer instanceof Customer); } } \ No newline at end of file diff --git a/tests/unit/extensions/mongo/QueryRunTest.php b/tests/unit/extensions/mongo/QueryRunTest.php index f8821b6..078e1c7 100644 --- a/tests/unit/extensions/mongo/QueryRunTest.php +++ b/tests/unit/extensions/mongo/QueryRunTest.php @@ -105,4 +105,16 @@ class QueryRunTest extends MongoTestCase ->all($connection); $this->assertEquals('name9', $rows[0]['name']); } + + public function testMatchPlainId() + { + $connection = $this->getConnection(); + $query = new Query; + $row = $query->from('customer')->one($connection); + $query = new Query; + $rows = $query->from('customer') + ->where(['_id' => $row['_id']->__toString()]) + ->all($connection); + $this->assertEquals(1, count($rows)); + } } \ No newline at end of file