diff --git a/framework/db/ar/ActiveFinder.php b/framework/db/ar/ActiveFinder.php index c668007..5db34e1 100644 --- a/framework/db/ar/ActiveFinder.php +++ b/framework/db/ar/ActiveFinder.php @@ -188,13 +188,22 @@ class ActiveFinder extends \yii\base\Object protected function applyScopes($query) { if (is_array($query->scopes)) { - foreach ($query->scopes as $scope => $params) { - if (is_integer($scope)) { - $scope = $params; + $class = $query->modelClass; + $defaultScope = $class::defaultScope(); + if ($defaultScope !== null) { + call_user_func_array($defaultScope, array($query)); + } + $scopes = $class::scopes(); + foreach ($query->scopes as $name => $params) { + if (is_integer($name)) { + $name = $params; $params = array(); } + if (!isset($scopes[$name])) { + throw new Exception("$class has no scope named '$name'."); + } array_unshift($params, $query); - call_user_func_array($scope, $params); + call_user_func_array($scopes[$name], $params); } } } diff --git a/framework/db/ar/ActiveQuery.php b/framework/db/ar/ActiveQuery.php index 8007ad7..b673f21 100644 --- a/framework/db/ar/ActiveQuery.php +++ b/framework/db/ar/ActiveQuery.php @@ -89,6 +89,18 @@ class ActiveQuery extends BaseQuery implements \IteratorAggregate, \ArrayAccess, $this->modelClass = $modelClass; } + 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); + } else { + return parent::__call($name, $params); + } + } + public function asArray($value = true) { $this->asArray = $value; diff --git a/tests/unit/data/ar/Customer.php b/tests/unit/data/ar/Customer.php index 02af604..0a2e121 100644 --- a/tests/unit/data/ar/Customer.php +++ b/tests/unit/data/ar/Customer.php @@ -4,6 +4,9 @@ namespace yiiunit\data\ar; class Customer extends ActiveRecord { + const STATUS_ACTIVE = 1; + const STATUS_INACTIVE = 2; + public static function tableName() { return 'tbl_customer'; @@ -17,4 +20,13 @@ class Customer extends ActiveRecord ), ); } + + public static function scopes() + { + return array( + 'active' => function($q) { + return $q->andWhere('@.status = 1'); + }, + ); + } } \ No newline at end of file diff --git a/tests/unit/data/mysql.sql b/tests/unit/data/mysql.sql index 65a6422..11fbe17 100644 --- a/tests/unit/data/mysql.sql +++ b/tests/unit/data/mysql.sql @@ -19,6 +19,7 @@ CREATE TABLE `tbl_customer` ( `email` varchar(128) NOT NULL, `name` varchar(128) NOT NULL, `address` text, + `status` int (11) DEFAULT 0, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -71,9 +72,9 @@ CREATE TABLE `tbl_type` ( `bool_col2` tinyint(1) DEFAULT '1' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -INSERT INTO tbl_customer (email, name, address) VALUES ('user1@example.com', 'user1', 'address1'); -INSERT INTO tbl_customer (email, name, address) VALUES ('user2@example.com', 'user2', 'address2'); -INSERT INTO tbl_customer (email, name, address) VALUES ('user3@example.com', 'user3', 'address3'); +INSERT INTO tbl_customer (email, name, address, status) VALUES ('user1@example.com', 'user1', 'address1', 1); +INSERT INTO tbl_customer (email, name, address, status) VALUES ('user2@example.com', 'user2', 'address2', 1); +INSERT INTO tbl_customer (email, name, address, status) VALUES ('user3@example.com', 'user3', 'address3', 2); INSERT INTO tbl_category (name) VALUES ('Books'); INSERT INTO tbl_category (name) VALUES ('Movies'); diff --git a/tests/unit/framework/db/ar/ActiveRecordTest.php b/tests/unit/framework/db/ar/ActiveRecordTest.php index 5632912..b851309 100644 --- a/tests/unit/framework/db/ar/ActiveRecordTest.php +++ b/tests/unit/framework/db/ar/ActiveRecordTest.php @@ -158,7 +158,12 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase $this->assertEquals('user2', $customer->name); // find count - $this->assertEquals(3, Customer::find()->count(true)); + $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', + ))); } public function testFindBySql() @@ -199,6 +204,10 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase $this->assertTrue($customer instanceof Customer); $this->assertEquals(3, $customer->id); $this->assertEquals(null, $customer->name); + + // scopes + $customers = Customer::find()->active()->all(); + $this->assertEquals(2, count($customers)); } public function testEagerLoading()