From 8b4dfcc8766ff933c66229431f690843de93cd95 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 3 Apr 2014 10:36:52 -0400 Subject: [PATCH] Fixes #2955: Changed the signature of ActiveQuery constructors and `ActiveRecord::createQuery()` to simplify customizing ActiveQuery classes --- docs/guide/active-record.md | 10 +++---- extensions/elasticsearch/ActiveQuery.php | 1 + extensions/elasticsearch/ActiveRecord.php | 11 +++----- extensions/mongodb/ActiveRecord.php | 11 +++----- extensions/mongodb/file/ActiveRecord.php | 11 +++----- extensions/redis/ActiveRecord.php | 11 +++----- extensions/sphinx/ActiveRecord.php | 11 +++----- framework/CHANGELOG.md | 3 +- framework/db/ActiveQueryTrait.php | 11 ++++++++ framework/db/ActiveRecord.php | 11 +++----- framework/db/ActiveRecordInterface.php | 7 ++--- framework/db/BaseActiveRecord.php | 26 ++++++++---------- framework/web/ContentTypeNegotiator.php | 35 ++++++++++++++++++++++++ tests/unit/data/ar/Customer.php | 6 ++-- tests/unit/data/ar/elasticsearch/Customer.php | 6 ++-- tests/unit/data/ar/mongodb/Customer.php | 6 ++-- tests/unit/data/ar/mongodb/file/CustomerFile.php | 6 ++-- tests/unit/data/ar/redis/Customer.php | 6 ++-- tests/unit/data/ar/sphinx/ArticleIndex.php | 6 ++-- 19 files changed, 104 insertions(+), 91 deletions(-) create mode 100644 framework/web/ContentTypeNegotiator.php diff --git a/docs/guide/active-record.md b/docs/guide/active-record.md index e7ad9dc..4e9680f 100644 --- a/docs/guide/active-record.md +++ b/docs/guide/active-record.md @@ -838,10 +838,9 @@ use yii\db\ActiveRecord; class Comment extends ActiveRecord { - public static function createQuery($config = []) + public static function createQuery() { - $config['modelClass'] = get_called_class(); - return new CommentQuery($config); + return new CommentQuery(get_called_class()); } } ``` @@ -910,10 +909,9 @@ If you used Yii 1.1 before, you may know a concept called *default scope*. A def applies to ALL queries. You can define a default scope easily by overriding [[yii\db\ActiveRecord::createQuery()]]. For example, ```php -public static function createQuery($config = []) +public static function createQuery() { - $config['modelClass'] = get_called_class(); - return (new ActiveQuery($config))->where(['deleted' => false]); + return parent::createQuery()->where(['deleted' => false]); } ``` diff --git a/extensions/elasticsearch/ActiveQuery.php b/extensions/elasticsearch/ActiveQuery.php index f2d9be7..662184d 100644 --- a/extensions/elasticsearch/ActiveQuery.php +++ b/extensions/elasticsearch/ActiveQuery.php @@ -77,6 +77,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface use ActiveQueryTrait; use ActiveRelationTrait; + /** * Creates a DB command that can be used to execute this query. * @param Connection $db the DB connection used to create the DB command. diff --git a/extensions/elasticsearch/ActiveRecord.php b/extensions/elasticsearch/ActiveRecord.php index 1827651..40dc08f 100644 --- a/extensions/elasticsearch/ActiveRecord.php +++ b/extensions/elasticsearch/ActiveRecord.php @@ -156,23 +156,20 @@ class ActiveRecord extends BaseActiveRecord * You may also define default conditions that should apply to all queries unless overridden: * * ```php - * public static function createQuery($config = []) + * public static function createQuery() * { - * return parent::createQuery($config)->where(['deleted' => false]); + * 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. * - * @param array $config the configuration passed to the ActiveQuery class. * @return ActiveQuery the newly created [[ActiveQuery]] instance. */ - public static function createQuery($config = []) + public static function createQuery() { - $config['modelClass'] = get_called_class(); - - return new ActiveQuery($config); + return new ActiveQuery(get_called_class()); } // TODO implement copy and move as pk change is not possible diff --git a/extensions/mongodb/ActiveRecord.php b/extensions/mongodb/ActiveRecord.php index e60aab7..c5ed748 100644 --- a/extensions/mongodb/ActiveRecord.php +++ b/extensions/mongodb/ActiveRecord.php @@ -102,23 +102,20 @@ abstract class ActiveRecord extends BaseActiveRecord * You may also define default conditions that should apply to all queries unless overridden: * * ```php - * public static function createQuery($config = []) + * public static function createQuery() * { - * return parent::createQuery($config)->where(['deleted' => false]); + * 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. * - * @param array $config the configuration passed to the ActiveQuery class. * @return ActiveQuery the newly created [[ActiveQuery]] instance. */ - public static function createQuery($config = []) + public static function createQuery() { - $config['modelClass'] = get_called_class(); - - return new ActiveQuery($config); + return new ActiveQuery(get_called_class()); } /** diff --git a/extensions/mongodb/file/ActiveRecord.php b/extensions/mongodb/file/ActiveRecord.php index f67e815..887f0d1 100644 --- a/extensions/mongodb/file/ActiveRecord.php +++ b/extensions/mongodb/file/ActiveRecord.php @@ -55,23 +55,20 @@ abstract class ActiveRecord extends \yii\mongodb\ActiveRecord * You may also define default conditions that should apply to all queries unless overridden: * * ```php - * public static function createQuery($config = []) + * public static function createQuery() * { - * return parent::createQuery($config)->where(['deleted' => false]); + * 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. * - * @param array $config the configuration passed to the ActiveQuery class. * @return ActiveQuery the newly created [[ActiveQuery]] instance. */ - public static function createQuery($config = []) + public static function createQuery() { - $config['modelClass'] = get_called_class(); - - return new ActiveQuery($config); + return new ActiveQuery(get_called_class()); } /** diff --git a/extensions/redis/ActiveRecord.php b/extensions/redis/ActiveRecord.php index 77883ec..5e154b2 100644 --- a/extensions/redis/ActiveRecord.php +++ b/extensions/redis/ActiveRecord.php @@ -59,23 +59,20 @@ class ActiveRecord extends BaseActiveRecord * You may also define default conditions that should apply to all queries unless overridden: * * ```php - * public static function createQuery($config = []) + * public static function createQuery() * { - * return parent::createQuery($config)->where(['deleted' => false]); + * 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. * - * @param array $config the configuration passed to the ActiveQuery class. * @return ActiveQuery the newly created [[ActiveQuery]] instance. */ - public static function createQuery($config = []) + public static function createQuery() { - $config['modelClass'] = get_called_class(); - - return new ActiveQuery($config); + return new ActiveQuery(get_called_class()); } /** diff --git a/extensions/sphinx/ActiveRecord.php b/extensions/sphinx/ActiveRecord.php index 87efa0e..290fe19 100644 --- a/extensions/sphinx/ActiveRecord.php +++ b/extensions/sphinx/ActiveRecord.php @@ -146,23 +146,20 @@ abstract class ActiveRecord extends BaseActiveRecord * You may also define default conditions that should apply to all queries unless overridden: * * ```php - * public static function createQuery($config = []) + * public static function createQuery() * { - * return parent::createQuery($config)->where(['deleted' => false]); + * 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. * - * @param array $config the configuration passed to the ActiveQuery class. * @return ActiveQuery the newly created [[ActiveQuery]] instance. */ - public static function createQuery($config = []) + public static function createQuery() { - $config['modelClass'] = get_called_class(); - - return new ActiveQuery($config); + return new ActiveQuery(get_called_class()); } /** diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index b4b6232..a424ee5 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -234,7 +234,8 @@ Yii Framework 2 Change Log - Chg #2691: Null parameters will not be included in the generated URLs by `UrlManager` (gonimar, qiangxue) - Chg #2734: `FileCache::keyPrefix` defaults to empty string now (qiangxue) - 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: Renamed `yii\jui\Widget::clientEventsMap` to `clientEventMap` (qiangxue) - Chg: Renamed `ActiveRecord::getPopulatedRelations()` to `getRelatedRecords()` (qiangxue) - Chg: Renamed `attributeName` and `className` to `targetAttribute` and `targetClass` for `UniqueValidator` and `ExistValidator` (qiangxue) diff --git a/framework/db/ActiveQueryTrait.php b/framework/db/ActiveQueryTrait.php index abc0728..6c423e3 100644 --- a/framework/db/ActiveQueryTrait.php +++ b/framework/db/ActiveQueryTrait.php @@ -32,6 +32,17 @@ trait ActiveQueryTrait /** + * Constructor. + * @param array $modelClass the model class associated with this query + * @param array $config configurations to be applied to the newly created query object + */ + public function __construct($modelClass, $config = []) + { + $this->modelClass = $modelClass; + parent::__construct($config); + } + + /** * Sets the [[asArray]] property. * @param boolean $value whether to return the query results in terms of arrays instead of Active Records. * @return static the query object itself diff --git a/framework/db/ActiveRecord.php b/framework/db/ActiveRecord.php index 324ab1b..26c4a8a 100644 --- a/framework/db/ActiveRecord.php +++ b/framework/db/ActiveRecord.php @@ -234,23 +234,20 @@ class ActiveRecord extends BaseActiveRecord * You may also define default conditions that should apply to all queries unless overridden: * * ```php - * public static function createQuery($config = []) + * public static function createQuery() * { - * return parent::createQuery($config)->where(['deleted' => false]); + * 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. * - * @param array $config the configuration passed to the ActiveQuery class. * @return ActiveQuery the newly created [[ActiveQuery]] instance. */ - public static function createQuery($config = []) + public static function createQuery() { - $config['modelClass'] = get_called_class(); - - return new ActiveQuery($config); + return new ActiveQuery(get_called_class()); } /** diff --git a/framework/db/ActiveRecordInterface.php b/framework/db/ActiveRecordInterface.php index 15a58c4..8418581 100644 --- a/framework/db/ActiveRecordInterface.php +++ b/framework/db/ActiveRecordInterface.php @@ -155,19 +155,18 @@ interface ActiveRecordInterface * You may also define default conditions that should apply to all queries unless overridden: * * ```php - * public static function createQuery($config = []) + * public static function createQuery() * { - * return parent::createQuery($config)->where(['deleted' => false]); + * 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. * - * @param array $config the configuration passed to the ActiveQuery class. * @return ActiveQueryInterface the newly created [[ActiveQueryInterface|ActiveQuery]] instance. */ - public static function createQuery($config = []); + public static function createQuery(); /** * Updates records using the provided attribute values and conditions. diff --git a/framework/db/BaseActiveRecord.php b/framework/db/BaseActiveRecord.php index 0b4ab38..e041086 100644 --- a/framework/db/BaseActiveRecord.php +++ b/framework/db/BaseActiveRecord.php @@ -309,13 +309,12 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface public function hasOne($class, $link) { /** @var ActiveRecordInterface $class */ - - return $class::createQuery([ - 'modelClass' => $class, - 'primaryModel' => $this, - 'link' => $link, - 'multiple' => false, - ]); + /** @var ActiveQuery $query */ + $query = $class::createQuery(); + $query->primaryModel = $this; + $query->link = $link; + $query->multiple = false; + return $query; } /** @@ -351,13 +350,12 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface public function hasMany($class, $link) { /** @var ActiveRecordInterface $class */ - - return $class::createQuery([ - 'modelClass' => $class, - 'primaryModel' => $this, - 'link' => $link, - 'multiple' => true, - ]); + /** @var ActiveQuery $query */ + $query = $class::createQuery(); + $query->primaryModel = $this; + $query->link = $link; + $query->multiple = true; + return $query; } /** diff --git a/framework/web/ContentTypeNegotiator.php b/framework/web/ContentTypeNegotiator.php new file mode 100644 index 0000000..51fa090 --- /dev/null +++ b/framework/web/ContentTypeNegotiator.php @@ -0,0 +1,35 @@ + + * @since 2.0 + */ +class ContentTypeNegotiator extends Component +{ + /** + * @var array list of supported API version numbers. If the current request does not specify a version + * number, the first element will be used as the [[version|chosen version number]]. For this reason, you should + * put the latest version number at the first. If this property is empty, [[version]] will not be set. + */ + public $supportedVersions = []; + /** + * @var array list of supported response formats. The array keys are the requested content MIME types, + * and the array values are the corresponding response formats. The first element will be used + * as the response format if the current request does not specify a content type. + */ + public $supportedFormats = [ + 'application/json' => Response::FORMAT_JSON, + 'application/xml' => Response::FORMAT_XML, + ]; + +} diff --git a/tests/unit/data/ar/Customer.php b/tests/unit/data/ar/Customer.php index 79f4c1a..855a4b8 100644 --- a/tests/unit/data/ar/Customer.php +++ b/tests/unit/data/ar/Customer.php @@ -62,10 +62,8 @@ class Customer extends ActiveRecord parent::afterSave($insert); } - public static function createQuery($config = []) + public static function createQuery() { - $config['modelClass'] = get_called_class(); - - return new CustomerQuery($config); + return new CustomerQuery(get_called_class()); } } diff --git a/tests/unit/data/ar/elasticsearch/Customer.php b/tests/unit/data/ar/elasticsearch/Customer.php index 6f058a5..61c1856 100644 --- a/tests/unit/data/ar/elasticsearch/Customer.php +++ b/tests/unit/data/ar/elasticsearch/Customer.php @@ -64,10 +64,8 @@ class Customer extends ActiveRecord } - public static function createQuery($config = []) + public static function createQuery() { - $config['modelClass'] = get_called_class(); - - return new CustomerQuery($config); + return new CustomerQuery(get_called_class()); } } diff --git a/tests/unit/data/ar/mongodb/Customer.php b/tests/unit/data/ar/mongodb/Customer.php index 268d931..98cf41f 100644 --- a/tests/unit/data/ar/mongodb/Customer.php +++ b/tests/unit/data/ar/mongodb/Customer.php @@ -25,10 +25,8 @@ class Customer extends ActiveRecord return $this->hasMany(CustomerOrder::className(), ['customer_id' => '_id']); } - public static function createQuery($config = []) + public static function createQuery() { - $config['modelClass'] = get_called_class(); - - return new CustomerQuery($config); + return new CustomerQuery(get_called_class()); } } diff --git a/tests/unit/data/ar/mongodb/file/CustomerFile.php b/tests/unit/data/ar/mongodb/file/CustomerFile.php index f3be658..6c97b37 100644 --- a/tests/unit/data/ar/mongodb/file/CustomerFile.php +++ b/tests/unit/data/ar/mongodb/file/CustomerFile.php @@ -20,10 +20,8 @@ class CustomerFile extends ActiveRecord ); } - public static function createQuery($config = []) + public static function createQuery() { - $config['modelClass'] = get_called_class(); - - return new CustomerFileQuery($config); + return new CustomerFileQuery(get_called_class()); } } diff --git a/tests/unit/data/ar/redis/Customer.php b/tests/unit/data/ar/redis/Customer.php index 637cea6..60c1983 100644 --- a/tests/unit/data/ar/redis/Customer.php +++ b/tests/unit/data/ar/redis/Customer.php @@ -31,10 +31,8 @@ class Customer extends ActiveRecord parent::afterSave($insert); } - public static function createQuery($config = []) + public static function createQuery() { - $config['modelClass'] = get_called_class(); - - return new CustomerQuery($config); + return new CustomerQuery(get_called_class()); } } diff --git a/tests/unit/data/ar/sphinx/ArticleIndex.php b/tests/unit/data/ar/sphinx/ArticleIndex.php index 916ddaf..742d2d4 100644 --- a/tests/unit/data/ar/sphinx/ArticleIndex.php +++ b/tests/unit/data/ar/sphinx/ArticleIndex.php @@ -25,10 +25,8 @@ class ArticleIndex extends ActiveRecord return $this->source->content; } - public static function createQuery($config = []) + public static function createQuery() { - $config['modelClass'] = get_called_class(); - - return new ArticleIndexQuery($config); + return new ArticleIndexQuery(get_called_class()); } }