From 8c268939922dfd788eda83969941551beabac19d Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 9 Aug 2012 22:27:42 -0400 Subject: [PATCH] Implemented new scope declaration syntax. --- framework/db/ar/ActiveFinder.php | 11 +++++++---- framework/db/ar/ActiveQuery.php | 8 +++----- framework/db/ar/ActiveRecord.php | 6 ++---- tests/unit/data/ar/Customer.php | 9 ++------- tests/unit/framework/db/ar/ActiveRecordTest.php | 21 ++++++++++----------- 5 files changed, 24 insertions(+), 31 deletions(-) diff --git a/framework/db/ar/ActiveFinder.php b/framework/db/ar/ActiveFinder.php index b5b085e..5613639 100644 --- a/framework/db/ar/ActiveFinder.php +++ b/framework/db/ar/ActiveFinder.php @@ -196,6 +196,7 @@ class ActiveFinder extends \yii\base\Object $records[$row[$query->index]] = $row; } } else { + /** @var $class ActiveRecord */ $class = $query->modelClass; if ($query->index === null) { foreach ($rows as $row) { @@ -212,18 +213,20 @@ class ActiveFinder extends \yii\base\Object protected function applyScopes($query) { + /** @var $class ActiveRecord */ $class = $query->modelClass; $class::defaultScope($query); if (is_array($query->scopes)) { - $scopes = $class::scopes(); + $model = new $class; foreach ($query->scopes as $name => $params) { - if (is_integer($name)) { + if (is_string($params)) { + // scope name only without parameters $name = $params; $params = array(); } - if (isset($scopes[$name])) { + if (method_exists($class, $name)) { array_unshift($params, $query); - call_user_func_array($scopes[$name], $params); + call_user_func_array(array($model, $name), $params); } else { throw new Exception("$class has no scope named '$name'."); } diff --git a/framework/db/ar/ActiveQuery.php b/framework/db/ar/ActiveQuery.php index 3c389eb..4a812a2 100644 --- a/framework/db/ar/ActiveQuery.php +++ b/framework/db/ar/ActiveQuery.php @@ -46,11 +46,9 @@ class ActiveQuery extends BaseActiveQuery implements \IteratorAggregate, \ArrayA public function __call($name, $params) { - $class = $this->modelClass; - $scopes = $class::scopes(); - if (isset($scopes[$name])) { - array_unshift($params, $this); - return call_user_func_array($scopes[$name], $params); + if (method_exists($this->modelClass, $name)) { + $this->scopes[$name] = $params; + return $this; } else { return parent::__call($name, $params); } diff --git a/framework/db/ar/ActiveRecord.php b/framework/db/ar/ActiveRecord.php index 544d7a7..88c0e5a 100644 --- a/framework/db/ar/ActiveRecord.php +++ b/framework/db/ar/ActiveRecord.php @@ -164,10 +164,8 @@ abstract class ActiveRecord extends Model * echo Customer::count('COUNT(DISTINCT age)')->value(); * ~~~ * - * @param mixed $q the query parameter. This can be one of the followings: - * - * - a scalar value (integer or string): query by a single primary key value. - * - an array of name-value pairs: it will be used to configure the [[ActiveQuery]] object for query purpose. + * @param array $q the query configuration. This should be an array of name-value pairs. + * It will be used to configure the [[ActiveQuery]] object for query purpose. * * @return integer the counting result */ diff --git a/tests/unit/data/ar/Customer.php b/tests/unit/data/ar/Customer.php index eb8013a..0ad8466 100644 --- a/tests/unit/data/ar/Customer.php +++ b/tests/unit/data/ar/Customer.php @@ -21,13 +21,8 @@ class Customer extends ActiveRecord ); } - public static function scopes() + public function active($query) { - $status = self::STATUS_ACTIVE; - return array( - 'active' => function($q) use ($status){ - return $q->andWhere('@.`status` = ' . $status); - }, - ); + return $query->andWhere('@.`status` = ' . self::STATUS_ACTIVE); } } \ No newline at end of file diff --git a/tests/unit/framework/db/ar/ActiveRecordTest.php b/tests/unit/framework/db/ar/ActiveRecordTest.php index a165764..a9263bc 100644 --- a/tests/unit/framework/db/ar/ActiveRecordTest.php +++ b/tests/unit/framework/db/ar/ActiveRecordTest.php @@ -35,7 +35,7 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase public function testUpdate() { // save - $customer = Customer::find(2)->one(); + $customer = Customer::find(2); $this->assertTrue($customer instanceof Customer); $this->assertEquals('user2', $customer->name); $this->assertFalse($customer->isNewRecord); @@ -43,7 +43,7 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase $customer->save(); $this->assertEquals('user2x', $customer->name); $this->assertFalse($customer->isNewRecord); - $customer2 = Customer::find(2)->one(); + $customer2 = Customer::find(2); $this->assertEquals('user2x', $customer2->name); // updateCounters @@ -57,13 +57,13 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase $this->assertEquals(0, $orderItem->quantity); // updateAll - $customer = Customer::find(3)->one(); + $customer = Customer::find(3); $this->assertEquals('user3', $customer->name); $ret = Customer::updateAll(array( 'name' => 'temp', ), array('id' => 3)); $this->assertEquals(1, $ret); - $customer = Customer::find(3)->one(); + $customer = Customer::find(3); $this->assertEquals('temp', $customer->name); // updateCounters @@ -81,11 +81,11 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase public function testDelete() { // delete - $customer = Customer::find(2)->one(); + $customer = Customer::find(2); $this->assertTrue($customer instanceof Customer); $this->assertEquals('user2', $customer->name); $customer->delete(); - $customer = Customer::find(2)->one(); + $customer = Customer::find(2); $this->assertNull($customer); // deleteAll @@ -140,7 +140,7 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase $this->assertTrue($result[2] instanceof Customer); // find by a single primary key - $customer = Customer::find(2)->one(); + $customer = Customer::find(2); $this->assertTrue($customer instanceof Customer); $this->assertEquals('user2', $customer->name); @@ -161,7 +161,6 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase // find count $this->assertEquals(3, Customer::find()->count()); $this->assertEquals(3, Customer::count()); - $this->assertEquals(1, Customer::count(2)); $this->assertEquals(2, Customer::count(array( 'where' => 'id=1 OR id=2', ))); @@ -294,12 +293,12 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase public function testLazyLoading() { // has one - $order = Order::find(3)->one(); + $order = Order::find(3); $this->assertTrue($order->customer instanceof Customer); $this->assertEquals(2, $order->customer->id); // has many - $customer = Customer::find(2)->one(); + $customer = Customer::find(2); $orders = $customer->orders; $this->assertEquals(2, count($orders)); $this->assertEquals(2, $orders[0]->id); @@ -316,7 +315,7 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase $this->assertEquals(2, $orders[2]->books[0]->id); // customized relation query - $customer = Customer::find(2)->one(); + $customer = Customer::find(2); $orders = $customer->orders(array( 'where' => '@.id = 3', ));