Fix #20654: Add missing generics in yii\db namespace. Fix PHPDoc annotations in yii\db\ArrayExpression

This commit is contained in:
Maksim Spirkov
2025-10-29 14:42:19 +03:00
committed by GitHub
parent 6238940918
commit 5dcf4b853d
16 changed files with 98 additions and 34 deletions

View File

@@ -73,6 +73,7 @@ Yii Framework 2 Change Log
- Bug #20639: Add missing generics in `yii\web` namespace (mspirkov) - Bug #20639: Add missing generics in `yii\web` namespace (mspirkov)
- Bug #20645: Add missing generics in `yii\helpers` and `yii\test` namespaces. Fix PHPDoc annotations in `ArrayAccessTrait` (mspirkov) - Bug #20645: Add missing generics in `yii\helpers` and `yii\test` namespaces. Fix PHPDoc annotations in `ArrayAccessTrait` (mspirkov)
- Bug #20640: Fix `@param` annotation for `$block` in `yii\console\Markdown::renderParagraph()` (mspirkov) - Bug #20640: Fix `@param` annotation for `$block` in `yii\console\Markdown::renderParagraph()` (mspirkov)
- Bug #20654: Add missing generics in `yii\db` namespace. Fix PHPDoc annotations in `yii\db\ArrayExpression` (mspirkov)
- Bug #20651: Add missing generics in `yii\filters` namespace (mspirkov) - Bug #20651: Add missing generics in `yii\filters` namespace (mspirkov)

View File

@@ -191,7 +191,10 @@ class ActiveQuery extends Query implements ActiveQueryInterface
$this->filterByModels($viaModels); $this->filterByModels($viaModels);
} elseif (is_array($this->via)) { } elseif (is_array($this->via)) {
// via relation // via relation
/** @var self $viaQuery */ /**
* @var self $viaQuery
* @phpstan-var self<ActiveRecord|array<string, mixed>> $viaQuery
*/
list($viaName, $viaQuery, $viaCallableUsed) = $this->via; list($viaName, $viaQuery, $viaCallableUsed) = $this->via;
if ($viaQuery->multiple) { if ($viaQuery->multiple) {
if ($viaCallableUsed) { if ($viaCallableUsed) {
@@ -458,7 +461,10 @@ class ActiveQuery extends Query implements ActiveQueryInterface
list(, $relation, $alias) = $matches; list(, $relation, $alias) = $matches;
$name = $relation; $name = $relation;
$callback = function ($query) use ($callback, $alias) { $callback = function ($query) use ($callback, $alias) {
/** @var self $query */ /**
* @var self $query
* @phpstan-var self<ActiveRecord|array<string, mixed>> $query
*/
$query->alias($alias); $query->alias($alias);
if ($callback !== null) { if ($callback !== null) {
call_user_func($callback, $query); call_user_func($callback, $query);
@@ -648,6 +654,9 @@ class ActiveQuery extends Query implements ActiveQueryInterface
* @param ActiveQuery $parent * @param ActiveQuery $parent
* @param ActiveQuery $child * @param ActiveQuery $child
* @param string $joinType * @param string $joinType
*
* @phpstan-param ActiveQuery<ActiveRecord|array<string, mixed>> $parent
* @phpstan-param ActiveQuery<ActiveRecord|array<string, mixed>> $child
*/ */
private function joinWithRelation($parent, $child, $joinType) private function joinWithRelation($parent, $child, $joinType)
{ {

View File

@@ -149,7 +149,10 @@ trait ActiveQueryTrait
$primaryModel = $modelClass::instance(); $primaryModel = $modelClass::instance();
} }
$relations = $this->normalizeRelations($primaryModel, $with); $relations = $this->normalizeRelations($primaryModel, $with);
/** @var ActiveQuery $relation */ /**
* @var ActiveQuery $relation
* @phpstan-var ActiveQuery<ActiveRecord|array<string, mixed>> $relation
*/
foreach ($relations as $name => $relation) { foreach ($relations as $name => $relation) {
if ($relation->asArray === null) { if ($relation->asArray === null) {
// inherit asArray from primary query // inherit asArray from primary query

View File

@@ -233,13 +233,19 @@ trait ActiveRelationTrait
if ($this->via instanceof self) { if ($this->via instanceof self) {
// via junction table // via junction table
/** @var self $viaQuery */ /**
* @var self $viaQuery
* @phpstan-var self<ActiveRecord|array<string, mixed>> $viaQuery
*/
$viaQuery = $this->via; $viaQuery = $this->via;
$viaModels = $viaQuery->findJunctionRows($primaryModels); $viaModels = $viaQuery->findJunctionRows($primaryModels);
$this->filterByModels($viaModels); $this->filterByModels($viaModels);
} elseif (is_array($this->via)) { } elseif (is_array($this->via)) {
// via relation // via relation
/** @var self|ActiveQueryTrait $viaQuery */ /**
* @var self|ActiveQueryTrait $viaQuery
* @phpstan-var self<ActiveRecord|array<string, mixed>>|ActiveQueryTrait $viaQuery
*/
list($viaName, $viaQuery) = $this->via; list($viaName, $viaQuery) = $this->via;
if ($viaQuery->asArray === null) { if ($viaQuery->asArray === null) {
// inherit asArray from primary query // inherit asArray from primary query
@@ -401,6 +407,8 @@ trait ActiveRelationTrait
* @param self|null $viaQuery * @param self|null $viaQuery
* @param bool $checkMultiple * @param bool $checkMultiple
* @return array * @return array
*
* @phpstan-param self<ActiveRecord|array<string, mixed>> $viaQuery
*/ */
private function buildBuckets($models, $link, $viaModels = null, $viaQuery = null, $checkMultiple = true) private function buildBuckets($models, $link, $viaModels = null, $viaQuery = null, $checkMultiple = true)
{ {

View File

@@ -25,6 +25,9 @@ use yii\base\InvalidConfigException;
* @author Dmytro Naumenko <d.naumenko.a@gmail.com> * @author Dmytro Naumenko <d.naumenko.a@gmail.com>
* @since 2.0.14 * @since 2.0.14
* @phpcs:disable Squiz.NamingConventions.ValidVariableName.PrivateNoUnderscore * @phpcs:disable Squiz.NamingConventions.ValidVariableName.PrivateNoUnderscore
*
* @implements \ArrayAccess<array-key, mixed>
* @implements \IteratorAggregate<array-key, mixed>
*/ */
class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable, \IteratorAggregate class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable, \IteratorAggregate
{ {
@@ -96,7 +99,7 @@ class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable,
* Whether a offset exists * Whether a offset exists
* *
* @link https://www.php.net/manual/en/arrayaccess.offsetexists.php * @link https://www.php.net/manual/en/arrayaccess.offsetexists.php
* @param mixed $offset <p> * @param int|string $offset <p>
* An offset to check for. * An offset to check for.
* </p> * </p>
* @return bool true on success or false on failure. * @return bool true on success or false on failure.
@@ -115,7 +118,7 @@ class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable,
* Offset to retrieve * Offset to retrieve
* *
* @link https://www.php.net/manual/en/arrayaccess.offsetget.php * @link https://www.php.net/manual/en/arrayaccess.offsetget.php
* @param mixed $offset <p> * @param int|string $offset <p>
* The offset to retrieve. * The offset to retrieve.
* </p> * </p>
* @return mixed Can return all value types. * @return mixed Can return all value types.
@@ -131,7 +134,7 @@ class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable,
* Offset to set * Offset to set
* *
* @link https://www.php.net/manual/en/arrayaccess.offsetset.php * @link https://www.php.net/manual/en/arrayaccess.offsetset.php
* @param mixed $offset <p> * @param int|string $offset <p>
* The offset to assign the value to. * The offset to assign the value to.
* </p> * </p>
* @param mixed $value <p> * @param mixed $value <p>
@@ -150,7 +153,7 @@ class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable,
* Offset to unset * Offset to unset
* *
* @link https://www.php.net/manual/en/arrayaccess.offsetunset.php * @link https://www.php.net/manual/en/arrayaccess.offsetunset.php
* @param mixed $offset <p> * @param int|string $offset <p>
* The offset to unset. * The offset to unset.
* </p> * </p>
* @return void * @return void

View File

@@ -454,8 +454,13 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
*/ */
protected function createRelationQuery($class, $link, $multiple) protected function createRelationQuery($class, $link, $multiple)
{ {
/** @var ActiveRecordInterface $class */ /**
/** @var ActiveQuery $query */ * @var ActiveRecordInterface $class
* @var ActiveQuery $query
*
* @phpstan-var ActiveQuery<ActiveRecord> $query
*/
$query = $class::find(); $query = $class::find();
$query->primaryModel = $this; $query->primaryModel = $this;
$query->link = $link; $query->link = $link;
@@ -1321,7 +1326,10 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
throw new InvalidCallException('Unable to link models: the models being linked cannot be newly created.'); throw new InvalidCallException('Unable to link models: the models being linked cannot be newly created.');
} }
if (is_array($relation->via)) { if (is_array($relation->via)) {
/** @var ActiveQuery $viaRelation */ /**
* @var ActiveQuery $viaRelation
* @phpstan-var ActiveQuery<ActiveRecord|array<string, mixed>> $viaRelation
*/
list($viaName, $viaRelation) = $relation->via; list($viaName, $viaRelation) = $relation->via;
$viaClass = $viaRelation->modelClass; $viaClass = $viaRelation->modelClass;
// unset $viaName so that it can be reloaded to reflect the change // unset $viaName so that it can be reloaded to reflect the change
@@ -1414,7 +1422,10 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
if ($relation->via !== null) { if ($relation->via !== null) {
if (is_array($relation->via)) { if (is_array($relation->via)) {
/** @var ActiveQuery $viaRelation */ /**
* @var ActiveQuery $viaRelation
* @phpstan-var ActiveQuery<ActiveRecord> $viaRelation
*/
list($viaName, $viaRelation) = $relation->via; list($viaName, $viaRelation) = $relation->via;
$viaClass = $viaRelation->modelClass; $viaClass = $viaRelation->modelClass;
unset($this->_related[$viaName]); unset($this->_related[$viaName]);
@@ -1517,7 +1528,10 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
if ($relation->via !== null) { if ($relation->via !== null) {
if (is_array($relation->via)) { if (is_array($relation->via)) {
/** @var ActiveQuery $viaRelation */ /**
* @var ActiveQuery $viaRelation
* @phpstan-var ActiveQuery<ActiveRecord|array<string, mixed>> $viaRelation
*/
list($viaName, $viaRelation) = $relation->via; list($viaName, $viaRelation) = $relation->via;
$viaClass = $viaRelation->modelClass; $viaClass = $viaRelation->modelClass;
unset($this->_related[$viaName]); unset($this->_related[$viaName]);

View File

@@ -27,6 +27,8 @@ use yii\base\Component;
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*
* @implements \Iterator<int, mixed>
*/ */
class BatchQueryResult extends Component implements \Iterator class BatchQueryResult extends Component implements \Iterator
{ {

View File

@@ -131,6 +131,9 @@ use yii\caching\CacheInterface;
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*
* @phpstan-property-read Schema<ColumnSchema> $schema
* @psalm-property-read Schema<ColumnSchema> $schema
*/ */
class Connection extends Component class Connection extends Component
{ {
@@ -436,6 +439,8 @@ class Connection extends Component
private $_transaction; private $_transaction;
/** /**
* @var Schema|null the database schema * @var Schema|null the database schema
*
* @phpstan-var Schema<ColumnSchema>|null
*/ */
private $_schema; private $_schema;
/** /**
@@ -854,6 +859,9 @@ class Connection extends Component
* Returns the schema information for the database opened by this connection. * Returns the schema information for the database opened by this connection.
* @return Schema the schema information for the database opened by this connection. * @return Schema the schema information for the database opened by this connection.
* @throws NotSupportedException if there is no support for the current driver type * @throws NotSupportedException if there is no support for the current driver type
*
* @phpstan-return Schema<ColumnSchema>
* @psalm-return Schema<ColumnSchema>
*/ */
public function getSchema() public function getSchema()
{ {

View File

@@ -47,6 +47,8 @@ use yii\base\InvalidCallException;
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*
* @implements \Iterator<int, mixed>
*/ */
class DataReader extends \yii\base\BaseObject implements \Iterator, \Countable class DataReader extends \yii\base\BaseObject implements \Iterator, \Countable
{ {

View File

@@ -400,12 +400,15 @@ class QueryBuilder extends \yii\base\BaseObject
* Prepare select-subquery and field names for INSERT INTO ... SELECT SQL statement. * Prepare select-subquery and field names for INSERT INTO ... SELECT SQL statement.
* *
* @param Query $columns Object, which represents select query. * @param Query $columns Object, which represents select query.
* @param \yii\db\Schema $schema Schema object to quote column name. * @param Schema $schema Schema object to quote column name.
* @param array $params the parameters to be bound to the generated SQL statement. These parameters will * @param array $params the parameters to be bound to the generated SQL statement. These parameters will
* be included in the result with the additional parameters generated during the query building process. * be included in the result with the additional parameters generated during the query building process.
* @return array array of column names, values and params. * @return array array of column names, values and params.
* @throws InvalidArgumentException if query's select does not contain named parameters only. * @throws InvalidArgumentException if query's select does not contain named parameters only.
* @since 2.0.11 * @since 2.0.11
*
* @phpstan-param Schema<ColumnSchema> $schema
* @psalm-param Schema<ColumnSchema> $schema
*/ */
protected function prepareInsertSelectSubQuery($columns, $schema, $params = []) protected function prepareInsertSelectSubQuery($columns, $schema, $params = [])
{ {

View File

@@ -19,6 +19,8 @@ use yii\base\BaseObject;
* *
* @author Sergey Makinen <sergey@makinen.ru> * @author Sergey Makinen <sergey@makinen.ru>
* @since 2.0.13 * @since 2.0.13
*
* @implements \ArrayAccess<int, SqlToken>
*/ */
class SqlToken extends BaseObject implements \ArrayAccess class SqlToken extends BaseObject implements \ArrayAccess
{ {

View File

@@ -46,6 +46,8 @@ abstract class SqlTokenizer extends Component
/** /**
* @var \SplStack stack of active tokens. * @var \SplStack stack of active tokens.
*
* @phpstan-var \SplStack<SqlToken>
*/ */
private $_tokenStack; private $_tokenStack;
/** /**

View File

@@ -9,6 +9,7 @@ namespace yii\db\cubrid;
use yii\base\InvalidArgumentException; use yii\base\InvalidArgumentException;
use yii\base\NotSupportedException; use yii\base\NotSupportedException;
use yii\db\ColumnSchema;
use yii\db\Exception; use yii\db\Exception;
use yii\db\Expression; use yii\db\Expression;
@@ -183,7 +184,10 @@ class QueryBuilder extends \yii\db\QueryBuilder
*/ */
public function dropIndex($name, $table) public function dropIndex($name, $table)
{ {
/** @var Schema $schema */ /**
* @var Schema $schema
* @phpstan-var Schema<ColumnSchema>
*/
$schema = $this->db->getSchema(); $schema = $this->db->getSchema();
foreach ($schema->getTableUniques($table) as $unique) { foreach ($schema->getTableUniques($table) as $unique) {
if ($unique->name === $name) { if ($unique->name === $name) {

View File

@@ -280,10 +280,15 @@ class QueryBuilder extends \yii\db\QueryBuilder
*/ */
public function checkIntegrity($check = true, $schema = '', $table = '') public function checkIntegrity($check = true, $schema = '', $table = '')
{ {
/**
* @var Schema
* @phpstan-var Schema<ColumnSchema>
*/
$dbSchema = $this->db->getSchema();
$enable = $check ? 'CHECK' : 'NOCHECK'; $enable = $check ? 'CHECK' : 'NOCHECK';
$schema = $schema ?: $this->db->getSchema()->defaultSchema; $schema = $schema ?: $dbSchema->defaultSchema;
$tableNames = $this->db->getTableSchema($table) ? [$table] : $this->db->getSchema()->getTableNames($schema); $tableNames = $this->db->getTableSchema($table) ? [$table] : $dbSchema->getTableNames($schema);
$viewNames = $this->db->getSchema()->getViewNames($schema); $viewNames = $dbSchema->getViewNames($schema);
$tableNames = array_diff($tableNames, $viewNames); $tableNames = array_diff($tableNames, $viewNames);
$command = ''; $command = '';

View File

@@ -208,10 +208,15 @@ class QueryBuilder extends \yii\db\QueryBuilder
*/ */
public function checkIntegrity($check = true, $schema = '', $table = '') public function checkIntegrity($check = true, $schema = '', $table = '')
{ {
/**
* @var Schema
* @phpstan-var Schema<ColumnSchema>
*/
$dbSchema = $this->db->getSchema();
$enable = $check ? 'ENABLE' : 'DISABLE'; $enable = $check ? 'ENABLE' : 'DISABLE';
$schema = $schema ?: $this->db->getSchema()->defaultSchema; $schema = $schema ?: $dbSchema->defaultSchema;
$tableNames = $table ? [$table] : $this->db->getSchema()->getTableNames($schema); $tableNames = $table ? [$table] : $dbSchema->getTableNames($schema);
$viewNames = $this->db->getSchema()->getViewNames($schema); $viewNames = $dbSchema->getViewNames($schema);
$tableNames = array_diff($tableNames, $viewNames); $tableNames = array_diff($tableNames, $viewNames);
$command = ''; $command = '';
@@ -376,7 +381,10 @@ class QueryBuilder extends \yii\db\QueryBuilder
$updateColumns = false; $updateColumns = false;
} }
/** @var Schema $schema */ /**
* @var Schema $schema
* @phpstan-var Schema<ColumnSchema>
*/
$schema = $this->db->getSchema(); $schema = $this->db->getSchema();
if (!$insertColumns instanceof Query) { if (!$insertColumns instanceof Query) {
$tableSchema = $schema->getTableSchema($table); $tableSchema = $schema->getTableSchema($table);

View File

@@ -55,11 +55,6 @@ parameters:
count: 1 count: 1
path: framework/grid/DataColumn.php path: framework/grid/DataColumn.php
-
message: "#^Call to an undefined method yii\\\\db\\\\Schema\\:\\:getViewNames\\(\\)\\.$#"
count: 1
path: framework/db/pgsql/QueryBuilder.php
- -
message: "#^Call to an undefined method yii\\\\db\\\\ExpressionInterface\\:\\:getValue\\(\\)\\.$#" message: "#^Call to an undefined method yii\\\\db\\\\ExpressionInterface\\:\\:getValue\\(\\)\\.$#"
count: 1 count: 1
@@ -85,11 +80,6 @@ parameters:
count: 1 count: 1
path: framework/db/mysql/JsonExpressionBuilder.php path: framework/db/mysql/JsonExpressionBuilder.php
-
message: "#^Call to an undefined method yii\\\\db\\\\Schema\\:\\:getViewNames\\(\\)\\.$#"
count: 1
path: framework/db/mssql/QueryBuilder.php
- -
message: "#^Access to an undefined property yii\\\\db\\\\ColumnSchema\\:\\:\\$isComputed\\.$#" message: "#^Access to an undefined property yii\\\\db\\\\ColumnSchema\\:\\:\\$isComputed\\.$#"
count: 1 count: 1
@@ -401,7 +391,7 @@ parameters:
path: framework/db/BaseActiveRecord.php path: framework/db/BaseActiveRecord.php
- -
message: "#^Property yii\\\\db\\\\ActiveQuery\\<array\\|yii\\\\db\\\\ActiveRecord\\>\\:\\:\\$primaryModel \\(yii\\\\db\\\\ActiveRecord\\) does not accept \\$this\\(yii\\\\db\\\\BaseActiveRecord\\)\\.$#" message: "#^Property yii\\\\db\\\\ActiveQuery\\<yii\\\\db\\\\ActiveRecord\\>\\:\\:\\$primaryModel \\(yii\\\\db\\\\ActiveRecord\\) does not accept \\$this\\(yii\\\\db\\\\BaseActiveRecord\\)\\.$#"
count: 1 count: 1
path: framework/db/BaseActiveRecord.php path: framework/db/BaseActiveRecord.php