diff --git a/lib/Doctrine/ORM/Query/ResultSetMapping.php b/lib/Doctrine/ORM/Query/ResultSetMapping.php index 66ea0c0aaea..a77b94466dc 100644 --- a/lib/Doctrine/ORM/Query/ResultSetMapping.php +++ b/lib/Doctrine/ORM/Query/ResultSetMapping.php @@ -25,17 +25,15 @@ class ResultSetMapping * Whether the result is mixed (contains scalar values together with field values). * * @ignore - * @var bool */ - public $isMixed = false; + public bool $isMixed = false; /** * Whether the result is a select statement. * * @ignore - * @var bool */ - public $isSelect = true; + public bool $isSelect = true; /** * Maps alias names to class names. @@ -43,7 +41,7 @@ class ResultSetMapping * @ignore * @psalm-var array */ - public $aliasMap = []; + public array $aliasMap = []; /** * Maps alias names to related association field names. @@ -51,7 +49,7 @@ class ResultSetMapping * @ignore * @psalm-var array */ - public $relationMap = []; + public array $relationMap = []; /** * Maps alias names to parent alias names. @@ -59,7 +57,7 @@ class ResultSetMapping * @ignore * @psalm-var array */ - public $parentAliasMap = []; + public array $parentAliasMap = []; /** * Maps column names in the result set to field names for each class. @@ -67,15 +65,15 @@ class ResultSetMapping * @ignore * @psalm-var array */ - public $fieldMappings = []; + public array $fieldMappings = []; /** * Maps column names in the result set to the alias/field name to use in the mapped result. * * @ignore - * @psalm-var array + * @psalm-var array */ - public $scalarMappings = []; + public array $scalarMappings = []; /** * Maps column names in the result set to the alias/field type to use in the mapped result. @@ -83,7 +81,7 @@ class ResultSetMapping * @ignore * @psalm-var array */ - public $typeMappings = []; + public array $typeMappings = []; /** * Maps entities in the result set to the alias name to use in the mapped result. @@ -91,7 +89,7 @@ class ResultSetMapping * @ignore * @psalm-var array */ - public $entityMappings = []; + public array $entityMappings = []; /** * Maps column names of meta columns (foreign keys, discriminator columns, ...) to field names. @@ -99,7 +97,7 @@ class ResultSetMapping * @ignore * @psalm-var array */ - public $metaMappings = []; + public array $metaMappings = []; /** * Maps column names in the result set to the alias they belong to. @@ -107,7 +105,7 @@ class ResultSetMapping * @ignore * @psalm-var array */ - public $columnOwnerMap = []; + public array $columnOwnerMap = []; /** * List of columns in the result set that are used as discriminator columns. @@ -115,7 +113,7 @@ class ResultSetMapping * @ignore * @psalm-var array */ - public $discriminatorColumns = []; + public array $discriminatorColumns = []; /** * Maps alias names to field names that should be used for indexing. @@ -123,7 +121,7 @@ class ResultSetMapping * @ignore * @psalm-var array */ - public $indexByMap = []; + public array $indexByMap = []; /** * Map from column names to class names that declare the field the column is mapped to. @@ -131,35 +129,35 @@ class ResultSetMapping * @ignore * @psalm-var array */ - public $declaringClasses = []; + public array $declaringClasses = []; /** * This is necessary to hydrate derivate foreign keys correctly. * * @psalm-var array> */ - public $isIdentifierColumn = []; + public array $isIdentifierColumn = []; /** * Maps column names in the result set to field names for each new object expression. * * @psalm-var array> */ - public $newObjectMappings = []; + public array $newObjectMappings = []; /** * Maps metadata parameter names to the metadata attribute. * * @psalm-var array */ - public $metadataParameterMapping = []; + public array $metadataParameterMapping = []; /** * Contains query parameter names to be resolved as discriminator values * * @psalm-var array */ - public $discriminatorParameters = []; + public array $discriminatorParameters = []; /** * Adds an entity result to this ResultSetMapping. @@ -169,12 +167,13 @@ class ResultSetMapping * results or joined entity results within this ResultSetMapping. * @param string|null $resultAlias The result alias with which the entity result should be * placed in the result structure. + * @psalm-param class-string $class * * @return $this * * @todo Rename: addRootEntity */ - public function addEntityResult($class, $alias, $resultAlias = null) + public function addEntityResult(string $class, string $alias, ?string $resultAlias = null): static { $this->aliasMap[$alias] = $class; $this->entityMappings[$alias] = $resultAlias; @@ -199,7 +198,7 @@ public function addEntityResult($class, $alias, $resultAlias = null) * * @todo Rename: addDiscriminatorColumn */ - public function setDiscriminatorColumn($alias, $discrColumn) + public function setDiscriminatorColumn(string $alias, string $discrColumn): static { $this->discriminatorColumns[$alias] = $discrColumn; $this->columnOwnerMap[$discrColumn] = $alias; @@ -215,7 +214,7 @@ public function setDiscriminatorColumn($alias, $discrColumn) * * @return $this */ - public function addIndexBy($alias, $fieldName) + public function addIndexBy(string $alias, string $fieldName): static { $found = false; @@ -248,11 +247,9 @@ public function addIndexBy($alias, $fieldName) /** * Sets to index by a scalar result column name. * - * @param string $resultColumnName - * * @return $this */ - public function addIndexByScalar($resultColumnName) + public function addIndexByScalar(string $resultColumnName): static { $this->indexByMap['scalars'] = $resultColumnName; @@ -262,12 +259,9 @@ public function addIndexByScalar($resultColumnName) /** * Sets a column to use for indexing an entity or joined entity result by the given alias name. * - * @param string $alias - * @param string $resultColumnName - * * @return $this */ - public function addIndexByColumn($alias, $resultColumnName) + public function addIndexByColumn(string $alias, string $resultColumnName): static { $this->indexByMap[$alias] = $resultColumnName; @@ -278,13 +272,9 @@ public function addIndexByColumn($alias, $resultColumnName) * Checks whether an entity result or joined entity result with a given alias has * a field set for indexing. * - * @param string $alias - * - * @return bool - * * @todo Rename: isIndexed($alias) */ - public function hasIndexBy($alias) + public function hasIndexBy(string $alias): bool { return isset($this->indexByMap[$alias]); } @@ -295,11 +285,9 @@ public function hasIndexBy($alias) * * @param string $columnName The name of the column in the SQL result set. * - * @return bool - * * @todo Rename: isField */ - public function isFieldResult($columnName) + public function isFieldResult(string $columnName): bool { return isset($this->fieldMappings[$columnName]); } @@ -315,12 +303,13 @@ public function isFieldResult($columnName) * the field $fieldName is defined on a subclass, specify that here. * If not specified, the field is assumed to belong to the class * designated by $alias. + * @psalm-param class-string|null $declaringClass * * @return $this * * @todo Rename: addField */ - public function addFieldResult($alias, $columnName, $fieldName, $declaringClass = null) + public function addFieldResult(string $alias, string $columnName, string $fieldName, ?string $declaringClass = null): static { // column name (in result set) => field name $this->fieldMappings[$columnName] = $fieldName; @@ -344,12 +333,13 @@ public function addFieldResult($alias, $columnName, $fieldName, $declaringClass * @param string $parentAlias The alias of the entity result that is the parent of this joined result. * @param string $relation The association field that connects the parent entity result * with the joined entity result. + * @psalm-param class-string $class * * @return $this * * @todo Rename: addJoinedEntity */ - public function addJoinedEntityResult($class, $alias, $parentAlias, $relation) + public function addJoinedEntityResult(string $class, string $alias, string $parentAlias, string $relation): static { $this->aliasMap[$alias] = $class; $this->parentAliasMap[$alias] = $parentAlias; @@ -361,15 +351,15 @@ public function addJoinedEntityResult($class, $alias, $parentAlias, $relation) /** * Adds a scalar result mapping. * - * @param string $columnName The name of the column in the SQL result set. - * @param string $alias The result alias with which the scalar result should be placed in the result structure. - * @param string $type The column type + * @param string $columnName The name of the column in the SQL result set. + * @param string|int $alias The result alias with which the scalar result should be placed in the result structure. + * @param string $type The column type * * @return $this * * @todo Rename: addScalar */ - public function addScalarResult($columnName, $alias, $type = 'string') + public function addScalarResult(string $columnName, string|int $alias, string $type = 'string'): static { $this->scalarMappings[$columnName] = $alias; $this->typeMappings[$columnName] = $type; @@ -383,13 +373,8 @@ public function addScalarResult($columnName, $alias, $type = 'string') /** * Adds a metadata parameter mappings. - * - * @param mixed $parameter The parameter name in the SQL result set. - * @param string $attribute The metadata attribute. - * - * @return void */ - public function addMetadataParameterMapping($parameter, $attribute) + public function addMetadataParameterMapping(string|int $parameter, string $attribute): void { $this->metadataParameterMapping[$parameter] = $attribute; } @@ -397,13 +382,9 @@ public function addMetadataParameterMapping($parameter, $attribute) /** * Checks whether a column with a given name is mapped as a scalar result. * - * @param string $columnName The name of the column in the SQL result set. - * - * @return bool - * * @todo Rename: isScalar */ - public function isScalarResult($columnName) + public function isScalarResult(string $columnName): bool { return isset($this->scalarMappings[$columnName]); } @@ -412,11 +393,9 @@ public function isScalarResult($columnName) * Gets the name of the class of an entity result or joined entity result, * identified by the given unique alias. * - * @param string $alias - * - * @return class-string + * @psalm-return class-string */ - public function getClassName($alias) + public function getClassName(string $alias): string { return $this->aliasMap[$alias]; } @@ -425,10 +404,8 @@ public function getClassName($alias) * Gets the field alias for a column that is mapped as a scalar value. * * @param string $columnName The name of the column in the SQL result set. - * - * @return string */ - public function getScalarAlias($columnName) + public function getScalarAlias(string $columnName): string|int { return $this->scalarMappings[$columnName]; } @@ -436,79 +413,51 @@ public function getScalarAlias($columnName) /** * Gets the name of the class that owns a field mapping for the specified column. * - * @param string $columnName - * - * @return class-string + * @psalm-return class-string */ - public function getDeclaringClass($columnName) + public function getDeclaringClass(string $columnName): string { return $this->declaringClasses[$columnName]; } - /** - * @param string $alias - * - * @return string - */ - public function getRelation($alias) + public function getRelation(string $alias): string { return $this->relationMap[$alias]; } - /** - * @param string $alias - * - * @return bool - */ - public function isRelation($alias) + public function isRelation(string $alias): bool { return isset($this->relationMap[$alias]); } /** * Gets the alias of the class that owns a field mapping for the specified column. - * - * @param string $columnName - * - * @return string */ - public function getEntityAlias($columnName) + public function getEntityAlias(string $columnName): string { return $this->columnOwnerMap[$columnName]; } /** * Gets the parent alias of the given alias. - * - * @param string $alias - * - * @return string */ - public function getParentAlias($alias) + public function getParentAlias(string $alias): string { return $this->parentAliasMap[$alias]; } /** * Checks whether the given alias has a parent alias. - * - * @param string $alias - * - * @return bool */ - public function hasParentAlias($alias) + public function hasParentAlias(string $alias): bool { return isset($this->parentAliasMap[$alias]); } /** * Gets the field name for a column name. - * - * @param string $columnName - * - * @return string */ - public function getFieldName($columnName) + public function getFieldName(string $columnName): string { return $this->fieldMappings[$columnName]; } @@ -516,7 +465,7 @@ public function getFieldName($columnName) /** * @psalm-return array */ - public function getAliasMap() + public function getAliasMap(): array { return $this->aliasMap; } @@ -524,10 +473,9 @@ public function getAliasMap() /** * Gets the number of different entities that appear in the mapped result. * - * @return int * @psalm-return 0|positive-int */ - public function getEntityResultCount() + public function getEntityResultCount(): int { return count($this->aliasMap); } @@ -538,10 +486,8 @@ public function getEntityResultCount() * Mixed results can only occur in object and array (graph) hydration. In such a * case a mixed result means that scalar values are mixed with objects/array in * the result. - * - * @return bool */ - public function isMixedResult() + public function isMixedResult(): bool { return $this->isMixed; } @@ -549,18 +495,22 @@ public function isMixedResult() /** * Adds a meta column (foreign key or discriminator column) to the result set. * - * @param string $alias The result alias with which the meta result should be placed in the result structure. - * @param string $columnName The name of the column in the SQL result set. - * @param string $fieldName The name of the field on the declaring class. - * @param bool $isIdentifierColumn - * @param string $type The column type + * @param string $alias The result alias with which the meta result should be placed in the result structure. + * @param string $columnName The name of the column in the SQL result set. + * @param string $fieldName The name of the field on the declaring class. + * @param string|null $type The column type * * @return $this * * @todo Make all methods of this class require all parameters and not infer anything */ - public function addMetaResult($alias, $columnName, $fieldName, $isIdentifierColumn = false, $type = null) - { + public function addMetaResult( + string $alias, + string $columnName, + string $fieldName, + bool $isIdentifierColumn = false, + ?string $type = null + ): static { $this->metaMappings[$columnName] = $fieldName; $this->columnOwnerMap[$columnName] = $alias; diff --git a/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php b/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php index 38bb5aefcf3..cce51d72559 100644 --- a/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php +++ b/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php @@ -43,26 +43,15 @@ class ResultSetMappingBuilder extends ResultSetMapping */ public const COLUMN_RENAMING_INCREMENT = 3; - /** @var int */ - private $sqlCounter = 0; - - /** @var EntityManagerInterface */ - private $em; - - /** - * Default column renaming mode. - * - * @var int - */ - private $defaultRenameMode; + private int $sqlCounter = 0; /** - * @param int $defaultRenameMode + * @psalm-param self::COLUMN_RENAMING_* $defaultRenameMode */ - public function __construct(EntityManagerInterface $em, $defaultRenameMode = self::COLUMN_RENAMING_NONE) - { - $this->em = $em; - $this->defaultRenameMode = $defaultRenameMode; + public function __construct( + private EntityManagerInterface $em, + private int $defaultRenameMode = self::COLUMN_RENAMING_NONE, + ) { } /** @@ -71,13 +60,16 @@ public function __construct(EntityManagerInterface $em, $defaultRenameMode = sel * @param string $class The class name of the root entity. * @param string $alias The unique alias to use for the root entity. * @param string[] $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName). - * @param int|null $renameMode One of the COLUMN_RENAMING_* constants or array for BC reasons (CUSTOM). + * @psalm-param class-string $class * @psalm-param array $renamedColumns - * - * @return void + * @psalm-param self::COLUMN_RENAMING_*|null $renameMode */ - public function addRootEntityFromClassMetadata($class, $alias, $renamedColumns = [], $renameMode = null) - { + public function addRootEntityFromClassMetadata( + string $class, + string $alias, + array $renamedColumns = [], + ?int $renameMode = null + ): void { $renameMode = $renameMode ?: $this->defaultRenameMode; $columnAliasMap = $this->getColumnAliasMap($class, $renameMode, $renamedColumns); @@ -94,13 +86,18 @@ public function addRootEntityFromClassMetadata($class, $alias, $renamedColumns = * @param string $relation The association field that connects the parent entity result * with the joined entity result. * @param string[] $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName). - * @param int|null $renameMode One of the COLUMN_RENAMING_* constants or array for BC reasons (CUSTOM). + * @psalm-param class-string $class * @psalm-param array $renamedColumns - * - * @return void + * @psalm-param self::COLUMN_RENAMING_*|null $renameMode */ - public function addJoinedEntityFromClassMetadata($class, $alias, $parentAlias, $relation, $renamedColumns = [], $renameMode = null) - { + public function addJoinedEntityFromClassMetadata( + string $class, + string $alias, + string $parentAlias, + string $relation, + array $renamedColumns = [], + ?int $renameMode = null + ): void { $renameMode = $renameMode ?: $this->defaultRenameMode; $columnAliasMap = $this->getColumnAliasMap($class, $renameMode, $renamedColumns); @@ -111,16 +108,12 @@ public function addJoinedEntityFromClassMetadata($class, $alias, $parentAlias, $ /** * Adds all fields of the given class to the result set mapping (columns and meta fields). * - * @param string $class - * @param string $alias * @param string[] $columnAliasMap * @psalm-param array $columnAliasMap * - * @return void - * * @throws InvalidArgumentException */ - protected function addAllClassFields($class, $alias, $columnAliasMap = []) + protected function addAllClassFields(string $class, string $alias, array $columnAliasMap = []): void { $classMetadata = $this->em->getClassMetadata($class); $platform = $this->em->getConnection()->getDatabasePlatform(); @@ -182,25 +175,17 @@ private function isInheritanceSupported(ClassMetadataInfo $classMetadata): bool * Gets column alias for a given column. * * @psalm-param array $customRenameColumns + * + * @psalm-assert self::COLUMN_RENAMING_* $mode */ private function getColumnAlias(string $columnName, int $mode, array $customRenameColumns): string { - switch ($mode) { - case self::COLUMN_RENAMING_INCREMENT: - return $columnName . $this->sqlCounter++; - - case self::COLUMN_RENAMING_CUSTOM: - return $customRenameColumns[$columnName] ?? $columnName; - - case self::COLUMN_RENAMING_NONE: - return $columnName; - - default: - throw new InvalidArgumentException(sprintf( - '%d is not a valid value for $mode', - $mode - )); - } + return match ($mode) { + self::COLUMN_RENAMING_INCREMENT => $columnName . $this->sqlCounter++, + self::COLUMN_RENAMING_CUSTOM => $customRenameColumns[$columnName] ?? $columnName, + self::COLUMN_RENAMING_NONE => $columnName, + default => throw new InvalidArgumentException(sprintf('%d is not a valid value for $mode', $mode)), + }; } /** @@ -251,10 +236,8 @@ private function getColumnAliasMap( * * @param string[] $tableAliases * @psalm-param array $tableAliases - * - * @return string */ - public function generateSelectClause($tableAliases = []) + public function generateSelectClause(array $tableAliases = []): string { $sql = ''; @@ -289,10 +272,7 @@ public function generateSelectClause($tableAliases = []) return $sql; } - /** - * @return string - */ - public function __toString() + public function __toString(): string { return $this->generateSelectClause([]); } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 60481e3ec8b..d75de9caa6d 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -730,11 +730,6 @@ parameters: count: 1 path: lib/Doctrine/ORM/Query/SqlWalker.php - - - message: "#^Parameter \\#2 \\$alias of method Doctrine\\\\ORM\\\\Query\\\\ResultSetMapping\\:\\:addScalarResult\\(\\) expects string, int given\\.$#" - count: 1 - path: lib/Doctrine/ORM/Query/SqlWalker.php - - message: "#^Result of && is always false\\.$#" count: 2 @@ -1314,3 +1309,4 @@ parameters: message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:\\$subClasses\\.$#" count: 1 path: lib/Doctrine/ORM/Utility/HierarchyDiscriminatorResolver.php + diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 9598b2193bd..5210129ad64 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -2049,21 +2049,6 @@ Comparison::EQ - - - $this->aliasMap - $this->aliasMap - $this->declaringClasses - - - - - $class - $class - $renameMode - $renameMode - - $likeExpr->stringPattern instanceof AST\Functions\FunctionNode @@ -2093,11 +2078,7 @@ $this->scalarResultAliasMap $this->scalarResultAliasMap - - $resultAlias - $resultAlias - $resultAlias - $resultAlias + $this->queryComponents[$expr]['token']['value'] $this->queryComponents[$factor]['token']['value'] $this->queryComponents[$term]['token']['value']