Commit a75a4415 by Qiang Xue

Merge pull request #3003 from yiisoft/split-find-into-find-findOne-findAll

Refactored AR find to fix #2999
parents c8d17099 5eebaf87
...@@ -69,7 +69,7 @@ class User extends ActiveRecord implements IdentityInterface ...@@ -69,7 +69,7 @@ class User extends ActiveRecord implements IdentityInterface
*/ */
public static function findIdentity($id) public static function findIdentity($id)
{ {
return static::find($id); return static::findOne($id);
} }
/** /**
...@@ -88,7 +88,7 @@ class User extends ActiveRecord implements IdentityInterface ...@@ -88,7 +88,7 @@ class User extends ActiveRecord implements IdentityInterface
*/ */
public static function findByUsername($username) public static function findByUsername($username)
{ {
return static::find(['username' => $username, 'status' => self::STATUS_ACTIVE]); return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
} }
/** /**
...@@ -107,7 +107,7 @@ class User extends ActiveRecord implements IdentityInterface ...@@ -107,7 +107,7 @@ class User extends ActiveRecord implements IdentityInterface
return null; return null;
} }
return static::find([ return static::findOne([
'password_reset_token' => $token, 'password_reset_token' => $token,
'status' => self::STATUS_ACTIVE, 'status' => self::STATUS_ACTIVE,
]); ]);
......
...@@ -36,7 +36,7 @@ class PasswordResetRequestForm extends Model ...@@ -36,7 +36,7 @@ class PasswordResetRequestForm extends Model
public function sendEmail() public function sendEmail()
{ {
/** @var User $user */ /** @var User $user */
$user = User::find([ $user = User::findOne([
'status' => User::STATUS_ACTIVE, 'status' => User::STATUS_ACTIVE,
'email' => $this->email, 'email' => $this->email,
]); ]);
......
...@@ -47,7 +47,7 @@ class PasswordResetRequestFormTest extends DbTestCase ...@@ -47,7 +47,7 @@ class PasswordResetRequestFormTest extends DbTestCase
{ {
$model = new PasswordResetRequestForm(); $model = new PasswordResetRequestForm();
$model->email = $this->user[0]['email']; $model->email = $this->user[0]['email'];
$user = User::find(['password_reset_token' => $this->user[0]['password_reset_token']]); $user = User::findOne(['password_reset_token' => $this->user[0]['password_reset_token']]);
expect('email sent', $model->sendEmail())->true(); expect('email sent', $model->sendEmail())->true();
expect('user has valid token', $user->password_reset_token)->notNull(); expect('user has valid token', $user->password_reset_token)->notNull();
......
...@@ -169,20 +169,27 @@ $customers = Customer::findBySql($sql)->all(); ...@@ -169,20 +169,27 @@ $customers = Customer::findBySql($sql)->all();
use meaningful constant names rather than hardcoded strings or numbers in your code. use meaningful constant names rather than hardcoded strings or numbers in your code.
The `find()` method also supports the following shortcut usage which allows you to retrieve an Active Record Two shortcut methods are provided to return Active Record instances matching a primary key value or a set of
instance based on a primary key value or a set of column values. The main difference here is that instead of column values: `findOne()` and `findAll()`. The former returns the first matching instance while the latter
returning a [[yii\db\ActiveQuery]] instance, the method takes the column value(s) and returns an Active Record returns all of them. For example,
instance directly without the need to call `one()`.
```php ```php
// to return a single customer whose ID is 1: // to return a single customer whose ID is 1:
$customer = Customer::find(1); $customer = Customer::findOne(1);
// to return an *active* customer whose ID is 1: // to return an *active* customer whose ID is 1:
$customer = Customer::find([ $customer = Customer::findOne([
'id' => 1, 'id' => 1,
'status' => Customer::STATUS_ACTIVE, 'status' => Customer::STATUS_ACTIVE,
]); ]);
// to return customers whose ID is 1, 2 or 3:
$customers = Customer::findAll([1, 2, 3]);
// to return customers whose status is "deleted":
$customer = Customer::findAll([
'status' => Customer::STATUS_DELETED,
]);
``` ```
...@@ -252,12 +259,12 @@ $customer->email = 'james@example.com'; ...@@ -252,12 +259,12 @@ $customer->email = 'james@example.com';
$customer->save(); // equivalent to $customer->insert(); $customer->save(); // equivalent to $customer->insert();
// to update an existing customer record // to update an existing customer record
$customer = Customer::find($id); $customer = Customer::findOne($id);
$customer->email = 'james@example.com'; $customer->email = 'james@example.com';
$customer->save(); // equivalent to $customer->update(); $customer->save(); // equivalent to $customer->update();
// to delete an existing customer record // to delete an existing customer record
$customer = Customer::find($id); $customer = Customer::findOne($id);
$customer->delete(); $customer->delete();
// to increment the age of ALL customers by 1 // to increment the age of ALL customers by 1
...@@ -267,8 +274,8 @@ Customer::updateAllCounters(['age' => 1]); ...@@ -267,8 +274,8 @@ Customer::updateAllCounters(['age' => 1]);
> Info: The `save()` method will call either `insert()` or `update()`, depending on whether > Info: The `save()` method will call either `insert()` or `update()`, depending on whether
the Active Record instance is new or not (internally it will check the value of [[yii\db\ActiveRecord::isNewRecord]]). the Active Record instance is new or not (internally it will check the value of [[yii\db\ActiveRecord::isNewRecord]]).
If an Active Record is instantiated via the `new` operator, calling `save()` will If an Active Record is instantiated via the `new` operator, calling `save()` will
insert a row in the table; if an Active Record is obtained by `find()`, calling `save()` will insert a row in the table; calling `save()` on active record fetched from database will update the corresponding
update the corresponding row in the table. row in the table.
### Data Input and Validation ### Data Input and Validation
...@@ -291,7 +298,7 @@ if ($model->load(Yii::$app->request->post()) && $model->save()) { ...@@ -291,7 +298,7 @@ if ($model->load(Yii::$app->request->post()) && $model->save()) {
} }
// updating a record whose primary key is $id // updating a record whose primary key is $id
$model = Customer::find($id); $model = Customer::findOne($id);
if ($model === null) { if ($model === null) {
throw new NotFoundHttpException; throw new NotFoundHttpException;
} }
...@@ -399,7 +406,7 @@ that is defined by the corresponding getter method: ...@@ -399,7 +406,7 @@ that is defined by the corresponding getter method:
```php ```php
// get the orders of a customer // get the orders of a customer
$customer = Customer::find(1); $customer = Customer::findOne(1);
$orders = $customer->orders; // $orders is an array of Order objects $orders = $customer->orders; // $orders is an array of Order objects
``` ```
...@@ -501,7 +508,7 @@ if you access the same related objects again. We call this *lazy loading*. For e ...@@ -501,7 +508,7 @@ if you access the same related objects again. We call this *lazy loading*. For e
```php ```php
// SQL executed: SELECT * FROM customer WHERE id=1 // SQL executed: SELECT * FROM customer WHERE id=1
$customer = Customer::find(1); $customer = Customer::findOne(1);
// SQL executed: SELECT * FROM order WHERE customer_id=1 // SQL executed: SELECT * FROM order WHERE customer_id=1
$orders = $customer->orders; $orders = $customer->orders;
// no SQL executed // no SQL executed
...@@ -559,7 +566,7 @@ Sometimes, you may want to customize the relational queries on the fly. This can ...@@ -559,7 +566,7 @@ Sometimes, you may want to customize the relational queries on the fly. This can
done for both lazy loading and eager loading. For example, done for both lazy loading and eager loading. For example,
```php ```php
$customer = Customer::find(1); $customer = Customer::findOne(1);
// lazy loading: SELECT * FROM order WHERE customer_id=1 AND subtotal>100 // lazy loading: SELECT * FROM order WHERE customer_id=1 AND subtotal>100
$orders = $customer->getOrders()->where('subtotal>100')->all(); $orders = $customer->getOrders()->where('subtotal>100')->all();
...@@ -605,7 +612,7 @@ the `customer` of an order will trigger another SQL execution: ...@@ -605,7 +612,7 @@ the `customer` of an order will trigger another SQL execution:
```php ```php
// SELECT * FROM customer WHERE id=1 // SELECT * FROM customer WHERE id=1
$customer = Customer::find(1); $customer = Customer::findOne(1);
// echoes "not equal" // echoes "not equal"
// SELECT * FROM order WHERE customer_id=1 // SELECT * FROM order WHERE customer_id=1
// SELECT * FROM customer WHERE id=1 // SELECT * FROM customer WHERE id=1
...@@ -634,7 +641,7 @@ Now if we execute the same query as shown above, we would get: ...@@ -634,7 +641,7 @@ Now if we execute the same query as shown above, we would get:
```php ```php
// SELECT * FROM customer WHERE id=1 // SELECT * FROM customer WHERE id=1
$customer = Customer::find(1); $customer = Customer::findOne(1);
// echoes "equal" // echoes "equal"
// SELECT * FROM order WHERE customer_id=1 // SELECT * FROM order WHERE customer_id=1
if ($customer->orders[0]->customer === $customer) { if ($customer->orders[0]->customer === $customer) {
...@@ -762,7 +769,7 @@ in the WHERE part of the corresponding SQL statement, because there is no JOIN q ...@@ -762,7 +769,7 @@ in the WHERE part of the corresponding SQL statement, because there is no JOIN q
```php ```php
// SELECT * FROM user WHERE id=10 // SELECT * FROM user WHERE id=10
$user = User::find(10); $user = User::findOne(10);
// SELECT * FROM item WHERE owner_id=10 AND category_id=1 // SELECT * FROM item WHERE owner_id=10 AND category_id=1
$books = $user->books; $books = $user->books;
``` ```
...@@ -781,7 +788,7 @@ For example, given a customer and a new order, we can use the following code to ...@@ -781,7 +788,7 @@ For example, given a customer and a new order, we can use the following code to
order owned by the customer: order owned by the customer:
```php ```php
$customer = Customer::find(1); $customer = Customer::findOne(1);
$order = new Order(); $order = new Order();
$order->subtotal = 100; $order->subtotal = 100;
$customer->link('orders', $order); $customer->link('orders', $order);
...@@ -828,7 +835,7 @@ Important points are: ...@@ -828,7 +835,7 @@ Important points are:
2. A method should be `public` and should return `$this` in order to allow method chaining. It may accept parameters. 2. A method should be `public` and should return `$this` in order to allow method chaining. It may accept parameters.
3. Check [[yii\db\ActiveQuery]] methods that are very useful for modifying query conditions. 3. Check [[yii\db\ActiveQuery]] methods that are very useful for modifying query conditions.
Second, override [[yii\db\ActiveRecord::createQuery()]] to use the custom query class instead of the regular [[yii\db\ActiveQuery|ActiveQuery]]. Second, override [[yii\db\ActiveRecord::find()]] to use the custom query class instead of the regular [[yii\db\ActiveQuery|ActiveQuery]].
For the example above, you need to write the following code: For the example above, you need to write the following code:
```php ```php
...@@ -838,7 +845,11 @@ use yii\db\ActiveRecord; ...@@ -838,7 +845,11 @@ use yii\db\ActiveRecord;
class Comment extends ActiveRecord class Comment extends ActiveRecord
{ {
public static function createQuery() /**
* @inheritdoc
* @return CommentQuery
*/
public static function find()
{ {
return new CommentQuery(get_called_class()); return new CommentQuery(get_called_class());
} }
...@@ -875,43 +886,15 @@ $posts = Post::find()->with([ ...@@ -875,43 +886,15 @@ $posts = Post::find()->with([
])->all(); ])->all();
``` ```
### Making it IDE-friendly
In order to make most modern IDE autocomplete happy you need to override return types for some methods of both model
and query like the following:
```php
/**
* @method \app\models\CommentQuery|static|null find($q = null) static
* @method \app\models\CommentQuery findBySql($sql, $params = []) static
*/
class Comment extends ActiveRecord
{
// ...
}
```
```php
/**
* @method \app\models\Comment|array|null one($db = null)
* @method \app\models\Comment[]|array all($db = null)
*/
class CommentQuery extends ActiveQuery
{
// ...
}
```
### Default Scope ### Default Scope
If you used Yii 1.1 before, you may know a concept called *default scope*. A default scope is a scope that If you used Yii 1.1 before, you may know a concept called *default scope*. A default scope is a scope that
applies to ALL queries. You can define a default scope easily by overriding [[yii\db\ActiveRecord::createQuery()]]. For example, applies to ALL queries. You can define a default scope easily by overriding [[yii\db\ActiveRecord::find()]]. For example,
```php ```php
public static function createQuery() public static function find()
{ {
return parent::createQuery()->where(['deleted' => false]); return parent::find()->where(['deleted' => false]);
} }
``` ```
......
...@@ -21,7 +21,7 @@ class User extends ActiveRecord implements IdentityInterface ...@@ -21,7 +21,7 @@ class User extends ActiveRecord implements IdentityInterface
*/ */
public static function findIdentity($id) public static function findIdentity($id)
{ {
return static::find($id); return static::findOne($id);
} }
/** /**
...@@ -32,7 +32,7 @@ class User extends ActiveRecord implements IdentityInterface ...@@ -32,7 +32,7 @@ class User extends ActiveRecord implements IdentityInterface
*/ */
public static function findIdentityByAccessToken($token) public static function findIdentityByAccessToken($token)
{ {
return static::find(['access_token' => $token]); return static::findOne(['access_token' => $token]);
} }
/** /**
......
...@@ -266,7 +266,7 @@ simple checks could be used instead. For example such code that uses RBAC: ...@@ -266,7 +266,7 @@ simple checks could be used instead. For example such code that uses RBAC:
```php ```php
public function editArticle($id) public function editArticle($id)
{ {
$article = Article::find($id); $article = Article::findOne($id);
if (!$article) { if (!$article) {
throw new NotFoundHttpException; throw new NotFoundHttpException;
} }
...@@ -282,7 +282,7 @@ can be replaced with simpler code that doesn't use RBAC: ...@@ -282,7 +282,7 @@ can be replaced with simpler code that doesn't use RBAC:
```php ```php
public function editArticle($id) public function editArticle($id)
{ {
$article = Article::find(['id' => $id, 'author_id' => \Yii::$app->user->id]); $article = Article::findOne(['id' => $id, 'author_id' => \Yii::$app->user->id]);
if (!$article) { if (!$article) {
throw new NotFoundHttpException; throw new NotFoundHttpException;
} }
......
...@@ -91,7 +91,7 @@ class BlogController extends Controller ...@@ -91,7 +91,7 @@ class BlogController extends Controller
{ {
public function actionView($id, $version = null) public function actionView($id, $version = null)
{ {
$post = Post::find($id); $post = Post::findOne($id);
$text = $post->text; $text = $post->text;
if ($version) { if ($version) {
...@@ -125,7 +125,7 @@ class BlogController extends Controller ...@@ -125,7 +125,7 @@ class BlogController extends Controller
{ {
public function actionUpdate($id) public function actionUpdate($id)
{ {
$post = Post::find($id); $post = Post::findOne($id);
if (!$post) { if (!$post) {
throw new NotFoundHttpException(); throw new NotFoundHttpException();
} }
......
...@@ -295,7 +295,7 @@ The following code will return *all* attributes in the `$post` model ...@@ -295,7 +295,7 @@ The following code will return *all* attributes in the `$post` model
as an array of name-value pairs. as an array of name-value pairs.
```php ```php
$post = Post::find(42); $post = Post::findOne(42);
if ($post) { if ($post) {
$attributes = $post->attributes; $attributes = $post->attributes;
var_dump($attributes); var_dump($attributes);
...@@ -356,7 +356,7 @@ class User extends ActiveRecord ...@@ -356,7 +356,7 @@ class User extends ActiveRecord
For the code above mass assignment will be allowed strictly according to `scenarios()`: For the code above mass assignment will be allowed strictly according to `scenarios()`:
```php ```php
$user = User::find(42); $user = User::findOne(42);
$data = ['password' => '123']; $data = ['password' => '123'];
$user->attributes = $data; $user->attributes = $data;
print_r($user->attributes); print_r($user->attributes);
...@@ -365,7 +365,7 @@ print_r($user->attributes); ...@@ -365,7 +365,7 @@ print_r($user->attributes);
Will give you empty array because there's no default scenario defined in our `scenarios()`. Will give you empty array because there's no default scenario defined in our `scenarios()`.
```php ```php
$user = User::find(42); $user = User::findOne(42);
$user->scenario = 'signup'; $user->scenario = 'signup';
$data = [ $data = [
'username' => 'samdark', 'username' => 'samdark',
...@@ -406,7 +406,7 @@ class User extends ActiveRecord ...@@ -406,7 +406,7 @@ class User extends ActiveRecord
The code above assumes default scenario so mass assignment will be available for all fields with `rules` defined: The code above assumes default scenario so mass assignment will be available for all fields with `rules` defined:
```php ```php
$user = User::find(42); $user = User::findOne(42);
$data = [ $data = [
'username' => 'samdark', 'username' => 'samdark',
'first_name' => 'Alexander', 'first_name' => 'Alexander',
...@@ -453,7 +453,7 @@ class User extends ActiveRecord ...@@ -453,7 +453,7 @@ class User extends ActiveRecord
Mass assignment is still available by default: Mass assignment is still available by default:
```php ```php
$user = User::find(42); $user = User::findOne(42);
$data = [ $data = [
'username' => 'samdark', 'username' => 'samdark',
'first_name' => 'Alexander', 'first_name' => 'Alexander',
......
...@@ -663,7 +663,7 @@ class User extends ActiveRecord implements IdentityInterface ...@@ -663,7 +663,7 @@ class User extends ActiveRecord implements IdentityInterface
{ {
public static function findIdentityByAccessToken($token) public static function findIdentityByAccessToken($token)
{ {
return static::find(['access_token' => $token]); return static::findOne(['access_token' => $token]);
} }
} }
``` ```
......
...@@ -454,7 +454,7 @@ $customers = Customer::find() ...@@ -454,7 +454,7 @@ $customers = Customer::find()
->orderBy('id') ->orderBy('id')
->all(); ->all();
// return the customer whose PK is 1 // return the customer whose PK is 1
$customer = Customer::find(1); $customer = Customer::findOne(1);
``` ```
......
...@@ -10,6 +10,7 @@ namespace yii\elasticsearch; ...@@ -10,6 +10,7 @@ namespace yii\elasticsearch;
use yii\base\InvalidCallException; use yii\base\InvalidCallException;
use yii\base\InvalidConfigException; use yii\base\InvalidConfigException;
use yii\db\BaseActiveRecord; use yii\db\BaseActiveRecord;
use yii\helpers\ArrayHelper;
use yii\helpers\Inflector; use yii\helpers\Inflector;
use yii\helpers\Json; use yii\helpers\Json;
use yii\helpers\StringHelper; use yii\helpers\StringHelper;
...@@ -65,19 +66,34 @@ class ActiveRecord extends BaseActiveRecord ...@@ -65,19 +66,34 @@ class ActiveRecord extends BaseActiveRecord
/** /**
* @inheritdoc * @inheritdoc
*/ */
public static function find($q = null) public static function find()
{ {
$query = static::createQuery(); return new ActiveQuery(get_called_class());
$args = func_get_args(); }
if (empty($args)) {
return $query; /**
* @inheritdoc
*/
public static function findOne($condition)
{
$query = static::find();
if (is_array($condition)) {
return $query->andWhere($condition)->one();
} else {
return static::get($condition);
} }
}
$q = reset($args); /**
if (is_array($q)) { * @inheritdoc
return $query->andWhere($q)->one(); */
public static function findAll($condition)
{
$query = static::find();
if (ArrayHelper::isAssociative($condition)) {
return $query->andWhere($condition)->all();
} else { } else {
return static::get($q); return static::mget((array) $condition);
} }
} }
...@@ -118,14 +134,18 @@ class ActiveRecord extends BaseActiveRecord ...@@ -118,14 +134,18 @@ class ActiveRecord extends BaseActiveRecord
* *
* Please refer to the [elasticsearch documentation](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-get.html) * Please refer to the [elasticsearch documentation](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-get.html)
* for more details on these options. * for more details on these options.
* @return static|null The record instance or null if it was not found. * @return array The record instances, or empty array if nothing was found
*/ */
public static function mget(array $primaryKeys, $options = [])
public static function mget($primaryKeys, $options = [])
{ {
if (empty($primaryKeys)) { if (empty($primaryKeys)) {
return []; return [];
} }
if (count($primaryKeys) === 1) {
$model = static::get(reset($primaryKeys));
return $model === null ? [] : [$model];
}
$command = static::getDb()->createCommand(); $command = static::getDb()->createCommand();
$result = $command->mget(static::index(), static::type(), $primaryKeys, $options); $result = $command->mget(static::index(), static::type(), $primaryKeys, $options);
$models = []; $models = [];
...@@ -145,33 +165,6 @@ class ActiveRecord extends BaseActiveRecord ...@@ -145,33 +165,6 @@ class ActiveRecord extends BaseActiveRecord
// TODO add percolate functionality http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-percolate.html // TODO add percolate functionality http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-percolate.html
/**
* Creates an [[ActiveQuery]] instance.
*
* This method is called by [[find()]] to start a SELECT query but also
* by [[hasOne()]] and [[hasMany()]] to create a relational query.
* You may override this method to return a customized query (e.g. `CustomerQuery` specified
* written for querying `Customer` purpose.)
*
* You may also define default conditions that should apply to all queries unless overridden:
*
* ```php
* public static function createQuery()
* {
* return parent::createQuery()->where(['deleted' => false]);
* }
* ```
*
* Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the
* default condition. Using [[Query::where()]] will override the default condition.
*
* @return ActiveQuery the newly created [[ActiveQuery]] instance.
*/
public static function createQuery()
{
return new ActiveQuery(get_called_class());
}
// TODO implement copy and move as pk change is not possible // TODO implement copy and move as pk change is not possible
/** /**
......
...@@ -150,7 +150,7 @@ if (count($pks) === 1) { ...@@ -150,7 +150,7 @@ if (count($pks) === 1) {
$condition = '[' . implode(', ', $condition) . ']'; $condition = '[' . implode(', ', $condition) . ']';
} }
?> ?>
if (($model = <?= $modelClass ?>::find(<?= $condition ?>)) !== null) { if (($model = <?= $modelClass ?>::findOne(<?= $condition ?>)) !== null) {
return $model; return $model;
} else { } else {
throw new NotFoundHttpException('The requested page does not exist.'); throw new NotFoundHttpException('The requested page does not exist.');
......
...@@ -92,28 +92,9 @@ abstract class ActiveRecord extends BaseActiveRecord ...@@ -92,28 +92,9 @@ abstract class ActiveRecord extends BaseActiveRecord
} }
/** /**
* Creates an [[ActiveQuery]] instance. * @inheritdoc
*
* This method is called by [[find()]] to start a SELECT query but also
* by [[hasOne()]] and [[hasMany()]] to create a relational query.
* You may override this method to return a customized query (e.g. `CustomerQuery` specified
* written for querying `Customer` purpose.)
*
* You may also define default conditions that should apply to all queries unless overridden:
*
* ```php
* public static function createQuery()
* {
* return parent::createQuery()->where(['deleted' => false]);
* }
* ```
*
* Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the
* default condition. Using [[Query::where()]] will override the default condition.
*
* @return ActiveQuery the newly created [[ActiveQuery]] instance.
*/ */
public static function createQuery() public static function find()
{ {
return new ActiveQuery(get_called_class()); return new ActiveQuery(get_called_class());
} }
......
...@@ -45,28 +45,9 @@ use yii\web\UploadedFile; ...@@ -45,28 +45,9 @@ use yii\web\UploadedFile;
abstract class ActiveRecord extends \yii\mongodb\ActiveRecord abstract class ActiveRecord extends \yii\mongodb\ActiveRecord
{ {
/** /**
* Creates an [[ActiveQuery]] instance. * @inheritdoc
*
* This method is called by [[find()]] to start a SELECT query but also
* by [[hasOne()]] and [[hasMany()]] to create a relational query.
* You may override this method to return a customized query (e.g. `CustomerQuery` specified
* written for querying `Customer` purpose.)
*
* You may also define default conditions that should apply to all queries unless overridden:
*
* ```php
* public static function createQuery()
* {
* return parent::createQuery()->where(['deleted' => false]);
* }
* ```
*
* Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the
* default condition. Using [[Query::where()]] will override the default condition.
*
* @return ActiveQuery the newly created [[ActiveQuery]] instance.
*/ */
public static function createQuery() public static function find()
{ {
return new ActiveQuery(get_called_class()); return new ActiveQuery(get_called_class());
} }
......
...@@ -49,28 +49,9 @@ class ActiveRecord extends BaseActiveRecord ...@@ -49,28 +49,9 @@ class ActiveRecord extends BaseActiveRecord
} }
/** /**
* Creates an [[ActiveQuery]] instance. * @inheritdoc
*
* This method is called by [[find()]] to start a SELECT query but also
* by [[hasOne()]] and [[hasMany()]] to create a relational query.
* You may override this method to return a customized query (e.g. `CustomerQuery` specified
* written for querying `Customer` purpose.)
*
* You may also define default conditions that should apply to all queries unless overridden:
*
* ```php
* public static function createQuery()
* {
* return parent::createQuery()->where(['deleted' => false]);
* }
* ```
*
* Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the
* default condition. Using [[Query::where()]] will override the default condition.
*
* @return ActiveQuery the newly created [[ActiveQuery]] instance.
*/ */
public static function createQuery() public static function find()
{ {
return new ActiveQuery(get_called_class()); return new ActiveQuery(get_called_class());
} }
...@@ -274,7 +255,7 @@ class ActiveRecord extends BaseActiveRecord ...@@ -274,7 +255,7 @@ class ActiveRecord extends BaseActiveRecord
private static function fetchPks($condition) private static function fetchPks($condition)
{ {
$query = static::createQuery(); $query = static::find();
$query->where($condition); $query->where($condition);
$records = $query->asArray()->all(); // TODO limit fetched columns to pk $records = $query->asArray()->all(); // TODO limit fetched columns to pk
$primaryKey = static::primaryKey(); $primaryKey = static::primaryKey();
......
...@@ -85,7 +85,7 @@ abstract class ActiveRecord extends BaseActiveRecord ...@@ -85,7 +85,7 @@ abstract class ActiveRecord extends BaseActiveRecord
*/ */
public static function findBySql($sql, $params = []) public static function findBySql($sql, $params = [])
{ {
$query = static::createQuery(); $query = static::find();
$query->sql = $sql; $query->sql = $sql;
return $query->params($params); return $query->params($params);
...@@ -136,28 +136,9 @@ abstract class ActiveRecord extends BaseActiveRecord ...@@ -136,28 +136,9 @@ abstract class ActiveRecord extends BaseActiveRecord
} }
/** /**
* Creates an [[ActiveQuery]] instance. * @inheritdoc
*
* This method is called by [[find()]], [[findBySql()]] to start a SELECT query but also
* by [[hasOne()]] and [[hasMany()]] to create a relational query.
* You may override this method to return a customized query (e.g. `CustomerQuery` specified
* written for querying `Customer` purpose.)
*
* You may also define default conditions that should apply to all queries unless overridden:
*
* ```php
* public static function createQuery()
* {
* return parent::createQuery()->where(['deleted' => false]);
* }
* ```
*
* Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the
* default condition. Using [[Query::where()]] will override the default condition.
*
* @return ActiveQuery the newly created [[ActiveQuery]] instance.
*/ */
public static function createQuery() public static function find()
{ {
return new ActiveQuery(get_called_class()); return new ActiveQuery(get_called_class());
} }
...@@ -442,7 +423,7 @@ abstract class ActiveRecord extends BaseActiveRecord ...@@ -442,7 +423,7 @@ abstract class ActiveRecord extends BaseActiveRecord
* For example, to update an article record: * For example, to update an article record:
* *
* ~~~ * ~~~
* $article = Article::find(['id' => $id]); * $article = Article::findOne($id);
* $article->genre_id = $genreId; * $article->genre_id = $genreId;
* $article->group_id = $groupId; * $article->group_id = $groupId;
* $article->update(); * $article->update();
......
...@@ -188,6 +188,7 @@ Yii Framework 2 Change Log ...@@ -188,6 +188,7 @@ Yii Framework 2 Change Log
- Enh: Implemented Oracle column comment reading from another schema (gureedo, samdark) - Enh: Implemented Oracle column comment reading from another schema (gureedo, samdark)
- Enh: Added support to allow an event handler to be inserted at the beginning of the existing event handler list (qiangxue) - Enh: Added support to allow an event handler to be inserted at the beginning of the existing event handler list (qiangxue)
- Enh: Improved action filter and action execution flow by supporting installing action filters at controller, module and application levels (qiangxue) - Enh: Improved action filter and action execution flow by supporting installing action filters at controller, module and application levels (qiangxue)
- Enh: Added `isAssociative()` and `isIndexed()` to `yii\helpers\ArrayHelper` (qiangxue)
- Chg #47: Changed Markdown library to cebe/markdown and adjusted Markdown helper API (cebe) - Chg #47: Changed Markdown library to cebe/markdown and adjusted Markdown helper API (cebe)
- Chg #735: Added back `ActiveField::hiddenInput()` (qiangxue) - Chg #735: Added back `ActiveField::hiddenInput()` (qiangxue)
- Chg #1186: Changed `Sort` to use comma to separate multiple sort fields and use negative sign to indicate descending sort (qiangxue) - Chg #1186: Changed `Sort` to use comma to separate multiple sort fields and use negative sign to indicate descending sort (qiangxue)
...@@ -240,7 +241,8 @@ Yii Framework 2 Change Log ...@@ -240,7 +241,8 @@ Yii Framework 2 Change Log
- Chg #2816: Changed default date and time format of `yii\base\Formatter` to `Y-m-d` and `H:i:s` (qiangxue) - Chg #2816: Changed default date and time format of `yii\base\Formatter` to `Y-m-d` and `H:i:s` (qiangxue)
- Chg #2911: Removed `tbl_` default for table prefix (samdark) - Chg #2911: Removed `tbl_` default for table prefix (samdark)
- Chg #2912: Relative view files will be looked for under the directory containing the view currently being rendered (qiangxue) - Chg #2912: Relative view files will be looked for under the directory containing the view currently being rendered (qiangxue)
- Chg #2955: Changed the signature of ActiveQuery constructors and `ActiveRecord::createQuery()` to simplify customizing ActiveQuery classes (qiangxue) - Chg #2955: Changed the signature of ActiveQuery constructors and replaced `ActiveRecord::createQuery()` with `find()` to simplify customizing ActiveQuery classes (qiangxue)
- Chg #2999: Added `findOne()` and `findAll()` to replace the usage of `ActiveRecord::query($condition)`. (samdark, qiangxue)
- Chg: Renamed `yii\jui\Widget::clientEventsMap` to `clientEventMap` (qiangxue) - Chg: Renamed `yii\jui\Widget::clientEventsMap` to `clientEventMap` (qiangxue)
- Chg: Renamed `ActiveRecord::getPopulatedRelations()` to `getRelatedRecords()` (qiangxue) - Chg: Renamed `ActiveRecord::getPopulatedRelations()` to `getRelatedRecords()` (qiangxue)
- Chg: Renamed `attributeName` and `className` to `targetAttribute` and `targetClass` for `UniqueValidator` and `ExistValidator` (qiangxue) - Chg: Renamed `attributeName` and `className` to `targetAttribute` and `targetClass` for `UniqueValidator` and `ExistValidator` (qiangxue)
......
...@@ -143,7 +143,7 @@ class ActiveRecord extends BaseActiveRecord ...@@ -143,7 +143,7 @@ class ActiveRecord extends BaseActiveRecord
*/ */
public static function findBySql($sql, $params = []) public static function findBySql($sql, $params = [])
{ {
$query = static::createQuery(); $query = static::find();
$query->sql = $sql; $query->sql = $sql;
return $query->params($params); return $query->params($params);
...@@ -224,28 +224,9 @@ class ActiveRecord extends BaseActiveRecord ...@@ -224,28 +224,9 @@ class ActiveRecord extends BaseActiveRecord
} }
/** /**
* Creates an [[ActiveQuery]] instance. * @inheritdoc
*
* This method is called by [[find()]], [[findBySql()]] to start a SELECT query but also
* by [[hasOne()]] and [[hasMany()]] to create a relational query.
* You may override this method to return a customized query (e.g. `CustomerQuery` specified
* written for querying `Customer` purpose.)
*
* You may also define default conditions that should apply to all queries unless overridden:
*
* ```php
* public static function createQuery()
* {
* return parent::createQuery()->where(['deleted' => false]);
* }
* ```
*
* Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the
* default condition. Using [[Query::where()]] will override the default condition.
*
* @return ActiveQuery the newly created [[ActiveQuery]] instance.
*/ */
public static function createQuery() public static function find()
{ {
return new ActiveQuery(get_called_class()); return new ActiveQuery(get_called_class());
} }
...@@ -479,7 +460,7 @@ class ActiveRecord extends BaseActiveRecord ...@@ -479,7 +460,7 @@ class ActiveRecord extends BaseActiveRecord
* For example, to update a customer record: * For example, to update a customer record:
* *
* ~~~ * ~~~
* $customer = Customer::find($id); * $customer = Customer::findOne($id);
* $customer->name = $name; * $customer->name = $name;
* $customer->email = $email; * $customer->email = $email;
* $customer->update(); * $customer->update();
......
...@@ -72,7 +72,7 @@ interface ActiveRecordInterface ...@@ -72,7 +72,7 @@ interface ActiveRecordInterface
/** /**
* Returns the old primary key value(s). * Returns the old primary key value(s).
* This refers to the primary key value that is populated into the record * This refers to the primary key value that is populated into the record
* after executing a find method (e.g. find(), findAll()). * after executing a find method (e.g. find(), findOne()).
* The value remains unchanged even if the primary key attribute is manually assigned with a different value. * The value remains unchanged even if the primary key attribute is manually assigned with a different value.
* @param boolean $asArray whether to return the primary key value as an array. If true, * @param boolean $asArray whether to return the primary key value as an array. If true,
* the return value will be an array with column name as key and column value as value. * the return value will be an array with column name as key and column value as value.
...@@ -111,62 +111,114 @@ interface ActiveRecordInterface ...@@ -111,62 +111,114 @@ interface ActiveRecordInterface
* ->all(); * ->all();
* ``` * ```
* *
* This method can also take a parameter which can be: * This method is also called by [[BaseActiveRecord::hasOne()]] and [[BaseActiveRecord::hasMany()]] to
* create a relational query.
*
* You may override this method to return a customized query. For example,
*
* ```php
* class Customer extends ActiveRecord
* {
* public static function find()
* {
* // use CustomerQuery instead of the default ActiveQuery
* return new CustomerQuery(get_called_class());
* }
* }
* ```
*
* The following code shows how to apply a default condition for all queries:
*
* ```php
* class Customer extends ActiveRecord
* {
* public static function find()
* {
* return parent::find()->where(['deleted' => false]);
* }
* }
*
* // Use andWhere()/orWhere() to apply the default condition
* // SELECT FROM customer WHERE `deleted`=:deleted AND age>30
* $customers = Customer::find()->andWhere('age>30')->all();
*
* // Use where() to ignore the default condition
* // SELECT FROM customer WHERE age>30
* $customers = Customer::find()->where('age>30')->all();
*
* @return ActiveQueryInterface the newly created [[ActiveQueryInterface|ActiveQuery]] instance.
*/
public static function find();
/**
* Returns a single active record model instance by a primary key or an array of column values.
*
* The method accepts:
* *
* - a scalar value (integer or string): query by a single primary key value and return the * - a scalar value (integer or string): query by a single primary key value and return the
* corresponding record (or null if not found). * corresponding record (or null if not found).
* - an array of name-value pairs: query by a set of attribute values and return a single record * - an array of name-value pairs: query by a set of attribute values and return a single record
* matching all of them (or null if not found). * matching all of them (or null if not found).
* *
* Note that in this case, the method will automatically call the `one()` method and return an * Note that this method will automatically call the `one()` method and return an
* [[ActiveRecordInterface|ActiveRecord]] instance. For example, * [[ActiveRecordInterface|ActiveRecord]] instance. For example,
* *
* ```php * ```php
* // find a single customer whose primary key value is 10 * // find a single customer whose primary key value is 10
* $customer = Customer::find(10); * $customer = Customer::findOne(10);
* *
* // the above code is equivalent to: * // the above code is equivalent to:
* $customer = Customer::find()->where(['id' => 10])->one(); * $customer = Customer::find()->where(['id' => 10])->one();
* *
* // find a single customer whose age is 30 and whose status is 1 * // find the first customer whose age is 30 and whose status is 1
* $customer = Customer::find(['age' => 30, 'status' => 1]); * $customer = Customer::findOne(['age' => 30, 'status' => 1]);
* *
* // the above code is equivalent to: * // the above code is equivalent to:
* $customer = Customer::find()->where(['age' => 30, 'status' => 1])->one(); * $customer = Customer::find()->where(['age' => 30, 'status' => 1])->one();
* ``` * ```
* *
* @return ActiveQueryInterface|static|null When this method receives no parameter, a new [[ActiveQuery]] instance * @param mixed $condition primary key value or a set of column values
* will be returned; Otherwise, the parameter will be treated as a primary key value or a set of column * @return static ActiveRecord instance matching the condition, or null if nothing matches.
* values, and an ActiveRecord object matching it will be returned (null will be returned if there is no matching).
* @see createQuery()
*/ */
public static function find(); public static function findOne($condition);
/** /**
* Creates an [[ActiveQueryInterface|ActiveQuery]] instance. * Returns a list of active record models that match the specified primary key value or a set of column values.
* *
* This method is called by [[find()]] to start a SELECT query but also * The method accepts:
* by [[BaseActiveRecord::hasOne()]] and [[BaseActiveRecord::hasMany()]] to
* create a relational query.
* *
* You may override this method to return a customized query (e.g. `CustomerQuery` specified * - a scalar value (integer or string): query by a single primary key value and return the
* written for querying `Customer` purpose.) * corresponding record (or null if not found).
* - an array of name-value pairs: query by a set of attribute values and return a single record
* matching all of them (or null if not found).
* *
* You may also define default conditions that should apply to all queries unless overridden: * Note that this method will automatically call the `all()` method and return an array of
* [[ActiveRecordInterface|ActiveRecord]] instances. For example,
* *
* ```php * ```php
* public static function createQuery() * // find the customers whose primary key value is 10
* { * $customers = Customer::findAll(10);
* return parent::createQuery()->where(['deleted' => false]);
* }
* ```
* *
* Note that all queries should use [[Query::andWhere()]] and [[Query::orWhere()]] to keep the * // the above code is equivalent to:
* default condition. Using [[Query::where()]] will override the default condition. * $customers = Customer::find()->where(['id' => 10])->all();
* *
* @return ActiveQueryInterface the newly created [[ActiveQueryInterface|ActiveQuery]] instance. * // find the customers whose primary key value is 10, 11 or 12.
* $customers = Customer::findAll([10, 11, 12]);
*
* // the above code is equivalent to:
* $customers = Customer::find()->where(['id' => [10, 11, 12]])->all();
*
* // find customers whose age is 30 and whose status is 1
* $customers = Customer::findOne(['age' => 30, 'status' => 1]);
*
* // the above code is equivalent to:
* $customers = Customer::find()->where(['age' => 30, 'status' => 1])->all();
* ```
*
* @param mixed $condition primary key value or a set of column values
* @return array an array of ActiveRecord instance, or an empty array if nothing matches.
*/ */
public static function createQuery(); public static function findAll($condition);
/** /**
* Updates records using the provided attribute values and conditions. * Updates records using the provided attribute values and conditions.
...@@ -211,7 +263,7 @@ interface ActiveRecordInterface ...@@ -211,7 +263,7 @@ interface ActiveRecordInterface
* For example, to save a customer record: * For example, to save a customer record:
* *
* ~~~ * ~~~
* $customer = new Customer; // or $customer = Customer::find($id); * $customer = new Customer; // or $customer = Customer::findOne($id);
* $customer->name = $name; * $customer->name = $name;
* $customer->email = $email; * $customer->email = $email;
* $customer->save(); * $customer->save();
...@@ -252,7 +304,7 @@ interface ActiveRecordInterface ...@@ -252,7 +304,7 @@ interface ActiveRecordInterface
* Usage example: * Usage example:
* *
* ```php * ```php
* $customer = Customer::find($id); * $customer = Customer::findOne($id);
* $customer->name = $name; * $customer->name = $name;
* $customer->email = $email; * $customer->email = $email;
* $customer->update(); * $customer->update();
......
...@@ -15,6 +15,7 @@ use yii\base\ModelEvent; ...@@ -15,6 +15,7 @@ use yii\base\ModelEvent;
use yii\base\NotSupportedException; use yii\base\NotSupportedException;
use yii\base\UnknownMethodException; use yii\base\UnknownMethodException;
use yii\base\InvalidCallException; use yii\base\InvalidCallException;
use yii\helpers\ArrayHelper;
/** /**
* ActiveRecord is the base class for classes representing relational data in terms of objects. * ActiveRecord is the base class for classes representing relational data in terms of objects.
...@@ -94,22 +95,37 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface ...@@ -94,22 +95,37 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
/** /**
* @inheritdoc * @inheritdoc
*/ */
public static function find() public static function findOne($condition)
{ {
$query = static::createQuery(); $query = static::find();
$args = func_get_args(); if (ArrayHelper::isAssociative($condition)) {
if (empty($args)) { // hash condition
return $query; return $query->andWhere($condition)->one();
} else {
// query by primary key
$primaryKey = static::primaryKey();
if (isset($primaryKey[0])) {
return $query->andWhere([$primaryKey[0] => $condition])->one();
} else {
throw new InvalidConfigException(get_called_class() . ' must have a primary key.');
}
} }
}
$q = reset($args); /**
if (is_array($q)) { * @inheritdoc
return $query->andWhere($q)->one(); */
public static function findAll($condition)
{
$query = static::find();
if (ArrayHelper::isAssociative($condition)) {
// hash condition
return $query->andWhere($condition)->all();
} else { } else {
// query by primary key // query by primary key(s)
$primaryKey = static::primaryKey(); $primaryKey = static::primaryKey();
if (isset($primaryKey[0])) { if (isset($primaryKey[0])) {
return $query->andWhere([$primaryKey[0] => $q])->one(); return $query->andWhere([$primaryKey[0] => $condition])->all();
} else { } else {
throw new InvalidConfigException(get_called_class() . ' must have a primary key.'); throw new InvalidConfigException(get_called_class() . ' must have a primary key.');
} }
...@@ -310,7 +326,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface ...@@ -310,7 +326,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
{ {
/** @var ActiveRecordInterface $class */ /** @var ActiveRecordInterface $class */
/** @var ActiveQuery $query */ /** @var ActiveQuery $query */
$query = $class::createQuery(); $query = $class::find();
$query->primaryModel = $this; $query->primaryModel = $this;
$query->link = $link; $query->link = $link;
$query->multiple = false; $query->multiple = false;
...@@ -351,7 +367,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface ...@@ -351,7 +367,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
{ {
/** @var ActiveRecordInterface $class */ /** @var ActiveRecordInterface $class */
/** @var ActiveQuery $query */ /** @var ActiveQuery $query */
$query = $class::createQuery(); $query = $class::find();
$query->primaryModel = $this; $query->primaryModel = $this;
$query->link = $link; $query->link = $link;
$query->multiple = true; $query->multiple = true;
...@@ -540,7 +556,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface ...@@ -540,7 +556,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
* For example, to save a customer record: * For example, to save a customer record:
* *
* ~~~ * ~~~
* $customer = new Customer; // or $customer = Customer::find($id); * $customer = new Customer; // or $customer = Customer::findOne($id);
* $customer->name = $name; * $customer->name = $name;
* $customer->email = $email; * $customer->email = $email;
* $customer->save(); * $customer->save();
...@@ -584,7 +600,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface ...@@ -584,7 +600,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
* For example, to update a customer record: * For example, to update a customer record:
* *
* ~~~ * ~~~
* $customer = Customer::find($id); * $customer = Customer::findOne($id);
* $customer->name = $name; * $customer->name = $name;
* $customer->email = $email; * $customer->email = $email;
* $customer->update(); * $customer->update();
...@@ -695,7 +711,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface ...@@ -695,7 +711,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
* An example usage is as follows: * An example usage is as follows:
* *
* ~~~ * ~~~
* $post = Post::find($id); * $post = Post::findOne($id);
* $post->updateCounters(['view_count' => 1]); * $post->updateCounters(['view_count' => 1]);
* ~~~ * ~~~
* *
...@@ -891,7 +907,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface ...@@ -891,7 +907,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
*/ */
public function refresh() public function refresh()
{ {
$record = $this->find($this->getPrimaryKey(true)); $record = $this->findOne($this->getPrimaryKey(true));
if ($record === null) { if ($record === null) {
return false; return false;
} }
...@@ -950,7 +966,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface ...@@ -950,7 +966,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
/** /**
* Returns the old primary key value(s). * Returns the old primary key value(s).
* This refers to the primary key value that is populated into the record * This refers to the primary key value that is populated into the record
* after executing a find method (e.g. find(), findAll()). * after executing a find method (e.g. find(), findOne()).
* The value remains unchanged even if the primary key attribute is manually assigned with a different value. * The value remains unchanged even if the primary key attribute is manually assigned with a different value.
* @param boolean $asArray whether to return the primary key value as an array. If true, * @param boolean $asArray whether to return the primary key value as an array. If true,
* the return value will be an array with column name as key and column value as value. * the return value will be an array with column name as key and column value as value.
......
...@@ -44,7 +44,7 @@ class HttpBasicAuth extends AuthMethod ...@@ -44,7 +44,7 @@ class HttpBasicAuth extends AuthMethod
* *
* ```php * ```php
* function ($username, $password) { * function ($username, $password) {
* return \app\models\User::find([ * return \app\models\User::findOne([
* 'username' => $username, * 'username' => $username,
* 'password' => $password, * 'password' => $password,
* ]); * ]);
......
...@@ -490,4 +490,75 @@ class BaseArrayHelper ...@@ -490,4 +490,75 @@ class BaseArrayHelper
return $d; return $d;
} }
/**
* Returns a value indicating whether the given array is an associative array.
*
* An array is associative if all its keys are strings. If `$allStrings` is false,
* then an array will be treated as associative if at least one of its keys is a string.
*
* Note that an empty array will NOT be considered associative.
*
* @param array $array the array being checked
* @param boolean $allStrings whether the array keys must be all strings in order for
* the array to be treated as associative.
* @return boolean whether the array is associative
*/
public static function isAssociative($array, $allStrings = true)
{
if (!is_array($array) || empty($array)) {
return false;
}
if ($allStrings) {
foreach ($array as $key => $value) {
if (!is_string($key)) {
return false;
}
}
return true;
} else {
foreach ($array as $key => $value) {
if (is_string($key)) {
return true;
}
}
return false;
}
}
/**
* Returns a value indicating whether the given array is an indexed array.
*
* An array is indexed if all its keys are integers. If `$consecutive` is true,
* then the array keys must be a consecutive sequence starting from 0.
*
* Note that an empty array will be considered indexed.
*
* @param array $array the array being checked
* @param boolean $consecutive whether the array keys must be a consecutive sequence
* in order for the array to be treated as indexed.
* @return boolean whether the array is associative
*/
public static function isIndexed($array, $consecutive = false)
{
if (!is_array($array)) {
return false;
}
if (empty($array)) {
return true;
}
if ($consecutive) {
return array_keys($array) === range(0, count($array) - 1);
} else {
foreach ($array as $key => $value) {
if (!is_integer($key)) {
return false;
}
}
return true;
}
}
} }
...@@ -90,10 +90,10 @@ class Action extends \yii\base\Action ...@@ -90,10 +90,10 @@ class Action extends \yii\base\Action
if (count($keys) > 1) { if (count($keys) > 1) {
$values = explode(',', $id); $values = explode(',', $id);
if (count($keys) === count($values)) { if (count($keys) === count($values)) {
$model = $modelClass::find(array_combine($keys, $values)); $model = $modelClass::findOne(array_combine($keys, $values));
} }
} elseif ($id !== null) { } elseif ($id !== null) {
$model = $modelClass::find($id); $model = $modelClass::findOne($id);
} }
if (isset($model)) { if (isset($model)) {
......
...@@ -68,7 +68,7 @@ abstract class BaseActiveFixture extends DbFixture implements \IteratorAggregate ...@@ -68,7 +68,7 @@ abstract class BaseActiveFixture extends DbFixture implements \IteratorAggregate
$keys[$key] = isset($row[$key]) ? $row[$key] : null; $keys[$key] = isset($row[$key]) ? $row[$key] : null;
} }
return $this->_models[$name] = $modelClass::find($keys); return $this->_models[$name] = $modelClass::findOne($keys);
} }
/** /**
......
...@@ -18,7 +18,7 @@ namespace yii\web; ...@@ -18,7 +18,7 @@ namespace yii\web;
* { * {
* public static function findIdentity($id) * public static function findIdentity($id)
* { * {
* return static::find($id); * return static::findOne($id);
* } * }
* *
* public function getId() * public function getId()
......
...@@ -13,7 +13,6 @@ use yiiunit\framework\db\ActiveRecordTest; ...@@ -13,7 +13,6 @@ use yiiunit\framework\db\ActiveRecordTest;
* @property string $address * @property string $address
* @property integer $status * @property integer $status
* *
* @method CustomerQuery|Customer|null find($q = null) static
* @method CustomerQuery findBySql($sql, $params = []) static * @method CustomerQuery findBySql($sql, $params = []) static
*/ */
class Customer extends ActiveRecord class Customer extends ActiveRecord
...@@ -62,7 +61,11 @@ class Customer extends ActiveRecord ...@@ -62,7 +61,11 @@ class Customer extends ActiveRecord
parent::afterSave($insert); parent::afterSave($insert);
} }
public static function createQuery() /**
* @inheritdoc
* @return CustomerQuery
*/
public static function find()
{ {
return new CustomerQuery(get_called_class()); return new CustomerQuery(get_called_class());
} }
......
...@@ -64,7 +64,11 @@ class Customer extends ActiveRecord ...@@ -64,7 +64,11 @@ class Customer extends ActiveRecord
} }
public static function createQuery() /**
* @inheritdoc
* @return CustomerQuery
*/
public static function find()
{ {
return new CustomerQuery(get_called_class()); return new CustomerQuery(get_called_class());
} }
......
...@@ -25,7 +25,11 @@ class Customer extends ActiveRecord ...@@ -25,7 +25,11 @@ class Customer extends ActiveRecord
return $this->hasMany(CustomerOrder::className(), ['customer_id' => '_id']); return $this->hasMany(CustomerOrder::className(), ['customer_id' => '_id']);
} }
public static function createQuery() /**
* @inheritdoc
* @return CustomerQuery
*/
public static function find()
{ {
return new CustomerQuery(get_called_class()); return new CustomerQuery(get_called_class());
} }
......
...@@ -4,11 +4,17 @@ namespace yiiunit\data\ar\mongodb\file; ...@@ -4,11 +4,17 @@ namespace yiiunit\data\ar\mongodb\file;
class CustomerFile extends ActiveRecord class CustomerFile extends ActiveRecord
{ {
/**
* @inheritdoc
*/
public static function collectionName() public static function collectionName()
{ {
return 'customer_fs'; return 'customer_fs';
} }
/**
* @inheritdoc
*/
public function attributes() public function attributes()
{ {
return array_merge( return array_merge(
...@@ -20,7 +26,11 @@ class CustomerFile extends ActiveRecord ...@@ -20,7 +26,11 @@ class CustomerFile extends ActiveRecord
); );
} }
public static function createQuery() /**
* @inheritdoc
* @return CustomerFileQuery
*/
public static function find()
{ {
return new CustomerFileQuery(get_called_class()); return new CustomerFileQuery(get_called_class());
} }
......
...@@ -11,6 +11,9 @@ class Customer extends ActiveRecord ...@@ -11,6 +11,9 @@ class Customer extends ActiveRecord
public $status2; public $status2;
/**
* @inheritdoc
*/
public function attributes() public function attributes()
{ {
return ['id', 'email', 'name', 'address', 'status', 'profile_id']; return ['id', 'email', 'name', 'address', 'status', 'profile_id'];
...@@ -24,6 +27,9 @@ class Customer extends ActiveRecord ...@@ -24,6 +27,9 @@ class Customer extends ActiveRecord
return $this->hasMany(Order::className(), ['customer_id' => 'id']); return $this->hasMany(Order::className(), ['customer_id' => 'id']);
} }
/**
* @inheritdoc
*/
public function afterSave($insert) public function afterSave($insert)
{ {
ActiveRecordTest::$afterSaveInsert = $insert; ActiveRecordTest::$afterSaveInsert = $insert;
...@@ -31,7 +37,11 @@ class Customer extends ActiveRecord ...@@ -31,7 +37,11 @@ class Customer extends ActiveRecord
parent::afterSave($insert); parent::afterSave($insert);
} }
public static function createQuery() /**
* @inheritdoc
* @return CustomerQuery
*/
public static function find()
{ {
return new CustomerQuery(get_called_class()); return new CustomerQuery(get_called_class());
} }
......
...@@ -5,6 +5,9 @@ class ArticleIndex extends ActiveRecord ...@@ -5,6 +5,9 @@ class ArticleIndex extends ActiveRecord
{ {
public $custom_column; public $custom_column;
/**
* @inheritdoc
*/
public static function indexName() public static function indexName()
{ {
return 'yii2_test_article_index'; return 'yii2_test_article_index';
...@@ -20,12 +23,18 @@ class ArticleIndex extends ActiveRecord ...@@ -20,12 +23,18 @@ class ArticleIndex extends ActiveRecord
return $this->hasMany(TagDb::className(), ['id' => 'tag']); return $this->hasMany(TagDb::className(), ['id' => 'tag']);
} }
/**
* @inheritdoc
*/
public function getSnippetSource() public function getSnippetSource()
{ {
return $this->source->content; return $this->source->content;
} }
public static function createQuery() /**
* @return ArticleIndexQuery
*/
public static function find()
{ {
return new ArticleIndexQuery(get_called_class()); return new ArticleIndexQuery(get_called_class());
} }
......
...@@ -243,7 +243,7 @@ class ActiveRecordTest extends ElasticSearchTestCase ...@@ -243,7 +243,7 @@ class ActiveRecordTest extends ElasticSearchTestCase
public function testFindLazy() public function testFindLazy()
{ {
/** @var $customer Customer */ /** @var $customer Customer */
$customer = Customer::find(2); $customer = Customer::findOne(2);
$orders = $customer->orders; $orders = $customer->orders;
$this->assertEquals(2, count($orders)); $this->assertEquals(2, count($orders));
...@@ -314,7 +314,7 @@ class ActiveRecordTest extends ElasticSearchTestCase ...@@ -314,7 +314,7 @@ class ActiveRecordTest extends ElasticSearchTestCase
{ {
$pkName = 'id'; $pkName = 'id';
$orderItem = Order::find([$pkName => 2]); $orderItem = Order::findOne([$pkName => 2]);
$this->assertEquals(2, $orderItem->primaryKey); $this->assertEquals(2, $orderItem->primaryKey);
$this->assertEquals(2, $orderItem->oldPrimaryKey); $this->assertEquals(2, $orderItem->oldPrimaryKey);
$this->assertEquals(2, $orderItem->$pkName); $this->assertEquals(2, $orderItem->$pkName);
...@@ -330,8 +330,8 @@ class ActiveRecordTest extends ElasticSearchTestCase ...@@ -330,8 +330,8 @@ class ActiveRecordTest extends ElasticSearchTestCase
$this->assertEquals(13, $orderItem->oldPrimaryKey); $this->assertEquals(13, $orderItem->oldPrimaryKey);
$this->assertEquals(13, $orderItem->$pkName); $this->assertEquals(13, $orderItem->$pkName);
$this->assertNull(Order::find([$pkName => 2])); $this->assertNull(Order::findOne([$pkName => 2]));
$this->assertNotNull(Order::find([$pkName => 13])); $this->assertNotNull(Order::findOne([$pkName => 13]));
} }
public function testFindLazyVia2() public function testFindLazyVia2()
......
...@@ -66,16 +66,16 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -66,16 +66,16 @@ class ActiveRecordTest extends MongoDbTestCase
// find by _id // find by _id
$testId = $this->testRows[0]['_id']; $testId = $this->testRows[0]['_id'];
$customer = Customer::find($testId); $customer = Customer::findOne($testId);
$this->assertTrue($customer instanceof Customer); $this->assertTrue($customer instanceof Customer);
$this->assertEquals($testId, $customer->_id); $this->assertEquals($testId, $customer->_id);
// find by column values // find by column values
$customer = Customer::find(['name' => 'name5']); $customer = Customer::findOne(['name' => 'name5']);
$this->assertTrue($customer instanceof Customer); $this->assertTrue($customer instanceof Customer);
$this->assertEquals($this->testRows[4]['_id'], $customer->_id); $this->assertEquals($this->testRows[4]['_id'], $customer->_id);
$this->assertEquals('name5', $customer->name); $this->assertEquals('name5', $customer->name);
$customer = Customer::find(['name' => 'unexisting name']); $customer = Customer::findOne(['name' => 'unexisting name']);
$this->assertNull($customer); $this->assertNull($customer);
// find by attributes // find by attributes
...@@ -142,7 +142,7 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -142,7 +142,7 @@ class ActiveRecordTest extends MongoDbTestCase
$record->save(); $record->save();
// save // save
$record = Customer::find($record->_id); $record = Customer::findOne($record->_id);
$this->assertTrue($record instanceof Customer); $this->assertTrue($record instanceof Customer);
$this->assertEquals(7, $record->status); $this->assertEquals(7, $record->status);
$this->assertFalse($record->isNewRecord); $this->assertFalse($record->isNewRecord);
...@@ -151,14 +151,14 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -151,14 +151,14 @@ class ActiveRecordTest extends MongoDbTestCase
$record->save(); $record->save();
$this->assertEquals(9, $record->status); $this->assertEquals(9, $record->status);
$this->assertFalse($record->isNewRecord); $this->assertFalse($record->isNewRecord);
$record2 = Customer::find($record->_id); $record2 = Customer::findOne($record->_id);
$this->assertEquals(9, $record2->status); $this->assertEquals(9, $record2->status);
// updateAll // updateAll
$pk = ['_id' => $record->_id]; $pk = ['_id' => $record->_id];
$ret = Customer::updateAll(['status' => 55], $pk); $ret = Customer::updateAll(['status' => 55], $pk);
$this->assertEquals(1, $ret); $this->assertEquals(1, $ret);
$record = Customer::find($pk); $record = Customer::findOne($pk);
$this->assertEquals(55, $record->status); $this->assertEquals(55, $record->status);
} }
...@@ -175,9 +175,9 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -175,9 +175,9 @@ class ActiveRecordTest extends MongoDbTestCase
$record->status = 7; $record->status = 7;
$record->save(); $record->save();
$record = Customer::find($record->_id); $record = Customer::findOne($record->_id);
$record->delete(); $record->delete();
$record = Customer::find($record->_id); $record = Customer::findOne($record->_id);
$this->assertNull($record); $this->assertNull($record);
// deleteAll // deleteAll
...@@ -198,7 +198,7 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -198,7 +198,7 @@ class ActiveRecordTest extends MongoDbTestCase
{ {
$this->assertEquals(1, Customer::updateAllCounters(['status' => 10], ['status' => 10])); $this->assertEquals(1, Customer::updateAllCounters(['status' => 10], ['status' => 10]));
$record = Customer::find(['status' => 10]); $record = Customer::findOne(['status' => 10]);
$this->assertNull($record); $this->assertNull($record);
} }
...@@ -207,14 +207,14 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -207,14 +207,14 @@ class ActiveRecordTest extends MongoDbTestCase
*/ */
public function testUpdateCounters() public function testUpdateCounters()
{ {
$record = Customer::find($this->testRows[9]); $record = Customer::findOne($this->testRows[9]);
$originalCounter = $record->status; $originalCounter = $record->status;
$counterIncrement = 20; $counterIncrement = 20;
$record->updateCounters(['status' => $counterIncrement]); $record->updateCounters(['status' => $counterIncrement]);
$this->assertEquals($originalCounter + $counterIncrement, $record->status); $this->assertEquals($originalCounter + $counterIncrement, $record->status);
$refreshedRecord = Customer::find($record->_id); $refreshedRecord = Customer::findOne($record->_id);
$this->assertEquals($originalCounter + $counterIncrement, $refreshedRecord->status); $this->assertEquals($originalCounter + $counterIncrement, $refreshedRecord->status);
} }
...@@ -234,13 +234,13 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -234,13 +234,13 @@ class ActiveRecordTest extends MongoDbTestCase
$record->save(); $record->save();
// save // save
$record = Customer::find($record->_id); $record = Customer::findOne($record->_id);
$newAddress = [ $newAddress = [
'city' => 'AnotherCity' 'city' => 'AnotherCity'
]; ];
$record->address = $newAddress; $record->address = $newAddress;
$record->save(); $record->save();
$record2 = Customer::find($record->_id); $record2 = Customer::findOne($record->_id);
$this->assertEquals($newAddress, $record2->address); $this->assertEquals($newAddress, $record2->address);
} }
......
...@@ -63,7 +63,7 @@ class ActiveRelationTest extends MongoDbTestCase ...@@ -63,7 +63,7 @@ class ActiveRelationTest extends MongoDbTestCase
public function testFindLazy() public function testFindLazy()
{ {
/** @var CustomerOrder $order */ /** @var CustomerOrder $order */
$order = CustomerOrder::find(['number' => 2]); $order = CustomerOrder::findOne(['number' => 2]);
$this->assertFalse($order->isRelationPopulated('customer')); $this->assertFalse($order->isRelationPopulated('customer'));
$customer = $order->customer; $customer = $order->customer;
$this->assertTrue($order->isRelationPopulated('customer')); $this->assertTrue($order->isRelationPopulated('customer'));
......
...@@ -86,16 +86,16 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -86,16 +86,16 @@ class ActiveRecordTest extends MongoDbTestCase
// find by _id // find by _id
$testId = $this->testRows[0]['_id']; $testId = $this->testRows[0]['_id'];
$customer = CustomerFile::find($testId); $customer = CustomerFile::findOne($testId);
$this->assertTrue($customer instanceof CustomerFile); $this->assertTrue($customer instanceof CustomerFile);
$this->assertEquals($testId, $customer->_id); $this->assertEquals($testId, $customer->_id);
// find by column values // find by column values
$customer = CustomerFile::find(['tag' => 'tag5']); $customer = CustomerFile::findOne(['tag' => 'tag5']);
$this->assertTrue($customer instanceof CustomerFile); $this->assertTrue($customer instanceof CustomerFile);
$this->assertEquals($this->testRows[4]['_id'], $customer->_id); $this->assertEquals($this->testRows[4]['_id'], $customer->_id);
$this->assertEquals('tag5', $customer->tag); $this->assertEquals('tag5', $customer->tag);
$customer = CustomerFile::find(['tag' => 'unexisting tag']); $customer = CustomerFile::findOne(['tag' => 'unexisting tag']);
$this->assertNull($customer); $this->assertNull($customer);
// find by attributes // find by attributes
...@@ -205,7 +205,7 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -205,7 +205,7 @@ class ActiveRecordTest extends MongoDbTestCase
$record->save(); $record->save();
// save // save
$record = CustomerFile::find($record->_id); $record = CustomerFile::findOne($record->_id);
$this->assertTrue($record instanceof CustomerFile); $this->assertTrue($record instanceof CustomerFile);
$this->assertEquals(7, $record->status); $this->assertEquals(7, $record->status);
$this->assertFalse($record->isNewRecord); $this->assertFalse($record->isNewRecord);
...@@ -214,14 +214,14 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -214,14 +214,14 @@ class ActiveRecordTest extends MongoDbTestCase
$record->save(); $record->save();
$this->assertEquals(9, $record->status); $this->assertEquals(9, $record->status);
$this->assertFalse($record->isNewRecord); $this->assertFalse($record->isNewRecord);
$record2 = CustomerFile::find($record->_id); $record2 = CustomerFile::findOne($record->_id);
$this->assertEquals(9, $record2->status); $this->assertEquals(9, $record2->status);
// updateAll // updateAll
$pk = ['_id' => $record->_id]; $pk = ['_id' => $record->_id];
$ret = CustomerFile::updateAll(['status' => 55], $pk); $ret = CustomerFile::updateAll(['status' => 55], $pk);
$this->assertEquals(1, $ret); $this->assertEquals(1, $ret);
$record = CustomerFile::find($pk); $record = CustomerFile::findOne($pk);
$this->assertEquals(55, $record->status); $this->assertEquals(55, $record->status);
} }
...@@ -239,13 +239,13 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -239,13 +239,13 @@ class ActiveRecordTest extends MongoDbTestCase
$record->save(); $record->save();
$updateFileName = __FILE__; $updateFileName = __FILE__;
$record = CustomerFile::find($record->_id); $record = CustomerFile::findOne($record->_id);
$record->setAttribute('file', $updateFileName); $record->setAttribute('file', $updateFileName);
$record->status = 55; $record->status = 55;
$record->save(); $record->save();
$this->assertEquals(file_get_contents($updateFileName), $record->getFileContent()); $this->assertEquals(file_get_contents($updateFileName), $record->getFileContent());
$record2 = CustomerFile::find($record->_id); $record2 = CustomerFile::findOne($record->_id);
$this->assertEquals($record->status, $record2->status); $this->assertEquals($record->status, $record2->status);
$this->assertEquals(file_get_contents($updateFileName), $record2->getFileContent()); $this->assertEquals(file_get_contents($updateFileName), $record2->getFileContent());
$this->assertEquals($record->tag, $record2->tag); $this->assertEquals($record->tag, $record2->tag);
...@@ -265,13 +265,13 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -265,13 +265,13 @@ class ActiveRecordTest extends MongoDbTestCase
$record->save(); $record->save();
$updateFileContent = 'New updated file content'; $updateFileContent = 'New updated file content';
$record = CustomerFile::find($record->_id); $record = CustomerFile::findOne($record->_id);
$record->setAttribute('newFileContent', $updateFileContent); $record->setAttribute('newFileContent', $updateFileContent);
$record->status = 55; $record->status = 55;
$record->save(); $record->save();
$this->assertEquals($updateFileContent, $record->getFileContent()); $this->assertEquals($updateFileContent, $record->getFileContent());
$record2 = CustomerFile::find($record->_id); $record2 = CustomerFile::findOne($record->_id);
$this->assertEquals($record->status, $record2->status); $this->assertEquals($record->status, $record2->status);
$this->assertEquals($updateFileContent, $record2->getFileContent()); $this->assertEquals($updateFileContent, $record2->getFileContent());
} }
...@@ -292,7 +292,7 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -292,7 +292,7 @@ class ActiveRecordTest extends MongoDbTestCase
$this->assertTrue($record->writeFile($outputFileName)); $this->assertTrue($record->writeFile($outputFileName));
$this->assertEquals($newFileContent, file_get_contents($outputFileName)); $this->assertEquals($newFileContent, file_get_contents($outputFileName));
$record2 = CustomerFile::find($record->_id); $record2 = CustomerFile::findOne($record->_id);
$outputFileName = $this->getTestFilePath() . DIRECTORY_SEPARATOR . 'out_refreshed.txt'; $outputFileName = $this->getTestFilePath() . DIRECTORY_SEPARATOR . 'out_refreshed.txt';
$this->assertTrue($record2->writeFile($outputFileName)); $this->assertTrue($record2->writeFile($outputFileName));
$this->assertEquals($newFileContent, file_get_contents($outputFileName)); $this->assertEquals($newFileContent, file_get_contents($outputFileName));
...@@ -315,7 +315,7 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -315,7 +315,7 @@ class ActiveRecordTest extends MongoDbTestCase
fclose($fileResource); fclose($fileResource);
$this->assertEquals($newFileContent, $contents); $this->assertEquals($newFileContent, $contents);
$record2 = CustomerFile::find($record->_id); $record2 = CustomerFile::findOne($record->_id);
$fileResource = $record2->getFileResource(); $fileResource = $record2->getFileResource();
$contents = stream_get_contents($fileResource); $contents = stream_get_contents($fileResource);
fclose($fileResource); fclose($fileResource);
......
...@@ -229,7 +229,7 @@ class ActiveRecordTest extends RedisTestCase ...@@ -229,7 +229,7 @@ class ActiveRecordTest extends RedisTestCase
{ {
// updateCounters // updateCounters
$pk = ['order_id' => 2, 'item_id' => 4]; $pk = ['order_id' => 2, 'item_id' => 4];
$orderItem = OrderItem::find($pk); $orderItem = OrderItem::findOne($pk);
$this->assertEquals(2, $orderItem->order_id); $this->assertEquals(2, $orderItem->order_id);
$this->assertEquals(4, $orderItem->item_id); $this->assertEquals(4, $orderItem->item_id);
...@@ -237,8 +237,8 @@ class ActiveRecordTest extends RedisTestCase ...@@ -237,8 +237,8 @@ class ActiveRecordTest extends RedisTestCase
$orderItem->item_id = 10; $orderItem->item_id = 10;
$orderItem->save(); $orderItem->save();
$this->assertNull(OrderItem::find($pk)); $this->assertNull(OrderItem::findOne($pk));
$this->assertNotNull(OrderItem::find(['order_id' => 2, 'item_id' => 10])); $this->assertNotNull(OrderItem::findOne(['order_id' => 2, 'item_id' => 10]));
} }
public function testFilterWhere() public function testFilterWhere()
......
...@@ -41,16 +41,16 @@ class ActiveRecordTest extends SphinxTestCase ...@@ -41,16 +41,16 @@ class ActiveRecordTest extends SphinxTestCase
$this->assertTrue($articles[1] instanceof ArticleIndex); $this->assertTrue($articles[1] instanceof ArticleIndex);
// find fulltext // find fulltext
$article = ArticleIndex::find(2); $article = ArticleIndex::findOne(2);
$this->assertTrue($article instanceof ArticleIndex); $this->assertTrue($article instanceof ArticleIndex);
$this->assertEquals(2, $article->id); $this->assertEquals(2, $article->id);
// find by column values // find by column values
$article = ArticleIndex::find(['id' => 2, 'author_id' => 2]); $article = ArticleIndex::findOne(['id' => 2, 'author_id' => 2]);
$this->assertTrue($article instanceof ArticleIndex); $this->assertTrue($article instanceof ArticleIndex);
$this->assertEquals(2, $article->id); $this->assertEquals(2, $article->id);
$this->assertEquals(2, $article->author_id); $this->assertEquals(2, $article->author_id);
$article = ArticleIndex::find(['id' => 2, 'author_id' => 1]); $article = ArticleIndex::findOne(['id' => 2, 'author_id' => 1]);
$this->assertNull($article); $this->assertNull($article);
// find by attributes // find by attributes
...@@ -148,7 +148,7 @@ class ActiveRecordTest extends SphinxTestCase ...@@ -148,7 +148,7 @@ class ActiveRecordTest extends SphinxTestCase
$record->save(); $record->save();
// save // save
$record = RuntimeIndex::find(2); $record = RuntimeIndex::findOne(2);
$this->assertTrue($record instanceof RuntimeIndex); $this->assertTrue($record instanceof RuntimeIndex);
$this->assertEquals(7, $record->type_id); $this->assertEquals(7, $record->type_id);
$this->assertFalse($record->isNewRecord); $this->assertFalse($record->isNewRecord);
...@@ -157,14 +157,14 @@ class ActiveRecordTest extends SphinxTestCase ...@@ -157,14 +157,14 @@ class ActiveRecordTest extends SphinxTestCase
$record->save(); $record->save();
$this->assertEquals(9, $record->type_id); $this->assertEquals(9, $record->type_id);
$this->assertFalse($record->isNewRecord); $this->assertFalse($record->isNewRecord);
$record2 = RuntimeIndex::find(['id' => 2]); $record2 = RuntimeIndex::findOne(['id' => 2]);
$this->assertEquals(9, $record2->type_id); $this->assertEquals(9, $record2->type_id);
// replace // replace
$query = 'replace'; $query = 'replace';
$rows = RuntimeIndex::find()->match($query)->all(); $rows = RuntimeIndex::find()->match($query)->all();
$this->assertEmpty($rows); $this->assertEmpty($rows);
$record = RuntimeIndex::find(2); $record = RuntimeIndex::findOne(2);
$record->content = 'Test content with ' . $query; $record->content = 'Test content with ' . $query;
$record->save(); $record->save();
$rows = RuntimeIndex::find()->match($query); $rows = RuntimeIndex::find()->match($query);
...@@ -174,7 +174,7 @@ class ActiveRecordTest extends SphinxTestCase ...@@ -174,7 +174,7 @@ class ActiveRecordTest extends SphinxTestCase
$pk = ['id' => 2]; $pk = ['id' => 2];
$ret = RuntimeIndex::updateAll(['type_id' => 55], $pk); $ret = RuntimeIndex::updateAll(['type_id' => 55], $pk);
$this->assertEquals(1, $ret); $this->assertEquals(1, $ret);
$record = RuntimeIndex::find($pk); $record = RuntimeIndex::findOne($pk);
$this->assertEquals(55, $record->type_id); $this->assertEquals(55, $record->type_id);
} }
...@@ -192,9 +192,9 @@ class ActiveRecordTest extends SphinxTestCase ...@@ -192,9 +192,9 @@ class ActiveRecordTest extends SphinxTestCase
$record->category = [1, 2]; $record->category = [1, 2];
$record->save(); $record->save();
$record = RuntimeIndex::find(2); $record = RuntimeIndex::findOne(2);
$record->delete(); $record->delete();
$record = RuntimeIndex::find(2); $record = RuntimeIndex::findOne(2);
$this->assertNull($record); $this->assertNull($record);
// deleteAll // deleteAll
......
...@@ -24,7 +24,7 @@ class ActiveRelationTest extends SphinxTestCase ...@@ -24,7 +24,7 @@ class ActiveRelationTest extends SphinxTestCase
public function testFindLazy() public function testFindLazy()
{ {
/** @var ArticleDb $article */ /** @var ArticleDb $article */
$article = ArticleDb::find(['id' => 2]); $article = ArticleDb::findOne(['id' => 2]);
$this->assertFalse($article->isRelationPopulated('index')); $this->assertFalse($article->isRelationPopulated('index'));
$index = $article->index; $index = $article->index;
$this->assertTrue($article->isRelationPopulated('index')); $this->assertTrue($article->isRelationPopulated('index'));
......
...@@ -24,7 +24,7 @@ class ExternalActiveRelationTest extends SphinxTestCase ...@@ -24,7 +24,7 @@ class ExternalActiveRelationTest extends SphinxTestCase
public function testFindLazy() public function testFindLazy()
{ {
/** @var ArticleIndex $article */ /** @var ArticleIndex $article */
$article = ArticleIndex::find(['id' => 2]); $article = ArticleIndex::findOne(['id' => 2]);
// has one : // has one :
$this->assertFalse($article->isRelationPopulated('source')); $this->assertFalse($article->isRelationPopulated('source'));
......
...@@ -55,7 +55,7 @@ class ActiveDataProviderTest extends DatabaseTestCase ...@@ -55,7 +55,7 @@ class ActiveDataProviderTest extends DatabaseTestCase
public function testActiveRelation() public function testActiveRelation()
{ {
/** @var Customer $customer */ /** @var Customer $customer */
$customer = Customer::find(2); $customer = Customer::findOne(2);
$provider = new ActiveDataProvider([ $provider = new ActiveDataProvider([
'query' => $customer->getOrders(), 'query' => $customer->getOrders(),
]); ]);
...@@ -78,7 +78,7 @@ class ActiveDataProviderTest extends DatabaseTestCase ...@@ -78,7 +78,7 @@ class ActiveDataProviderTest extends DatabaseTestCase
public function testActiveRelationVia() public function testActiveRelationVia()
{ {
/** @var Order $order */ /** @var Order $order */
$order = Order::find(2); $order = Order::findOne(2);
$provider = new ActiveDataProvider([ $provider = new ActiveDataProvider([
'query' => $order->getItems(), 'query' => $order->getItems(),
]); ]);
...@@ -102,7 +102,7 @@ class ActiveDataProviderTest extends DatabaseTestCase ...@@ -102,7 +102,7 @@ class ActiveDataProviderTest extends DatabaseTestCase
public function testActiveRelationViaTable() public function testActiveRelationViaTable()
{ {
/** @var Order $order */ /** @var Order $order */
$order = Order::find(1); $order = Order::findOne(1);
$provider = new ActiveDataProvider([ $provider = new ActiveDataProvider([
'query' => $order->getBooks(), 'query' => $order->getBooks(),
]); ]);
......
...@@ -101,13 +101,13 @@ class ActiveRecordTest extends DatabaseTestCase ...@@ -101,13 +101,13 @@ class ActiveRecordTest extends DatabaseTestCase
public function testFindLazyViaTable() public function testFindLazyViaTable()
{ {
/** @var Order $order */ /** @var Order $order */
$order = Order::find(1); $order = Order::findOne(1);
$this->assertEquals(1, $order->id); $this->assertEquals(1, $order->id);
$this->assertEquals(2, count($order->books)); $this->assertEquals(2, count($order->books));
$this->assertEquals(1, $order->items[0]->id); $this->assertEquals(1, $order->items[0]->id);
$this->assertEquals(2, $order->items[1]->id); $this->assertEquals(2, $order->items[1]->id);
$order = Order::find(2); $order = Order::findOne(2);
$this->assertEquals(2, $order->id); $this->assertEquals(2, $order->id);
$this->assertEquals(0, count($order->books)); $this->assertEquals(0, count($order->books));
} }
...@@ -148,7 +148,7 @@ class ActiveRecordTest extends DatabaseTestCase ...@@ -148,7 +148,7 @@ class ActiveRecordTest extends DatabaseTestCase
public function testDeeplyNestedTableRelation() public function testDeeplyNestedTableRelation()
{ {
/** @var Customer $customer */ /** @var Customer $customer */
$customer = Customer::find(1); $customer = Customer::findOne(1);
$this->assertNotNull($customer); $this->assertNotNull($customer);
$items = $customer->orderItems; $items = $customer->orderItems;
...@@ -356,11 +356,11 @@ class ActiveRecordTest extends DatabaseTestCase ...@@ -356,11 +356,11 @@ class ActiveRecordTest extends DatabaseTestCase
$this->assertEquals(1, count($orders[2]->books2)); $this->assertEquals(1, count($orders[2]->books2));
// lazy loading with ON condition // lazy loading with ON condition
$order = Order::find(1); $order = Order::findOne(1);
$this->assertEquals(2, count($order->books2)); $this->assertEquals(2, count($order->books2));
$order = Order::find(2); $order = Order::findOne(2);
$this->assertEquals(0, count($order->books2)); $this->assertEquals(0, count($order->books2));
$order = Order::find(3); $order = Order::findOne(3);
$this->assertEquals(1, count($order->books2)); $this->assertEquals(1, count($order->books2));
// eager loading with ON condition // eager loading with ON condition
...@@ -384,7 +384,7 @@ class ActiveRecordTest extends DatabaseTestCase ...@@ -384,7 +384,7 @@ class ActiveRecordTest extends DatabaseTestCase
$this->assertEquals(3, count($orders)); $this->assertEquals(3, count($orders));
// https://github.com/yiisoft/yii2/issues/2880 // https://github.com/yiisoft/yii2/issues/2880
$query = Order::find(1); $query = Order::findOne(1);
$customer = $query->getCustomer()->joinWith([ $customer = $query->getCustomer()->joinWith([
'orders' => function ($q) { $q->orderBy([]); } 'orders' => function ($q) { $q->orderBy([]); }
])->one(); ])->one();
...@@ -451,13 +451,13 @@ class ActiveRecordTest extends DatabaseTestCase ...@@ -451,13 +451,13 @@ class ActiveRecordTest extends DatabaseTestCase
$this->assertTrue($customers[0]->orders2[0]->customer2 === $customers[0]); $this->assertTrue($customers[0]->orders2[0]->customer2 === $customers[0]);
$this->assertTrue(empty($customers[1]->orders2)); $this->assertTrue(empty($customers[1]->orders2));
// lazy loading // lazy loading
$customer = Customer::find(2); $customer = Customer::findOne(2);
$orders = $customer->orders2; $orders = $customer->orders2;
$this->assertTrue(count($orders) === 2); $this->assertTrue(count($orders) === 2);
$this->assertTrue($customer->orders2[0]->customer2 === $customer); $this->assertTrue($customer->orders2[0]->customer2 === $customer);
$this->assertTrue($customer->orders2[1]->customer2 === $customer); $this->assertTrue($customer->orders2[1]->customer2 === $customer);
// ad-hoc lazy loading // ad-hoc lazy loading
$customer = Customer::find(2); $customer = Customer::findOne(2);
$orders = $customer->getOrders2()->all(); $orders = $customer->getOrders2()->all();
$this->assertTrue(count($orders) === 2); $this->assertTrue(count($orders) === 2);
$this->assertTrue($customer->orders2[0]->customer2 === $customer); $this->assertTrue($customer->orders2[0]->customer2 === $customer);
......
...@@ -377,4 +377,23 @@ class ArrayHelperTest extends TestCase ...@@ -377,4 +377,23 @@ class ArrayHelperTest extends TestCase
$this->assertEquals($expected, ArrayHelper::getValue($array, $key, $default)); $this->assertEquals($expected, ArrayHelper::getValue($array, $key, $default));
} }
public function testIsAssociative()
{
$this->assertFalse(ArrayHelper::isAssociative('test'));
$this->assertFalse(ArrayHelper::isAssociative([]));
$this->assertFalse(ArrayHelper::isAssociative([1, 2, 3]));
$this->assertTrue(ArrayHelper::isAssociative(['name' => 1, 'value' => 'test']));
$this->assertFalse(ArrayHelper::isAssociative(['name' => 1, 'value' => 'test', 3]));
$this->assertTrue(ArrayHelper::isAssociative(['name' => 1, 'value' => 'test', 3], false));
}
public function testIsIndexed()
{
$this->assertFalse(ArrayHelper::isIndexed('test'));
$this->assertTrue(ArrayHelper::isIndexed([]));
$this->assertTrue(ArrayHelper::isIndexed([1, 2, 3]));
$this->assertTrue(ArrayHelper::isIndexed([2 => 'a', 3 => 'b']));
$this->assertFalse(ArrayHelper::isIndexed([2 => 'a', 3 => 'b'], true));
}
} }
...@@ -57,38 +57,38 @@ class ExistValidatorTest extends DatabaseTestCase ...@@ -57,38 +57,38 @@ class ExistValidatorTest extends DatabaseTestCase
{ {
// existing value on different table // existing value on different table
$val = new ExistValidator(['targetClass' => ValidatorTestMainModel::className(), 'targetAttribute' => 'id']); $val = new ExistValidator(['targetClass' => ValidatorTestMainModel::className(), 'targetAttribute' => 'id']);
$m = ValidatorTestRefModel::find(['id' => 1]); $m = ValidatorTestRefModel::findOne(['id' => 1]);
$val->validateAttribute($m, 'ref'); $val->validateAttribute($m, 'ref');
$this->assertFalse($m->hasErrors()); $this->assertFalse($m->hasErrors());
// non-existing value on different table // non-existing value on different table
$val = new ExistValidator(['targetClass' => ValidatorTestMainModel::className(), 'targetAttribute' => 'id']); $val = new ExistValidator(['targetClass' => ValidatorTestMainModel::className(), 'targetAttribute' => 'id']);
$m = ValidatorTestRefModel::find(['id' => 6]); $m = ValidatorTestRefModel::findOne(['id' => 6]);
$val->validateAttribute($m, 'ref'); $val->validateAttribute($m, 'ref');
$this->assertTrue($m->hasErrors('ref')); $this->assertTrue($m->hasErrors('ref'));
// existing value on same table // existing value on same table
$val = new ExistValidator(['targetAttribute' => 'ref']); $val = new ExistValidator(['targetAttribute' => 'ref']);
$m = ValidatorTestRefModel::find(['id' => 2]); $m = ValidatorTestRefModel::findOne(['id' => 2]);
$val->validateAttribute($m, 'test_val'); $val->validateAttribute($m, 'test_val');
$this->assertFalse($m->hasErrors()); $this->assertFalse($m->hasErrors());
// non-existing value on same table // non-existing value on same table
$val = new ExistValidator(['targetAttribute' => 'ref']); $val = new ExistValidator(['targetAttribute' => 'ref']);
$m = ValidatorTestRefModel::find(['id' => 5]); $m = ValidatorTestRefModel::findOne(['id' => 5]);
$val->validateAttribute($m, 'test_val_fail'); $val->validateAttribute($m, 'test_val_fail');
$this->assertTrue($m->hasErrors('test_val_fail')); $this->assertTrue($m->hasErrors('test_val_fail'));
// check for given value (true) // check for given value (true)
$val = new ExistValidator(); $val = new ExistValidator();
$m = ValidatorTestRefModel::find(['id' => 3]); $m = ValidatorTestRefModel::findOne(['id' => 3]);
$val->validateAttribute($m, 'ref'); $val->validateAttribute($m, 'ref');
$this->assertFalse($m->hasErrors()); $this->assertFalse($m->hasErrors());
// check for given defaults (false) // check for given defaults (false)
$val = new ExistValidator(); $val = new ExistValidator();
$m = ValidatorTestRefModel::find(['id' => 4]); $m = ValidatorTestRefModel::findOne(['id' => 4]);
$m->a_field = 'some new value'; $m->a_field = 'some new value';
$val->validateAttribute($m, 'a_field'); $val->validateAttribute($m, 'a_field');
$this->assertTrue($m->hasErrors('a_field')); $this->assertTrue($m->hasErrors('a_field'));
// check array // check array
$val = new ExistValidator(['targetAttribute' => 'ref']); $val = new ExistValidator(['targetAttribute' => 'ref']);
$m = ValidatorTestRefModel::find(['id' => 2]); $m = ValidatorTestRefModel::findOne(['id' => 2]);
$m->test_val = [1,2,3]; $m->test_val = [1,2,3];
$val->validateAttribute($m, 'test_val'); $val->validateAttribute($m, 'test_val');
$this->assertTrue($m->hasErrors('test_val')); $this->assertTrue($m->hasErrors('test_val'));
...@@ -101,7 +101,7 @@ class ExistValidatorTest extends DatabaseTestCase ...@@ -101,7 +101,7 @@ class ExistValidatorTest extends DatabaseTestCase
'targetAttribute' => ['order_id', 'item_id'], 'targetAttribute' => ['order_id', 'item_id'],
]); ]);
// validate old record // validate old record
$m = OrderItem::find(['order_id' => 1, 'item_id' => 2]); $m = OrderItem::findOne(['order_id' => 1, 'item_id' => 2]);
$val->validateAttribute($m, 'order_id'); $val->validateAttribute($m, 'order_id');
$this->assertFalse($m->hasErrors('order_id')); $this->assertFalse($m->hasErrors('order_id'));
...@@ -118,10 +118,10 @@ class ExistValidatorTest extends DatabaseTestCase ...@@ -118,10 +118,10 @@ class ExistValidatorTest extends DatabaseTestCase
'targetAttribute' => ['id' => 'order_id'], 'targetAttribute' => ['id' => 'order_id'],
]); ]);
// validate old record // validate old record
$m = Order::find(1); $m = Order::findOne(1);
$val->validateAttribute($m, 'id'); $val->validateAttribute($m, 'id');
$this->assertFalse($m->hasErrors('id')); $this->assertFalse($m->hasErrors('id'));
$m = Order::find(1); $m = Order::findOne(1);
$m->id = 10; $m->id = 10;
$val->validateAttribute($m, 'id'); $val->validateAttribute($m, 'id');
$this->assertTrue($m->hasErrors('id')); $this->assertTrue($m->hasErrors('id'));
......
...@@ -35,7 +35,7 @@ class UniqueValidatorTest extends DatabaseTestCase ...@@ -35,7 +35,7 @@ class UniqueValidatorTest extends DatabaseTestCase
$m = ValidatorTestMainModel::find()->one(); $m = ValidatorTestMainModel::find()->one();
$val->validateAttribute($m, 'id'); $val->validateAttribute($m, 'id');
$this->assertFalse($m->hasErrors('id')); $this->assertFalse($m->hasErrors('id'));
$m = ValidatorTestRefModel::find(1); $m = ValidatorTestRefModel::findOne(1);
$val->validateAttribute($m, 'ref'); $val->validateAttribute($m, 'ref');
$this->assertTrue($m->hasErrors('ref')); $this->assertTrue($m->hasErrors('ref'));
// new record: // new record:
...@@ -70,10 +70,10 @@ class UniqueValidatorTest extends DatabaseTestCase ...@@ -70,10 +70,10 @@ class UniqueValidatorTest extends DatabaseTestCase
public function testValidateNonDatabaseAttribute() public function testValidateNonDatabaseAttribute()
{ {
$val = new UniqueValidator(['targetClass' => ValidatorTestRefModel::className(), 'targetAttribute' => 'ref']); $val = new UniqueValidator(['targetClass' => ValidatorTestRefModel::className(), 'targetAttribute' => 'ref']);
$m = ValidatorTestMainModel::find(1); $m = ValidatorTestMainModel::findOne(1);
$val->validateAttribute($m, 'testMainVal'); $val->validateAttribute($m, 'testMainVal');
$this->assertFalse($m->hasErrors('testMainVal')); $this->assertFalse($m->hasErrors('testMainVal'));
$m = ValidatorTestMainModel::find(1); $m = ValidatorTestMainModel::findOne(1);
$m->testMainVal = 4; $m->testMainVal = 4;
$val->validateAttribute($m, 'testMainVal'); $val->validateAttribute($m, 'testMainVal');
$this->assertTrue($m->hasErrors('testMainVal')); $this->assertTrue($m->hasErrors('testMainVal'));
...@@ -94,7 +94,7 @@ class UniqueValidatorTest extends DatabaseTestCase ...@@ -94,7 +94,7 @@ class UniqueValidatorTest extends DatabaseTestCase
'targetAttribute' => ['order_id', 'item_id'], 'targetAttribute' => ['order_id', 'item_id'],
]); ]);
// validate old record // validate old record
$m = OrderItem::find(['order_id' => 1, 'item_id' => 2]); $m = OrderItem::findOne(['order_id' => 1, 'item_id' => 2]);
$val->validateAttribute($m, 'order_id'); $val->validateAttribute($m, 'order_id');
$this->assertFalse($m->hasErrors('order_id')); $this->assertFalse($m->hasErrors('order_id'));
$m->item_id = 1; $m->item_id = 1;
...@@ -114,14 +114,14 @@ class UniqueValidatorTest extends DatabaseTestCase ...@@ -114,14 +114,14 @@ class UniqueValidatorTest extends DatabaseTestCase
'targetAttribute' => ['id' => 'order_id'], 'targetAttribute' => ['id' => 'order_id'],
]); ]);
// validate old record // validate old record
$m = Order::find(1); $m = Order::findOne(1);
$val->validateAttribute($m, 'id'); $val->validateAttribute($m, 'id');
$this->assertTrue($m->hasErrors('id')); $this->assertTrue($m->hasErrors('id'));
$m = Order::find(1); $m = Order::findOne(1);
$m->id = 2; $m->id = 2;
$val->validateAttribute($m, 'id'); $val->validateAttribute($m, 'id');
$this->assertTrue($m->hasErrors('id')); $this->assertTrue($m->hasErrors('id'));
$m = Order::find(1); $m = Order::findOne(1);
$m->id = 10; $m->id = 10;
$val->validateAttribute($m, 'id'); $val->validateAttribute($m, 'id');
$this->assertFalse($m->hasErrors('id')); $this->assertFalse($m->hasErrors('id'));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment