diff --git a/src/Bridges/NetteDI/DIRepositoryFinder.php b/src/Bridges/NetteDI/DIRepositoryFinder.php index 3ca261f3..0ef3a85c 100644 --- a/src/Bridges/NetteDI/DIRepositoryFinder.php +++ b/src/Bridges/NetteDI/DIRepositoryFinder.php @@ -59,7 +59,7 @@ public function beforeCompile(): ?array ); } - /** @var class-string $class */ + /** @var class-string> $class */ $class = $serviceDefinition->getType(); $repositories[$name] = $class; $repositoriesMap[$class] = $serviceName; @@ -80,7 +80,7 @@ protected function getRepositoryName(string $serviceName, $serviceDefinition): s /** - * @param array, string> $repositoriesMap + * @param array>, string> $repositoriesMap */ protected function setupRepositoryLoader(array $repositoriesMap): void { diff --git a/src/Bridges/NetteDI/IRepositoryFinder.php b/src/Bridges/NetteDI/IRepositoryFinder.php index 7b527e30..0be170c9 100644 --- a/src/Bridges/NetteDI/IRepositoryFinder.php +++ b/src/Bridges/NetteDI/IRepositoryFinder.php @@ -17,7 +17,7 @@ public function __construct(string $modelClass, ContainerBuilder $containerBuild /** * Load configuration DIC phase. * Returns array of repositories or null if they are loaded in the other phase. - * @return array> + * @return array>> */ public function loadConfiguration(): ?array; @@ -25,7 +25,7 @@ public function loadConfiguration(): ?array; /** * Before compile DIC phase. * Returns array of repositories or null if they are loaded in the other phase. - * @return array> + * @return array>> */ public function beforeCompile(): ?array; } diff --git a/src/Bridges/NetteDI/OrmExtension.php b/src/Bridges/NetteDI/OrmExtension.php index 86b24be2..84600c2d 100644 --- a/src/Bridges/NetteDI/OrmExtension.php +++ b/src/Bridges/NetteDI/OrmExtension.php @@ -140,7 +140,7 @@ protected function setupMetadataParserFactory(): void /** - * @param array, class-string<\Nextras\Orm\Repository\IRepository>> $entityClassMap + * @param array, class-string<\Nextras\Orm\Repository\IRepository<\Nextras\Orm\Entity\IEntity>>> $entityClassMap */ protected function setupMetadataStorage(array $entityClassMap): void { @@ -162,9 +162,9 @@ protected function setupMetadataStorage(array $entityClassMap): void /** * @phpstan-param array{ - * array, true>, - * array>, - * array, class-string<\Nextras\Orm\Repository\IRepository>> + * array>, true>, + * array>>, + * array, class-string<\Nextras\Orm\Repository\IRepository<\Nextras\Orm\Entity\IEntity>>> * } $repositoriesConfig */ protected function setupModel(string $modelClass, array $repositoriesConfig): void diff --git a/src/Bridges/NetteDI/PhpDocRepositoryFinder.php b/src/Bridges/NetteDI/PhpDocRepositoryFinder.php index a3f18524..01de2003 100644 --- a/src/Bridges/NetteDI/PhpDocRepositoryFinder.php +++ b/src/Bridges/NetteDI/PhpDocRepositoryFinder.php @@ -39,6 +39,7 @@ public function loadConfiguration(): ?array { $repositories = $this->findRepositories($this->modelClass); $repositoriesMap = []; + foreach ($repositories as $repositoryName => $repositoryClass) { $this->setupMapperService($repositoryName, $repositoryClass); $this->setupRepositoryService($repositoryName, $repositoryClass); @@ -59,7 +60,7 @@ public function beforeCompile(): ?array /** * @return array * @phpstan-param class-string<\Nextras\Orm\Model\IModel> $modelClass - * @phpstan-return array> + * @phpstan-return array>> */ protected function findRepositories(string $modelClass): array { @@ -83,7 +84,7 @@ protected function findRepositories(string $modelClass): array * @var string $name */ foreach ($matches as [, $type, $name]) { - /** @phpstan-var class-string $type */ + /** @phpstan-var class-string> $type */ $type = Reflection::expandClassName($type, $modelReflection); if (!class_exists($type)) { throw new RuntimeException("Repository '{$type}' does not exist."); @@ -140,7 +141,7 @@ protected function setupRepositoryService(string $repositoryName, string $reposi /** - * @param array, string> $repositoriesMap + * @param array>, string> $repositoriesMap */ protected function setupRepositoryLoader(array $repositoriesMap): void { diff --git a/src/Bridges/NetteDI/RepositoryLoader.php b/src/Bridges/NetteDI/RepositoryLoader.php index d0da58f8..ea38e38d 100644 --- a/src/Bridges/NetteDI/RepositoryLoader.php +++ b/src/Bridges/NetteDI/RepositoryLoader.php @@ -4,6 +4,7 @@ use Nette\DI\Container; +use Nextras\Orm\Entity\IEntity; use Nextras\Orm\Model\IRepositoryLoader; use Nextras\Orm\Repository\IRepository; @@ -13,12 +14,12 @@ class RepositoryLoader implements IRepositoryLoader /** @var Container */ private $container; - /** @var array, string> */ + /** @var array>, string> */ private $repositoryNamesMap; /** - * @param array, string> $repositoryNamesMap + * @param array>, string> $repositoryNamesMap */ public function __construct(Container $container, array $repositoryNamesMap) { @@ -33,11 +34,16 @@ public function hasRepository(string $className): bool } + /** + * Returns instance of repository. + * @phpstan-template R of IRepository<\Nextras\Orm\Entity\IEntity> + * @phpstan-param class-string $className + * @phpstan-return R + */ public function getRepository(string $className): IRepository { - $repository = $this->container->getService($this->repositoryNamesMap[$className]); - assert($repository instanceof IRepository); - return $repository; + /** @phpstan-var R */ + return $this->container->getService($this->repositoryNamesMap[$className]); } diff --git a/src/Collection/ArrayCollection.php b/src/Collection/ArrayCollection.php index b1d30b52..3832fba4 100644 --- a/src/Collection/ArrayCollection.php +++ b/src/Collection/ArrayCollection.php @@ -18,6 +18,10 @@ use function array_values; +/** + * @phpstan-template E of IEntity + * @phpstan-implements ICollection + */ class ArrayCollection implements ICollection { /** @@ -28,7 +32,7 @@ class ArrayCollection implements ICollection /** * @var IEntity[] - * @phpstan-var list + * @phpstan-var list */ protected $data; @@ -38,10 +42,16 @@ class ArrayCollection implements ICollection /** @var IEntity|null */ protected $relationshipParent; - /** @var null|Iterator */ + /** + * @var Iterator|null + * @phpstan-var Iterator|null + */ protected $fetchIterator; - /** @var IRepository */ + /** + * @var IRepository + * @phpstan-var IRepository + */ protected $repository; /** @var ArrayCollectionHelper */ @@ -49,7 +59,7 @@ class ArrayCollection implements ICollection /** * @var Closure[] - * @phpstan-var list + * @phpstan-var list */ protected $collectionFilter = []; @@ -68,7 +78,8 @@ class ArrayCollection implements ICollection /** * @param IEntity[] $entities - * @phpstan-param list $entities + * @phpstan-param IRepository $repository + * @phpstan-param list $entities */ public function __construct(array $entities, IRepository $repository) { @@ -192,6 +203,9 @@ public function __call(string $name, array $args) } + /** + * @phpstan-return Iterator + */ public function getIterator(): Iterator { if ($this->relationshipParent !== null && $this->relationshipMapper !== null) { @@ -212,6 +226,7 @@ public function getIterator(): Iterator $this->entityFetchEventTriggered = true; } + /** @phpstan-var Iterator */ return $entityIterator; } diff --git a/src/Collection/DbalCollection.php b/src/Collection/DbalCollection.php index 02c58c45..56828867 100644 --- a/src/Collection/DbalCollection.php +++ b/src/Collection/DbalCollection.php @@ -17,6 +17,10 @@ use function is_array; +/** + * @phpstan-template E of IEntity + * @phpstan-implements ICollection + */ class DbalCollection implements ICollection { /** @@ -31,10 +35,16 @@ class DbalCollection implements ICollection /** @var IEntity|null */ protected $relationshipParent; - /** @var null|Iterator */ + /** + * @var Iterator|null + * @phpstan-var Iterator|null + */ protected $fetchIterator; - /** @var DbalMapper */ + /** + * @var DbalMapper + * @phpstan-var DbalMapper + */ protected $mapper; /** @var IConnection */ @@ -47,8 +57,8 @@ class DbalCollection implements ICollection protected $helper; /** - * @var array|null - * @phpstan-var list|null + * @var IEntity[]|null + * @phpstan-var list|null */ protected $result; @@ -59,6 +69,9 @@ class DbalCollection implements ICollection protected $entityFetchEventTriggered = false; + /** + * @phpstan-param DbalMapper $mapper + */ public function __construct(DbalMapper $mapper, IConnection $connection, QueryBuilder $queryBuilder) { $this->mapper = $mapper; @@ -153,6 +166,10 @@ public function limitBy(int $limit, int $offset = null): ICollection } + /** + * @inheritDoc + * @phpstan-return E|null + */ public function fetch(): ?IEntity { if ($this->fetchIterator === null) { @@ -193,6 +210,9 @@ public function __call(string $name, array $args) } + /** + * @phpstan-return Iterator + */ public function getIterator(): Iterator { if ($this->relationshipParent !== null && $this->relationshipMapper !== null) { @@ -214,6 +234,7 @@ public function getIterator(): Iterator $this->entityFetchEventTriggered = true; } + /** @phpstan-var Iterator */ return $entityIterator; } diff --git a/src/Collection/EmptyCollection.php b/src/Collection/EmptyCollection.php index c3da892f..fb162c6c 100644 --- a/src/Collection/EmptyCollection.php +++ b/src/Collection/EmptyCollection.php @@ -10,7 +10,11 @@ use Nextras\Orm\Mapper\IRelationshipMapper; -class EmptyCollection implements ICollection +/** + * @phpstan-template E of IEntity + * @phpstan-implements ICollection + */ +final class EmptyCollection implements ICollection { /** @var IRelationshipMapper|null */ private $relationshipMapper; @@ -82,6 +86,9 @@ public function fetchPairs(string $key = null, string $value = null): array } + /** + * @phpstan-return Iterator + */ public function getIterator(): Iterator { return new EmptyIterator(); diff --git a/src/Collection/HasManyCollection.php b/src/Collection/HasManyCollection.php index 0b54636a..7737e31c 100644 --- a/src/Collection/HasManyCollection.php +++ b/src/Collection/HasManyCollection.php @@ -18,23 +18,33 @@ use function spl_object_hash; +/** + * @phpstan-template E of IEntity + * @phpstan-implements ICollection + */ class HasManyCollection implements ICollection { /** * @var array of callbacks with $entities argument - * @phpstan-var array):void> + * @phpstan-var array):void> */ public $onEntityFetch = []; - /** @var ICollection */ + /** + * @var ICollection + * @phpstan-var ICollection + */ private $storageCollection; - /** @var MutableArrayCollection */ + /** + * @var MutableArrayCollection + * @phpstan-var MutableArrayCollection + */ private $inMemoryCollection; /** * @var callable A callback returning a list entities to add & remove. - * @phpstan-var callable(): array{array, array} + * @phpstan-var callable(): array{array, array} */ private $diffCallback; @@ -43,7 +53,9 @@ class HasManyCollection implements ICollection /** - * @phpstan-param callable():array{array, array} $diffCallback + * @phpstan-param IRepository $repository + * @phpstan-param ICollection $innerCollection + * @phpstan-param callable():array{array, array} $diffCallback */ public function __construct( IRepository $repository, @@ -53,7 +65,7 @@ public function __construct( { $this->storageCollection = $innerCollection; $this->diffCallback = $diffCallback; - $this->inMemoryCollection = new MutableArrayCollection([], $repository); + $this->inMemoryCollection = new MutableArrayCollection([], $repository); // @phpstan-ignore-line } @@ -152,6 +164,9 @@ public function fetchPairs(string $key = null, string $value = null): array } + /** + * @phpstan-return Iterator + */ public function getIterator(): Iterator { [$toAdd, $toRemove] = ($this->diffCallback)(); diff --git a/src/Collection/Helpers/ArrayCollectionHelper.php b/src/Collection/Helpers/ArrayCollectionHelper.php index b04cf956..8a8ba76b 100644 --- a/src/Collection/Helpers/ArrayCollectionHelper.php +++ b/src/Collection/Helpers/ArrayCollectionHelper.php @@ -27,10 +27,13 @@ class ArrayCollectionHelper { - /** @var IRepository */ + /** @var IRepository */ private $repository; + /** + * @param IRepository $repository + */ public function __construct(IRepository $repository) { $this->repository = $repository; diff --git a/src/Collection/Helpers/DbalQueryBuilderHelper.php b/src/Collection/Helpers/DbalQueryBuilderHelper.php index 041d03d5..80ccaee7 100644 --- a/src/Collection/Helpers/DbalQueryBuilderHelper.php +++ b/src/Collection/Helpers/DbalQueryBuilderHelper.php @@ -9,6 +9,7 @@ use Nextras\Orm\Collection\Functions\IQueryBuilderFunction; use Nextras\Orm\Collection\ICollection; use Nextras\Orm\Entity\Embeddable\EmbeddableContainer; +use Nextras\Orm\Entity\IEntity; use Nextras\Orm\Entity\Reflection\EntityMetadata; use Nextras\Orm\Entity\Reflection\PropertyMetadata; use Nextras\Orm\Entity\Reflection\PropertyRelationshipMetadata as Relationship; @@ -39,10 +40,10 @@ class DbalQueryBuilderHelper /** @var IModel */ private $model; - /** @var IRepository */ + /** @var IRepository */ private $repository; - /** @var DbalMapper */ + /** @var DbalMapper */ private $mapper; /** @var string */ @@ -67,6 +68,10 @@ public static function getAlias(string $name, array $tokens = []): string } + /** + * @param IRepository $repository + * @param DbalMapper $mapper + */ public function __construct(IModel $model, IRepository $repository, DbalMapper $mapper) { $this->model = $model; @@ -97,7 +102,7 @@ public function processPropertyExpr(QueryBuilder $builder, $expr): DbalExpressio */ public function processFilterFunction(QueryBuilder $builder, array $expr): DbalExpressionResult { - $function = isset($expr[0]) ? array_shift($expr) : ICollection::AND; + $function = isset($expr[0]) ? array_shift($expr) : ICollection:: AND; $collectionFunction = $this->getCollectionFunction($function); return $collectionFunction->processQueryBuilderExpression($this, $builder, $expr); } @@ -280,9 +285,9 @@ function ($value) use ($propertyMetadata, $currentConventions) { /** * @param array $tokens + * @param DbalMapper $currentMapper * @param mixed $token - * @param int $tokenIndex - * @return array{string, IConventions, EntityMetadata, DbalMapper} + * @return array{string, IConventions, EntityMetadata, DbalMapper} */ private function processRelationship( array $tokens, @@ -389,6 +394,9 @@ private function toColumnExpr( } + /** + * @param DbalMapper $mapper + */ private function makeDistinct(QueryBuilder $builder, DbalMapper $mapper): void { $baseTable = $builder->getFromAlias(); diff --git a/src/Collection/ICollection.php b/src/Collection/ICollection.php index 6f56165b..16238adb 100644 --- a/src/Collection/ICollection.php +++ b/src/Collection/ICollection.php @@ -14,7 +14,8 @@ /** - * @extends IteratorAggregate + * @phpstan-template E of IEntity + * @extends IteratorAggregate */ interface ICollection extends IteratorAggregate, Countable { @@ -43,6 +44,7 @@ interface ICollection extends IteratorAggregate, Countable * Limits collection via {@see ICollection::findBy()} and returns the first entity (or null). * * @phpstan-param array|array $conds + * @phpstan-return E|null */ public function getBy(array $conds): ?IEntity; @@ -54,6 +56,7 @@ public function getBy(array $conds): ?IEntity; * * @phpstan-param array|array $conds * @throws NoResultException + * @phpstan-return E */ public function getByChecked(array $conds): IEntity; @@ -61,6 +64,7 @@ public function getByChecked(array $conds): IEntity; /** * Returns entity by primary value, null if none found. * @param mixed $id + * @phpstan-return E|null */ public function getById($id): ?IEntity; @@ -69,6 +73,7 @@ public function getById($id): ?IEntity; * Returns entity by primary value, throws if none found. * @param mixed $id * @throws NoResultException + * @phpstan-return E */ public function getByIdChecked($id): IEntity; @@ -159,6 +164,7 @@ public function limitBy(int $limit, int $offset = null): ICollection; /** * Fetches the first row. + * @phpstan-return E|null */ public function fetch(): ?IEntity; @@ -166,6 +172,7 @@ public function fetch(): ?IEntity; /** * Fetches all records. * @return IEntity[] + * @phpstan-return list */ public function fetchAll(); @@ -181,6 +188,7 @@ public function fetchPairs(?string $key = null, ?string $value = null): array; /** * @return Iterator + * @phpstan-return Iterator */ public function getIterator(); @@ -213,7 +221,7 @@ public function countStored(): int; /** - * @phpstan-param callable(\Traversable):void $callback + * @phpstan-param callable(\Traversable):void $callback */ public function subscribeOnEntityFetch(callable $callback): void; } diff --git a/src/Collection/MutableArrayCollection.php b/src/Collection/MutableArrayCollection.php index a06ba6fd..df93ca5c 100644 --- a/src/Collection/MutableArrayCollection.php +++ b/src/Collection/MutableArrayCollection.php @@ -5,11 +5,13 @@ /** * @internal + * @phpstan-template E of \Nextras\Orm\Entity\IEntity + * @phpstan-extends ArrayCollection */ class MutableArrayCollection extends ArrayCollection { /** - * @phpstan-param list<\Nextras\Orm\Entity\IEntity> $data + * @phpstan-param list $data * @return static */ public function withData(array $data): ICollection diff --git a/src/Entity/AbstractEntity.php b/src/Entity/AbstractEntity.php index 4bd14881..014bfd15 100644 --- a/src/Entity/AbstractEntity.php +++ b/src/Entity/AbstractEntity.php @@ -22,7 +22,7 @@ abstract class AbstractEntity implements IEntity use ImmutableDataTrait; - /** @var IRepository|null */ + /** @var IRepository|null */ private $repository; /** @var array */ @@ -506,6 +506,9 @@ private function createPropertyWrapper(PropertyMetadata $metadata): IProperty } + /** + * @param IRepository $repository + */ private function attach(IRepository $repository): void { if ($this->repository !== null && $this->repository !== $repository) { diff --git a/src/Entity/IEntity.php b/src/Entity/IEntity.php index 6930380c..e9b66b01 100644 --- a/src/Entity/IEntity.php +++ b/src/Entity/IEntity.php @@ -9,6 +9,9 @@ interface IEntity { + /** + * @return IRepository + */ public function getRepository(): IRepository; @@ -143,7 +146,10 @@ public function onRefresh(?array $data, bool $isPartial = false): void; public function onFree(): void; - /** @internal */ + /** + * @param IRepository $repository + * @internal + */ public function onAttach(IRepository $repository, EntityMetadata $metadata): void; diff --git a/src/Entity/Reflection/IMetadataParserFactory.php b/src/Entity/Reflection/IMetadataParserFactory.php index 61338292..0e202404 100644 --- a/src/Entity/Reflection/IMetadataParserFactory.php +++ b/src/Entity/Reflection/IMetadataParserFactory.php @@ -8,7 +8,7 @@ interface IMetadataParserFactory /** * Creates metadata parser. * @param array $entityClassesMap - * @phpstan-param array, class-string<\Nextras\Orm\Repository\IRepository>> $entityClassesMap + * @phpstan-param array, class-string<\Nextras\Orm\Repository\IRepository<\Nextras\Orm\Entity\IEntity>>> $entityClassesMap */ public function create(array $entityClassesMap): IMetadataParser; } diff --git a/src/Entity/Reflection/MetadataParser.php b/src/Entity/Reflection/MetadataParser.php index 8b6fe3a9..eb4a8471 100644 --- a/src/Entity/Reflection/MetadataParser.php +++ b/src/Entity/Reflection/MetadataParser.php @@ -67,7 +67,7 @@ class MetadataParser implements IMetadataParser /** * @var array - * @phpstan-var array, class-string<\Nextras\Orm\Repository\IRepository>> + * @phpstan-var array, class-string<\Nextras\Orm\Repository\IRepository<\Nextras\Orm\Entity\IEntity>>> */ protected $entityClassesMap; @@ -83,7 +83,7 @@ class MetadataParser implements IMetadataParser /** * @param array $entityClassesMap - * @phpstan-param array, class-string<\Nextras\Orm\Repository\IRepository>> $entityClassesMap + * @phpstan-param array, class-string<\Nextras\Orm\Repository\IRepository<\Nextras\Orm\Entity\IEntity>>> $entityClassesMap */ public function __construct(array $entityClassesMap) { @@ -527,11 +527,11 @@ protected function processRelationshipEntityProperty(PropertyMetadata $property, } } + /** @var class-string<\Nextras\Orm\Entity\IEntity> $entity */ $entity = Reflection::expandClassName($class, $this->currentReflection); if (!isset($this->entityClassesMap[$entity])) { throw new InvalidModifierDefinitionException("Relationship {{$modifier}} in {$this->currentReflection->name}::\${$property->name} points to unknown '{$entity}' entity. Don't forget to return it in IRepository::getEntityClassNames() and register its repository."); } - assert(is_subclass_of($entity, IEntity::class)); $property->relationship->entity = $entity; $property->relationship->repository = $this->entityClassesMap[$entity]; diff --git a/src/Entity/Reflection/MetadataParserFactory.php b/src/Entity/Reflection/MetadataParserFactory.php index a47e3e88..c31fee5f 100644 --- a/src/Entity/Reflection/MetadataParserFactory.php +++ b/src/Entity/Reflection/MetadataParserFactory.php @@ -5,9 +5,7 @@ class MetadataParserFactory implements IMetadataParserFactory { - /** - * @inheritDoc - */ + /** @inheritDoc */ public function create(array $entityClassesMap): IMetadataParser { return new MetadataParser($entityClassesMap); diff --git a/src/Entity/Reflection/PropertyRelationshipMetadata.php b/src/Entity/Reflection/PropertyRelationshipMetadata.php index 801f136b..753b5880 100644 --- a/src/Entity/Reflection/PropertyRelationshipMetadata.php +++ b/src/Entity/Reflection/PropertyRelationshipMetadata.php @@ -12,11 +12,14 @@ class PropertyRelationshipMetadata /** * @var string - * @phpstan-var class-string<\Nextras\Orm\Repository\IRepository> + * @phpstan-var class-string<\Nextras\Orm\Repository\IRepository<\Nextras\Orm\Entity\IEntity>> */ public $repository; - /** @var class-string<\Nextras\Orm\Entity\IEntity> */ + /** + * @var string + * @phpstan-var class-string<\Nextras\Orm\Entity\IEntity> + */ public $entity; /** @var EntityMetadata */ diff --git a/src/Mapper/Dbal/DbalMapper.php b/src/Mapper/Dbal/DbalMapper.php index e6c446d9..fac2df56 100644 --- a/src/Mapper/Dbal/DbalMapper.php +++ b/src/Mapper/Dbal/DbalMapper.php @@ -18,21 +18,23 @@ use Nextras\Orm\Entity\Reflection\PropertyMetadata; use Nextras\Orm\Entity\Reflection\PropertyRelationshipMetadata as Relationship; use Nextras\Orm\Exception\InvalidArgumentException; +use Nextras\Orm\Exception\InvalidStateException; use Nextras\Orm\Exception\NotSupportedException; use Nextras\Orm\Mapper\Dbal\Conventions\IConventions; use Nextras\Orm\Mapper\Dbal\Conventions\Inflector\IInflector; use Nextras\Orm\Mapper\Dbal\Conventions\Inflector\SnakeCaseInflector; use Nextras\Orm\Mapper\IMapper; use Nextras\Orm\Mapper\IRelationshipMapper; -use Nextras\Orm\Mapper\MapperRepositoryTrait; +use Nextras\Orm\Repository\IRepository; use Nextras\Orm\StorageReflection\StringHelper; -class DbalMapper implements IMapper +/** + * @phpstan-template E of IEntity + * @phpstan-implements IMapper + */ +abstract class DbalMapper implements IMapper { - use MapperRepositoryTrait; - - /** @var IConnection */ protected $connection; @@ -42,6 +44,9 @@ class DbalMapper implements IMapper /** @var Cache */ protected $cache; + /** @var IRepository|null */ + private $repository; + /** * @var IRelationshipMapper[] * @phpstan-var array @@ -64,6 +69,28 @@ public function __construct(IConnection $connection, DbalMapperCoordinator $mapp } + public function setRepository(IRepository $repository): void + { + if ($this->repository !== null && $this->repository !== $repository) { + $name = get_class($this); + throw new InvalidStateException("Mapper '$name' is already attached to repository."); + } + + $this->repository = $repository; + } + + + public function getRepository(): IRepository + { + if ($this->repository === null) { + $name = get_class($this); + throw new InvalidStateException("Mapper '$name' is not attached to repository."); + } + + return $this->repository; + } + + /** {@inheritdoc} */ public function findAll(): ICollection { @@ -105,6 +132,7 @@ public function getTableName(): string * Transforms value from mapper, which is not a collection. * @param QueryBuilder|array|Result $data * @phpstan-param QueryBuilder|list>|Result $data + * @return ICollection */ public function toCollection($data): ICollection { @@ -180,6 +208,7 @@ public function clearCache(): void /** + * @param DbalMapper $targetMapper * @phpstan-return array{string,array{string,string}} */ public function getManyHasManyParameters(PropertyMetadata $sourceProperty, DbalMapper $targetMapper): array @@ -228,6 +257,9 @@ public function createCollectionOneHasMany(PropertyMetadata $metadata): ICollect } + /** + * @param IMapper|null $sourceMapper + */ protected function getRelationshipMapper( int $type, PropertyMetadata $metadata, @@ -242,6 +274,9 @@ protected function getRelationshipMapper( } + /** + * @param IMapper|null $sourceMapper + */ protected function createRelationshipMapper( int $type, PropertyMetadata $metadata, diff --git a/src/Mapper/Dbal/RelationshipMapperManyHasMany.php b/src/Mapper/Dbal/RelationshipMapperManyHasMany.php index a0e5f528..9eb9f19b 100644 --- a/src/Mapper/Dbal/RelationshipMapperManyHasMany.php +++ b/src/Mapper/Dbal/RelationshipMapperManyHasMany.php @@ -41,7 +41,7 @@ class RelationshipMapperManyHasMany implements IRelationshipMapperManyHasMany /** @var string */ protected $primaryKeyTo; - /** @var DbalMapper */ + /** @var DbalMapper */ protected $targetMapper; /** @@ -60,6 +60,10 @@ class RelationshipMapperManyHasMany implements IRelationshipMapperManyHasMany private $mapperCoordinator; + /** + * @param DbalMapper $mapper + * @param DbalMapper $sourceMapper + */ public function __construct( IConnection $connection, DbalMapper $mapper, @@ -108,6 +112,9 @@ public function getIterator(IEntity $parent, ICollection $collection): Iterator } + /** + * @param DbalCollection $collection + */ protected function execute(DbalCollection $collection, IEntity $parent): MultiEntityIterator { $preloadIterator = $parent instanceof IEntityHasPreloadContainer ? $parent->getPreloadContainer() : null; @@ -179,6 +186,10 @@ private function fetchByTwoPassStrategy(QueryBuilder $builder, array $values): M // ==== ITERATOR COUNT ============================================================================================= + + /** + * @param ICollection $collection + */ public function getIteratorCount(IEntity $parent, ICollection $collection): int { assert($collection instanceof DbalCollection); @@ -189,6 +200,7 @@ public function getIteratorCount(IEntity $parent, ICollection $collection): int /** + * @param DbalCollection $collection * @phpstan-return array */ protected function executeCounts(DbalCollection $collection, IEntity $parent): array diff --git a/src/Mapper/Dbal/RelationshipMapperManyHasOne.php b/src/Mapper/Dbal/RelationshipMapperManyHasOne.php index fc52443a..76a976f8 100644 --- a/src/Mapper/Dbal/RelationshipMapperManyHasOne.php +++ b/src/Mapper/Dbal/RelationshipMapperManyHasOne.php @@ -31,10 +31,13 @@ class RelationshipMapperManyHasOne implements IRelationshipMapper */ protected $cacheEntityIterators; - /** @var DbalMapper */ + /** @var DbalMapper */ private $targetMapper; + /** + * @param DbalMapper $targetMapper + */ public function __construct(IConnection $connection, DbalMapper $targetMapper, PropertyMetadata $metadata) { $this->connection = $connection; @@ -63,6 +66,9 @@ public function clearCache(): void } + /** + * @param DbalCollection $collection + */ protected function execute(DbalCollection $collection, IEntity $parent): MultiEntityIterator { $preloadContainer = $parent instanceof IEntityHasPreloadContainer ? $parent->getPreloadContainer() : null; diff --git a/src/Mapper/Dbal/RelationshipMapperOneHasMany.php b/src/Mapper/Dbal/RelationshipMapperOneHasMany.php index eb6be620..88111512 100644 --- a/src/Mapper/Dbal/RelationshipMapperOneHasMany.php +++ b/src/Mapper/Dbal/RelationshipMapperOneHasMany.php @@ -35,7 +35,7 @@ class RelationshipMapperOneHasMany implements IRelationshipMapper /** @var PropertyRelationshipMetadata */ protected $metadataRelationship; - /** @var DbalMapper */ + /** @var DbalMapper */ protected $targetMapper; /** @var string */ @@ -54,6 +54,9 @@ class RelationshipMapperOneHasMany implements IRelationshipMapper protected $cacheCounts; + /** + * @param DbalMapper $targetMapper + */ public function __construct(IConnection $connection, DbalMapper $targetMapper, PropertyMetadata $metadata) { assert($metadata->relationship !== null); @@ -76,6 +79,10 @@ public function clearCache(): void // ==== ITERATOR =================================================================================================== + + /** + * @param ICollection $collection + */ public function getIterator(IEntity $parent, ICollection $collection): Iterator { assert($collection instanceof DbalCollection); @@ -85,6 +92,9 @@ public function getIterator(IEntity $parent, ICollection $collection): Iterator } + /** + * @param DbalCollection $collection + */ protected function execute(DbalCollection $collection, IEntity $parent): MultiEntityIterator { $preloadContainer = $parent instanceof IEntityHasPreloadContainer ? $parent->getPreloadContainer() : null; @@ -213,6 +223,7 @@ public function getIteratorCount(IEntity $parent, ICollection $collection): int /** + * @param DbalCollection $collection * @phpstan-return array */ protected function executeCounts(DbalCollection $collection, IEntity $parent): array diff --git a/src/Mapper/IMapper.php b/src/Mapper/IMapper.php index 67fb3e57..380a5d29 100644 --- a/src/Mapper/IMapper.php +++ b/src/Mapper/IMapper.php @@ -9,45 +9,62 @@ use Nextras\Orm\Repository\IRepository; +/** + * @phpstan-template E of IEntity + */ interface IMapper { /** * Returns all entities. + * @phpstan-return ICollection */ public function findAll(): ICollection; /** * Creates collection with HasOne mapper. + * @phpstan-return ICollection */ public function createCollectionManyHasOne(PropertyMetadata $metadata): ICollection; /** * Creates collection with OneHasOneDirected mapper. + * @phpstan-return ICollection */ public function createCollectionOneHasOne(PropertyMetadata $metadata): ICollection; /** * Creates collection with ManyHasMany mapper. + * @phpstan-param IMapper $sourceMapper + * @phpstan-return ICollection */ public function createCollectionManyHasMany(IMapper $sourceMapper, PropertyMetadata $metadata): ICollection; /** * Creates collection with OneHasMany mapper. + * @phpstan-return ICollection */ public function createCollectionOneHasMany(PropertyMetadata $metadata): ICollection; + /** + * @phpstan-param IRepository $repository + */ public function setRepository(IRepository $repository): void; + /** + * @phpstan-return IRepository + */ public function getRepository(): IRepository; /** + * Persist entity and return new id. + * @phpstan-param E $entity * @internal * @see IRepository::persist() */ @@ -55,6 +72,7 @@ public function persist(IEntity $entity): void; /** + * @phpstan-param E $entity * @see IRepository::remove() */ public function remove(IEntity $entity): void; diff --git a/src/Mapper/IRelationshipMapper.php b/src/Mapper/IRelationshipMapper.php index bc35cf43..72251861 100644 --- a/src/Mapper/IRelationshipMapper.php +++ b/src/Mapper/IRelationshipMapper.php @@ -12,13 +12,15 @@ interface IRelationshipMapper { /** * Returns iterator. - * @return Iterator + * @phpstan-param ICollection $collection + * @return Iterator */ public function getIterator(IEntity $parent, ICollection $collection): Iterator; /** * Returns iterator's counts. + * @phpstan-param ICollection $collection */ public function getIteratorCount(IEntity $parent, ICollection $collection): int; diff --git a/src/Mapper/Mapper.php b/src/Mapper/Mapper.php index a26c32a2..d2172075 100644 --- a/src/Mapper/Mapper.php +++ b/src/Mapper/Mapper.php @@ -7,7 +7,9 @@ /** - * Default mapper. + * @phpstan-template E of \Nextras\Orm\Entity\IEntity + * @phpstan-extends DbalMapper + * @deprecated Use {@see DbalMapper} directly. */ abstract class Mapper extends DbalMapper { diff --git a/src/Mapper/MapperRepositoryTrait.php b/src/Mapper/MapperRepositoryTrait.php deleted file mode 100644 index 1525d0f0..00000000 --- a/src/Mapper/MapperRepositoryTrait.php +++ /dev/null @@ -1,36 +0,0 @@ -repository !== null && $this->repository !== $repository) { - $name = get_class($this); - throw new InvalidStateException("Mapper '$name' is already attached to repository."); - } - - $this->repository = $repository; - } - - - public function getRepository(): IRepository - { - if ($this->repository === null) { - $name = get_class($this); - throw new InvalidStateException("Mapper '$name' is not attached to repository."); - } - - return $this->repository; - } -} diff --git a/src/Mapper/Memory/ArrayMapper.php b/src/Mapper/Memory/ArrayMapper.php index 2efdf30e..472b993a 100644 --- a/src/Mapper/Memory/ArrayMapper.php +++ b/src/Mapper/Memory/ArrayMapper.php @@ -12,21 +12,22 @@ use Nextras\Orm\Exception\IOException; use Nextras\Orm\Exception\LogicException; use Nextras\Orm\Mapper\IMapper; -use Nextras\Orm\Mapper\MapperRepositoryTrait; use Nextras\Orm\Mapper\Memory\Conventions\Conventions; use Nextras\Orm\Mapper\Memory\Conventions\IConventions; +use Nextras\Orm\Repository\IRepository; use function array_values; use function assert; +/** + * @phpstan-template E of IEntity + * @phpstan-implements IMapper + */ abstract class ArrayMapper implements IMapper { - use MapperRepositoryTrait; - - /** * @var IEntity[]|null[]|null - * @phpstan-var array|null + * @phpstan-var array|null */ protected $data; @@ -45,10 +46,35 @@ abstract class ArrayMapper implements IMapper /** @var IConventions */ protected $conventions; + /** @var IRepository|null */ + private $repository; + /** @var resource|null */ static protected $lock; + public function setRepository(IRepository $repository): void + { + if ($this->repository !== null && $this->repository !== $repository) { + $name = get_class($this); + throw new InvalidStateException("Mapper '$name' is already attached to repository."); + } + + $this->repository = $repository; + } + + + public function getRepository(): IRepository + { + if ($this->repository === null) { + $name = get_class($this); + throw new InvalidStateException("Mapper '$name' is not attached to repository."); + } + /** @phpstan-var IRepository */ + return $this->repository; + } + + public function findAll(): ICollection { return new ArrayCollection($this->getData(), $this->getRepository()); @@ -56,7 +82,8 @@ public function findAll(): ICollection /** - * @phpstan-param list $data + * @phpstan-param list $data + * @phpstan-return ICollection */ public function toCollection(array $data): ICollection { @@ -227,7 +254,7 @@ protected function initializeData(): void /** - * @phpstan-return list + * @phpstan-return list */ protected function getData(): array { diff --git a/src/Mapper/Memory/RelationshipMapperManyHasMany.php b/src/Mapper/Memory/RelationshipMapperManyHasMany.php index 82215dfe..1aea1931 100644 --- a/src/Mapper/Memory/RelationshipMapperManyHasMany.php +++ b/src/Mapper/Memory/RelationshipMapperManyHasMany.php @@ -3,6 +3,7 @@ namespace Nextras\Orm\Mapper\Memory; +use Countable; use Iterator; use Nextras\Orm\Collection\EntityIterator; use Nextras\Orm\Collection\ICollection; @@ -14,13 +15,17 @@ class RelationshipMapperManyHasMany implements IRelationshipMapperManyHasMany { - /** @var ArrayMapper */ + /** @var ArrayMapper */ protected $mapper; /** @var PropertyMetadata */ protected $metadata; + /** + * @param ArrayMapper $mapper + * @param ArrayMapper $sourceMapper + */ public function __construct(ArrayMapper $mapper, ArrayMapper $sourceMapper, PropertyMetadata $metadata) { assert($metadata->relationship !== null); @@ -38,9 +43,6 @@ public function clearCache(): void } - /** - * @return EntityIterator - */ public function getIterator(IEntity $parent, ICollection $collection): Iterator { assert($this->metadata->relationship !== null); @@ -67,7 +69,9 @@ public function getIterator(IEntity $parent, ICollection $collection): Iterator public function getIteratorCount(IEntity $parent, ICollection $collection): int { - return count($this->getIterator($parent, $collection)); + $iterator = $this->getIterator($parent, $collection); + assert($iterator instanceof Countable); + return count($iterator); } diff --git a/src/Mapper/Memory/RelationshipMapperOneHasMany.php b/src/Mapper/Memory/RelationshipMapperOneHasMany.php index 8d727f6c..e220a38d 100644 --- a/src/Mapper/Memory/RelationshipMapperOneHasMany.php +++ b/src/Mapper/Memory/RelationshipMapperOneHasMany.php @@ -21,6 +21,9 @@ class RelationshipMapperOneHasMany implements IRelationshipMapper protected $joinStorageKey; + /** + * @param ArrayMapper $targetMapper + */ public function __construct(ArrayMapper $targetMapper, PropertyMetadata $metadata) { assert($metadata->relationship !== null); diff --git a/src/Model/IModel.php b/src/Model/IModel.php index e79fa309..8468065c 100644 --- a/src/Model/IModel.php +++ b/src/Model/IModel.php @@ -17,12 +17,15 @@ public function hasRepositoryByName(string $name): bool; /** * Returns repository by repository name. + * @phpstan-return IRepository */ public function getRepositoryByName(string $name): IRepository; /** * Returns true if repository class is attached to model. + * @phpstan-template T of IRepository + * @phpstan-param class-string $className */ public function hasRepository(string $className): bool; @@ -39,7 +42,9 @@ public function getRepository(string $className): IRepository; /** * Returns repository associated for entity type. * @param IEntity|string $entity - * @phpstan-param IEntity|class-string $entity + * @phpstan-template E of IEntity + * @phpstan-param E|class-string $entity + * @phpstan-return IRepository */ public function getRepositoryForEntity($entity): IRepository; diff --git a/src/Model/IRepositoryLoader.php b/src/Model/IRepositoryLoader.php index a4798d33..91924025 100644 --- a/src/Model/IRepositoryLoader.php +++ b/src/Model/IRepositoryLoader.php @@ -10,18 +10,24 @@ interface IRepositoryLoader { /** * Returns true if repository exists. + * @phpstan-param class-string> $className */ public function hasRepository(string $className): bool; /** * Returns instance of repository. + * @phpstan-template T of IRepository<\Nextras\Orm\Entity\IEntity> + * @phpstan-param class-string $className + * @phpstan-return T */ public function getRepository(string $className): IRepository; /** * Checks, if repository has been already created. + * @phpstan-template T of IRepository<\Nextras\Orm\Entity\IEntity> + * @phpstan-param class-string $className */ public function isCreated(string $className): bool; } diff --git a/src/Model/MetadataStorage.php b/src/Model/MetadataStorage.php index c5031593..47105673 100644 --- a/src/Model/MetadataStorage.php +++ b/src/Model/MetadataStorage.php @@ -36,7 +36,7 @@ public static function get(string $className): EntityMetadata /** * @param array $entityClassesMap - * @phpstan-param array, class-string<\Nextras\Orm\Repository\IRepository>> $entityClassesMap + * @phpstan-param array, class-string<\Nextras\Orm\Repository\IRepository<\Nextras\Orm\Entity\IEntity>>> $entityClassesMap */ public function __construct( array $entityClassesMap, diff --git a/src/Model/Model.php b/src/Model/Model.php index ea939ca9..55fe4ea4 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -37,9 +37,9 @@ class Model implements IModel /** * @var array * @phpstan-var array{ - * array, true>, - * array>, - * array, class-string> + * array>, true>, + * array>>, + * array, class-string>> * } */ private $configuration; @@ -48,11 +48,11 @@ class Model implements IModel /** * Creates repository list configuration. * @param IRepository[]|string[] $repositories - * @phpstan-param array|IRepository> $repositories + * @phpstan-param array>|IRepository> $repositories * @phpstan-return array{ - * array, true>, - * array>, - * array, class-string> + * array>, true>, + * array>>, + * array, class-string>> * } */ public static function getConfiguration(array $repositories): array @@ -61,7 +61,7 @@ public static function getConfiguration(array $repositories): array foreach ($repositories as $name => $repository) { /** * @var string $className - * @phpstan-var class-string $className + * @phpstan-var class-string> $className */ $className = is_object($repository) ? get_class($repository) : $repository; $config[0][$className] = true; @@ -76,9 +76,9 @@ public static function getConfiguration(array $repositories): array /** * @phpstan-param array{ - * array, true>, - * array>, - * array, class-string> + * array>, true>, + * array>>, + * array, class-string>> * } $configuration */ public function __construct( @@ -125,18 +125,23 @@ public function getRepository(string $className): IRepository if (!isset($this->configuration[0][$className])) { throw new InvalidArgumentException("Repository '$className' does not exist."); } - /** @phpstan-var T $repository */ $repository = $this->loader->getRepository($className); return $repository; } + /** + * @phpstan-template E of IEntity + * @phpstan-param E|class-string $entity + * @phpstan-return IRepository + */ public function getRepositoryForEntity($entity): IRepository { $entityClassName = is_string($entity) ? $entity : get_class($entity); if (!isset($this->configuration[2][$entityClassName])) { throw new InvalidArgumentException("Repository for '$entityClassName' entity does not exist."); } + /** @var IRepository */ return $this->getRepository($this->configuration[2][$entityClassName]); } @@ -237,21 +242,22 @@ public function refreshAll(bool $allowOverwrite = false): void /** * Returns repository by name. - * @param string $name - * @return IRepository + * @phpstan-return IRepository<\Nextras\Orm\Entity\IEntity> */ - public function &__get($name) + public function &__get(string $name): IRepository { $repository = $this->getRepositoryByName($name); return $repository; } - /** @return IRepository[] */ + /** + * @return IRepository[] + * @phpstan-return list>> + */ private function getLoadedRepositories() { $repositories = []; - /** @var string $className */ foreach (array_keys($this->configuration[0]) as $className) { if ($this->loader->isCreated($className)) { $repositories[] = $this->loader->getRepository($className); diff --git a/src/Model/SimpleModelFactory.php b/src/Model/SimpleModelFactory.php index 201f6ff2..33261110 100644 --- a/src/Model/SimpleModelFactory.php +++ b/src/Model/SimpleModelFactory.php @@ -7,6 +7,7 @@ use Nextras\Orm\Entity\Reflection\IMetadataParserFactory; use Nextras\Orm\Entity\Reflection\MetadataParserFactory; use Nextras\Orm\Repository\IRepository; +use function array_values; class SimpleModelFactory @@ -16,7 +17,7 @@ class SimpleModelFactory /** * @var IRepository[] - * @phpstan-var array + * @phpstan-var array> */ private $repositories; @@ -26,7 +27,8 @@ class SimpleModelFactory /** * @param array $repositories - * @phpstan-param array $repositories + * @template E of \Nextras\Orm\Entity\IEntity + * @phpstan-param array> $repositories */ public function __construct(Cache $cache, array $repositories, IMetadataParserFactory $metadataParserFactory = null) { @@ -43,7 +45,7 @@ public function create() { $config = Model::getConfiguration($this->repositories); $parser = $this->metadataParserFactory ?? new MetadataParserFactory(); - $loader = new SimpleRepositoryLoader($this->repositories); + $loader = new SimpleRepositoryLoader(array_values($this->repositories)); $metadata = new MetadataStorage($config[2], $this->cache, $parser, $loader); $model = new Model($config, $loader, $metadata); diff --git a/src/Model/SimpleRepositoryLoader.php b/src/Model/SimpleRepositoryLoader.php index b5f775e1..8915ee16 100644 --- a/src/Model/SimpleRepositoryLoader.php +++ b/src/Model/SimpleRepositoryLoader.php @@ -3,18 +3,22 @@ namespace Nextras\Orm\Model; +use Nextras\Orm\Entity\IEntity; use Nextras\Orm\Exception\InvalidArgumentException; use Nextras\Orm\Repository\IRepository; class SimpleRepositoryLoader implements IRepositoryLoader { - /** @var IRepository[] */ + /** + * @var IRepository[] + * @phpstan-var array>, IRepository<\Nextras\Orm\Entity\IEntity>> + */ private $repositories; /** - * @param IRepository[] $repositories + * @phpstan-param list> $repositories */ public function __construct(array $repositories) { @@ -25,17 +29,25 @@ public function __construct(array $repositories) } + /** {@inheritDoc} */ public function hasRepository(string $className): bool { return isset($this->repositories[$className]); } + /** + * Returns instance of repository. + * @phpstan-template T of IRepository<\Nextras\Orm\Entity\IEntity> + * @phpstan-param class-string $className + * @phpstan-return T + */ public function getRepository(string $className): IRepository { if (!isset($this->repositories[$className])) { throw new InvalidArgumentException("Repository '$className' not defined."); } + /** @phpstan-var T */ return $this->repositories[$className]; } diff --git a/src/Relationships/HasMany.php b/src/Relationships/HasMany.php index f379d434..a5119e40 100644 --- a/src/Relationships/HasMany.php +++ b/src/Relationships/HasMany.php @@ -34,7 +34,10 @@ abstract class HasMany implements IRelationshipCollection /** @var PropertyRelationshipMetadata */ protected $metadataRelationship; - /** @var ICollection|null */ + /** + * @var ICollection|null + * @phpstan-var ICollection|null + */ protected $collection; /** @var IEntity[] */ @@ -49,7 +52,10 @@ abstract class HasMany implements IRelationshipCollection /** @var IEntity[] */ protected $tracked = []; - /** @var IRepository|null */ + /** + * @var IRepository|null + * @phpstan-var IRepository|null + */ protected $targetRepository; /** @var bool */ @@ -240,6 +246,7 @@ public function toCollection(): ICollection /** * @deprecated Use toCollection() instead. + * @phpstan-return ICollection */ public function get(): ICollection { @@ -261,6 +268,7 @@ public function countStored(): int /** * @return ICollection|IEntity[] + * @phpstan-return ICollection */ public function getIterator(): ICollection { @@ -290,6 +298,9 @@ public function trackEntity(IEntity $entity): void } + /** + * @phpstan-return ICollection + */ protected function getCollection(bool $forceNew = false): ICollection { if ($this->collection !== null && !$forceNew) { @@ -356,6 +367,9 @@ public function __clone() } + /** + * @phpstan-return IRepository + */ protected function getTargetRepository(): IRepository { if ($this->targetRepository === null) { @@ -379,6 +393,11 @@ protected function getRelationshipMapper(): IRelationshipMapper } + /** + * @phpstan-template T of ICollection + * @phpstan-param T $collection + * @phpstan-return T + */ protected function applyDefaultOrder(ICollection $collection): ICollection { if ($this->metadataRelationship->order !== null) { @@ -397,6 +416,7 @@ abstract protected function modify(): void; /** * Returns collection for has many relationship. + * @phpstan-return ICollection */ abstract protected function createCollection(): ICollection; diff --git a/src/Relationships/HasOne.php b/src/Relationships/HasOne.php index 3a239f8f..aac359fd 100644 --- a/src/Relationships/HasOne.php +++ b/src/Relationships/HasOne.php @@ -29,7 +29,10 @@ abstract class HasOne implements IRelationshipContainer /** @var PropertyRelationshipMetadata */ protected $metadataRelationship; - /** @var ICollection */ + /** + * @var ICollection + * @phpstan-var ICollection + */ protected $collection; /** @var mixed|null */ @@ -38,7 +41,10 @@ abstract class HasOne implements IRelationshipContainer /** @var IEntity|null|false */ protected $value = false; - /** @var IRepository|null */ + /** + * @var IRepository|null + * @phpstan-var IRepository|null + */ protected $targetRepository; /** @var bool */ @@ -193,6 +199,9 @@ protected function getPrimaryValue() } + /** + * @phpstan-return IRepository + */ protected function getTargetRepository(): IRepository { if ($this->targetRepository === null) { @@ -204,6 +213,9 @@ protected function getTargetRepository(): IRepository } + /** + * @phpstan-return ICollection + */ protected function getCollection(): ICollection { if ($this->collection !== null) { @@ -274,6 +286,7 @@ protected function isChanged($newValue): bool /** * Creates relationship collection. + * @phpstan-return ICollection */ abstract protected function createCollection(): ICollection; diff --git a/src/Relationships/IRelationshipCollection.php b/src/Relationships/IRelationshipCollection.php index 79aff7b3..bfccf920 100644 --- a/src/Relationships/IRelationshipCollection.php +++ b/src/Relationships/IRelationshipCollection.php @@ -46,6 +46,7 @@ public function has($entity): bool; /** * Returns collection of all entity. + * @phpstan-return ICollection */ public function toCollection(): ICollection; diff --git a/src/Relationships/OneHasMany.php b/src/Relationships/OneHasMany.php index eed00d33..0f0da299 100644 --- a/src/Relationships/OneHasMany.php +++ b/src/Relationships/OneHasMany.php @@ -51,7 +51,6 @@ protected function modify(): void $this->isModified = true; } - protected function createCollection(): ICollection { /** @phpstan-var callable(\Traversable):void $subscribeCb */ diff --git a/src/Relationships/OneHasOne.php b/src/Relationships/OneHasOne.php index 1711680a..aaa49f33 100644 --- a/src/Relationships/OneHasOne.php +++ b/src/Relationships/OneHasOne.php @@ -10,6 +10,7 @@ class OneHasOne extends HasOne { + /** {@inheritDoc} */ protected function createCollection(): ICollection { $collection = $this->getTargetRepository()->getMapper()->createCollectionOneHasOne($this->metadata); diff --git a/src/Repository/IRepository.php b/src/Repository/IRepository.php index 5ce9decc..bdafc365 100644 --- a/src/Repository/IRepository.php +++ b/src/Repository/IRepository.php @@ -21,6 +21,9 @@ use Nextras\Orm\Model\IModel; +/** + * @phpstan-template E of IEntity + */ interface IRepository { public function getModel(): IModel; @@ -29,24 +32,30 @@ public function getModel(): IModel; public function setModel(IModel $model): void; + /** + * @phpstan-return IMapper + */ public function getMapper(): IMapper; /** * Hydrates entity. * @param array $data + * @phpstan-return E|null */ public function hydrateEntity(array $data): ?IEntity; /** * Attaches entity to repository. + * @phpstan-param E $entity */ public function attach(IEntity $entity): void; /** * Detaches entity from repository. + * @phpstan-param E $entity */ public function detach(IEntity $entity): void; @@ -62,6 +71,7 @@ public static function getEntityClassNames(): array; /** * Returns entity metadata. * @param string|null $entityClass for STI (must extends base class) + * @phpstan-param class-string|null $entityClass */ public function getEntityMetadata(string $entityClass = null): EntityMetadata; @@ -69,7 +79,7 @@ public function getEntityMetadata(string $entityClass = null): EntityMetadata; /** * Returns entity class name. * @param array $data - * @phpstan-return class-string + * @phpstan-return class-string */ public function getEntityClassName(array $data): string; @@ -80,6 +90,7 @@ public function getEntityClassName(array $data): string; * Limits collection via {@see ICollection::findBy()} and returns the first entity (or null). * * @phpstan-param array|array $conds + * @phpstan-return E|null */ public function getBy(array $conds): ?IEntity; @@ -91,6 +102,7 @@ public function getBy(array $conds): ?IEntity; * * @phpstan-param array|array $conds * @throws NoResultException + * @phpstan-return E */ public function getByChecked(array $conds): IEntity; @@ -98,6 +110,7 @@ public function getByChecked(array $conds): IEntity; /** * Returns entity by primary value, null if none found. * @param mixed $id + * @phpstan-return E|null */ public function getById($id): ?IEntity; @@ -112,6 +125,7 @@ public function getByIdChecked($id): IEntity; /** * Returns new collection with all entities. + * @phpstan-return ICollection */ public function findAll(): ICollection; @@ -147,6 +161,7 @@ public function findAll(): ICollection; * * * @phpstan-param array|array|list $conds + * @phpstan-return ICollection */ public function findBy(array $conds): ICollection; @@ -155,6 +170,7 @@ public function findBy(array $conds): ICollection; * Returns entities by primary values. * @param mixed[] $ids * @phpstan-param list $ids + * @phpstan-return ICollection */ public function findByIds(array $ids): ICollection; @@ -172,15 +188,35 @@ public function getCollectionFunction(string $name); public function getConditionParser(): ConditionParser; + /** + * @phpstan-template F of E + * @phpstan-param F $entity + * @phpstan-return F + */ public function persist(IEntity $entity, bool $withCascade = true): IEntity; + /** + * @phpstan-template F of E + * @phpstan-param F $entity + * @phpstan-return F + */ public function persistAndFlush(IEntity $entity, bool $withCascade = true): IEntity; + /** + * @phpstan-template F of E + * @phpstan-param F $entity + * @phpstan-return F + */ public function remove(IEntity $entity, bool $withCascade = true): IEntity; + /** + * @phpstan-template F of E + * @phpstan-param F $entity + * @phpstan-return F + */ public function removeAndFlush(IEntity $entity, bool $withCascade = true): IEntity; @@ -194,6 +230,7 @@ public function flush(): void; * DO NOT CALL THIS METHOD DIRECTLY. * @internal * @ignore + * @phpstan-param E $entity */ public function doPersist(IEntity $entity): void; @@ -202,6 +239,7 @@ public function doPersist(IEntity $entity): void; * DO NOT CALL THIS METHOD DIRECTLY. * @internal * @ignore + * @phpstan-param E $entity */ public function doRemove(IEntity $entity): void; @@ -209,7 +247,7 @@ public function doRemove(IEntity $entity): void; /** * DO NOT CALL THIS METHOD DIRECTLY. * @internal - * @phpstan-return array{list, list} array of all persisted & removed entities + * @phpstan-return array{list, list} array of all persisted & removed entities * @ignore */ public function doFlush(): array; @@ -235,34 +273,58 @@ public function doRefreshAll(bool $allowOverwrite): void; // === events ====================================================================================================== - /** @internal */ + /** + * @phpstan-param E $entity + * @internal + */ public function onBeforePersist(IEntity $entity): void; - /** @internal */ + /** + * @phpstan-param E $entity + * @internal + */ public function onAfterPersist(IEntity $entity): void; - /** @internal */ + /** + * @phpstan-param E $entity + * @internal + */ public function onBeforeInsert(IEntity $entity): void; - /** @internal */ + /** + * @phpstan-param E $entity + * @internal + */ public function onAfterInsert(IEntity $entity): void; - /** @internal */ + /** + * @phpstan-param E $entity + * @internal + */ public function onBeforeUpdate(IEntity $entity): void; - /** @internal */ + /** + * @phpstan-param E $entity + * @internal + */ public function onAfterUpdate(IEntity $entity): void; - /** @internal */ + /** + * @phpstan-param E $entity + * @internal + */ public function onBeforeRemove(IEntity $entity): void; - /** @internal */ + /** + * @phpstan-param E $entity + * @internal + */ public function onAfterRemove(IEntity $entity): void; } diff --git a/src/Repository/IdentityMap.php b/src/Repository/IdentityMap.php index d3f6351b..e543470d 100644 --- a/src/Repository/IdentityMap.php +++ b/src/Repository/IdentityMap.php @@ -17,14 +17,20 @@ use ReflectionClass; +/** + * @phpstan-template E of IEntity + */ class IdentityMap { - /** @var IRepository */ + /** + * @var IRepository + * @phpstan-var IRepository + */ private $repository; /** - * @var IEntity[] - * @phpstan-var array + * @var E[] + * @phpstan-var array */ private $entities = []; @@ -36,11 +42,14 @@ class IdentityMap /** * @var ReflectionClass[] - * @phpstan-var array, ReflectionClass> + * @phpstan-var array, ReflectionClass> */ private $entityReflections; + /** + * @phpstan-param IRepository $repository + */ public function __construct(IRepository $repository) { $this->repository = $repository; @@ -60,6 +69,7 @@ public function hasById($id): bool /** * @param array|int|mixed $id * @return IEntity|null|false + * @phpstan-return E|null|false */ public function getById($id) { @@ -76,6 +86,9 @@ public function getById($id) } + /** + * @phpstan-param E $entity + */ public function add(IEntity $entity): void { $id = $this->getIdHash($entity->getPersistedId()); @@ -96,6 +109,7 @@ public function remove($id): void /** * @param array $data + * @phpstan-return E|null */ public function create(array $data): ?IEntity { @@ -121,7 +135,7 @@ public function create(array $data): ?IEntity /** * @return IEntity[] - * @phpstan-return list + * @phpstan-return list */ public function getAll(): array { @@ -166,6 +180,7 @@ public function isMarkedForRefresh(IEntity $entity): bool /** * @param array $data + * @phpstan-return E */ protected function createEntity(array $data): IEntity { diff --git a/src/Repository/Repository.php b/src/Repository/Repository.php index 3a8652a5..0c4343c0 100644 --- a/src/Repository/Repository.php +++ b/src/Repository/Repository.php @@ -43,6 +43,10 @@ use function count; +/** + * @phpstan-template E of IEntity + * @phpstan-implements IRepository + */ abstract class Repository implements IRepository { /** @@ -99,19 +103,25 @@ abstract class Repository implements IRepository */ public $onFlush = []; - /** @var IMapper */ + /** + * @var IMapper + * @phpstan-var IMapper + */ protected $mapper; /** * @var string|null - * @phpstan-var class-string|null + * @phpstan-var class-string|null */ protected $entityClassName; /** @var IModel|null */ private $model; - /** @var IdentityMap */ + /** + * @var IdentityMap + * @phpstan-var IdentityMap + */ private $identityMap; /** @var array */ @@ -119,7 +129,7 @@ abstract class Repository implements IRepository /** * @var array - * @phpstan-var array{list, list} + * @phpstan-var array{list, list} */ private $entitiesToFlush = [[], []]; @@ -139,8 +149,7 @@ abstract class Repository implements IRepository /** - * @param IMapper $mapper - * @param IDependencyProvider $dependencyProvider + * @phpstan-param IMapper $mapper */ public function __construct(IMapper $mapper, IDependencyProvider $dependencyProvider = null) { @@ -256,6 +265,7 @@ public function findBy(array $conds): ICollection /** * @param array|mixed $ids + * @return ICollection * @deprecated Use {@see findByIds()}. */ public function findById($ids): ICollection @@ -378,7 +388,9 @@ public function getEntityMetadata(string $entityClass = null): EntityMetadata public function getEntityClassName(array $data): string { if ($this->entityClassName === null) { - $this->entityClassName = static::getEntityClassNames()[0]; + /** @phpstan-var class-string $entityClassName */ + $entityClassName = static::getEntityClassNames()[0]; + $this->entityClassName = $entityClassName; } return $this->entityClassName; @@ -399,7 +411,8 @@ public function getConditionParser(): ConditionParser public function persist(IEntity $entity, bool $withCascade = true): IEntity { $this->identityMap->check($entity); - return $this->getModel()->persist($entity, $withCascade); + $this->getModel()->persist($entity, $withCascade); + return $entity; } @@ -464,18 +477,18 @@ public function flush(): void /** {@inheritdoc} */ public function persistAndFlush(IEntity $entity, bool $withCascade = true): IEntity { - $return = $this->persist($entity, $withCascade); + $this->persist($entity, $withCascade); $this->flush(); - return $return; + return $entity; } /** {@inheritdoc} */ public function removeAndFlush(IEntity $entity, bool $withCascade = true): IEntity { - $result = $this->remove($entity, $withCascade); + $this->remove($entity, $withCascade); $this->flush(); - return $result; + return $entity; } diff --git a/src/TestHelper/EntityCreator.php b/src/TestHelper/EntityCreator.php index 240e8d30..26c87d62 100644 --- a/src/TestHelper/EntityCreator.php +++ b/src/TestHelper/EntityCreator.php @@ -27,8 +27,8 @@ public function __construct(IModel $model) /** * @template T of IEntity * @phpstan-param class-string $entity + * @phpstan-param array $params * @phpstan-return T - * @param array $params */ public function create(string $entity, array $params = []): IEntity { diff --git a/src/TestHelper/TestMapper.php b/src/TestHelper/TestMapper.php index b8ddce8d..09bc7490 100644 --- a/src/TestHelper/TestMapper.php +++ b/src/TestHelper/TestMapper.php @@ -7,6 +7,10 @@ use Nextras\Orm\Mapper\Memory\ArrayMapper; +/** + * @phpstan-template E of \Nextras\Orm\Entity\IEntity + * @phpstan-extends ArrayMapper + */ class TestMapper extends ArrayMapper { /** @var string */ diff --git a/tests/cases/integration/Mapper/file.general.phpt b/tests/cases/integration/Mapper/file.general.phpt index 325fecff..345bd2e6 100644 --- a/tests/cases/integration/Mapper/file.general.phpt +++ b/tests/cases/integration/Mapper/file.general.phpt @@ -34,6 +34,7 @@ class FileMapperTest extends TestCase { public function testGeneral(): void { + /** @var Model $orm */ $orm = $this->createOrm(); $author = new Author(); @@ -59,6 +60,7 @@ class FileMapperTest extends TestCase $orm->authors->persistAndFlush($author); + /** @var Model $orm */ $orm = $this->createOrm(); $book3 = new Book(); $book3->author = $orm->authors->getByIdChecked(1); @@ -68,6 +70,7 @@ class FileMapperTest extends TestCase $orm->books->persistAndFlush($book3); + /** @var Model $orm */ $orm = $this->createOrm(); /** @var Author $author */ $author = $orm->authors->findAll()->fetch(); @@ -99,7 +102,7 @@ class FileMapperTest extends TestCase /** - * @return Model + * @return \Nextras\Orm\Model\Model */ private function createOrm() { @@ -107,20 +110,33 @@ class FileMapperTest extends TestCase return TEMP_DIR . "/$name.data"; // FileMock::create(''); }; - $factory = new SimpleModelFactory(new Cache(new MemoryStorage()), [ - 'books' => new BooksRepository(new TestFileMapper($fileName('books'))), - 'authors' => new AuthorsRepository(new TestFileMapper($fileName('authors'))), - 'publishers' => new PublishersRepository(new TestFileMapper($fileName('publishers'))), - 'tags' => new TagsRepository(new TestFileMapper($fileName('tags'))), - 'tagFollowers' => new TagFollowersRepository(new TestFileMapper($fileName('tags'))), - 'eans' => new EansRepository(new TestFileMapper($fileName('eans'))), - ]); - /** @var Model */ + // @phpstan-ignore-next-line + $factory = new SimpleModelFactory( + new Cache(new MemoryStorage()), + [ + // @phpstan-ignore-next-line + 'books' => new BooksRepository(new TestFileMapper($fileName('books'))), + // @phpstan-ignore-next-line + 'authors' => new AuthorsRepository(new TestFileMapper($fileName('authors'))), + // @phpstan-ignore-next-line + 'publishers' => new PublishersRepository(new TestFileMapper($fileName('publishers'))), + // @phpstan-ignore-next-line + 'tags' => new TagsRepository(new TestFileMapper($fileName('tags'))), + // @phpstan-ignore-next-line + 'tagFollowers' => new TagFollowersRepository(new TestFileMapper($fileName('tags'))), + // @phpstan-ignore-next-line + 'eans' => new EansRepository(new TestFileMapper($fileName('eans'))), + ] + ); return $factory->create(); } } +/** + * @template E of \Nextras\Orm\Entity\IEntity + * @extends ArrayMapper + */ class TestFileMapper extends ArrayMapper { /** @var string */ diff --git a/tests/cases/unit/Collection/ArrayCollectionTest.phpt b/tests/cases/unit/Collection/ArrayCollectionTest.phpt index 17f0b2a8..2ebedb1e 100644 --- a/tests/cases/unit/Collection/ArrayCollectionTest.phpt +++ b/tests/cases/unit/Collection/ArrayCollectionTest.phpt @@ -46,7 +46,6 @@ class ArrayCollectionTest extends TestCase public function testFiltering(): void { - /** @var ICollection $collection */ [$collection, $authors, $books] = $this->createCollection(); Assert::same($authors, iterator_to_array($collection)); @@ -66,7 +65,6 @@ class ArrayCollectionTest extends TestCase public function testFilteringDatetime(): void { - /** @var ICollection $collection */ [$collection, $authors, $books] = $this->createCollection(); Assert::same(1, $collection->findBy(['born<' => new DateTime('2011-01-02')])->count()); @@ -90,7 +88,6 @@ class ArrayCollectionTest extends TestCase public function testSorting(): void { - /** @var ICollection $collection */ [$collection, $authors, $books] = $this->createCollection(); Assert::same( @@ -133,7 +130,7 @@ class ArrayCollectionTest extends TestCase $this->e(Book::class, ['title' => 'd', 'printedAt' => new DateTime('2017-01-01 10:00:00')]), ]; - /** @var Book[]|ArrayCollection */ + /** @var Book[]|ArrayCollection */ $collection = new ArrayCollection($books, $this->orm->books); $collection = $collection->orderBy('printedAt', ICollection::DESC_NULLS_LAST); @@ -148,7 +145,6 @@ class ArrayCollectionTest extends TestCase public function testSlicing(): void { - /** @var ICollection $collection */ [$collection, $authors, $books] = $this->createCollection(); Assert::same($authors, iterator_to_array($collection->limitBy(3))); @@ -161,7 +157,6 @@ class ArrayCollectionTest extends TestCase public function testTogether(): void { - /** @var ICollection $collection */ [$collection, $authors, $books] = $this->createCollection(); Assert::same( @@ -184,7 +179,6 @@ class ArrayCollectionTest extends TestCase public function testCount(): void { - /** @var ICollection $collection */ [$collection, $authors, $books] = $this->createCollection(); Assert::same( @@ -214,7 +208,7 @@ class ArrayCollectionTest extends TestCase /** - * @return array{ICollection|Author[], Author[], Book[]} + * @return array{ICollection|Author[], Author[], Book[]} */ private function createCollection(): array { @@ -231,7 +225,7 @@ class ArrayCollectionTest extends TestCase $this->e(Book::class, ['title' => 'Valyria 3', 'author' => $authors[2]]), ]; - /** @var ICollection|Author[] $collection */ + /** @var ICollection|Author[] $collection */ $collection = new ArrayCollection($authors, $this->orm->authors); return [$collection, $authors, $books]; } diff --git a/tests/cases/unit/Entity/Reflection/MetadataParser.parseManyHasMany().phpt b/tests/cases/unit/Entity/Reflection/MetadataParser.parseManyHasMany().phpt index 54956f93..1d3abf4e 100644 --- a/tests/cases/unit/Entity/Reflection/MetadataParser.parseManyHasMany().phpt +++ b/tests/cases/unit/Entity/Reflection/MetadataParser.parseManyHasMany().phpt @@ -40,6 +40,9 @@ class ManyHasManyTestEntity extends Entity } +/** + * @extends Repository + */ class FooRepository extends Repository { public static function getEntityClassNames(): array @@ -54,7 +57,7 @@ class MetadataParserParseManyHasManyTest extends TestCase public function testManyHasMany(): void { $dependencies = []; - $parser = new MetadataParser([ + $parser = new MetadataParser([ // @phpstan-ignore-line Foo::class => FooRepository::class, ]); diff --git a/tests/cases/unit/Entity/Reflection/MetadataParser.parseOneHasMany().phpt b/tests/cases/unit/Entity/Reflection/MetadataParser.parseOneHasMany().phpt index b5cc7e9e..4c183b86 100644 --- a/tests/cases/unit/Entity/Reflection/MetadataParser.parseOneHasMany().phpt +++ b/tests/cases/unit/Entity/Reflection/MetadataParser.parseOneHasMany().phpt @@ -39,6 +39,9 @@ class OneHasManyTestEntity extends Entity } +/** + * @extends Repository + */ class BarRepository extends Repository { public static function getEntityClassNames(): array @@ -53,7 +56,7 @@ class MetadataParserParseOneHasManyTest extends TestCase public function testOneHasMany(): void { $dependencies = []; - $parser = new MetadataParser([ + $parser = new MetadataParser([ // @phpstan-ignore-line Bar::class => BarRepository::class, ]); diff --git a/tests/cases/unit/Mapper/Dbal/DbalMapperTest.phpt b/tests/cases/unit/Mapper/Dbal/DbalMapperTest.phpt index 26dd2678..29f743f2 100644 --- a/tests/cases/unit/Mapper/Dbal/DbalMapperTest.phpt +++ b/tests/cases/unit/Mapper/Dbal/DbalMapperTest.phpt @@ -44,7 +44,7 @@ class DbalMapperTest extends TestCase $repository->shouldReceive('hydrateEntity')->once()->with(['id' => 2])->andReturn($b = new Author()); $repository->shouldReceive('hydrateEntity')->once()->with(['id' => 3])->andReturn($c = new Author()); - /** @var ArrayCollection $collection */ + /** @var ArrayCollection $collection */ $collection = $mapper->toCollection([ ['id' => 1], ['id' => 2], @@ -93,7 +93,7 @@ class DbalMapperTest extends TestCase $result->shouldReceive('next')->times(3); $result->shouldReceive('valid')->once()->andReturn(false); - /** @var ArrayCollection $collection */ + /** @var ArrayCollection $collection */ $collection = $mapper->toCollection($result); Assert::type(ArrayCollection::class, $collection); diff --git a/tests/inc/model/author/AuthorsMapper.php b/tests/inc/model/author/AuthorsMapper.php index de64b6c4..4a2c1d95 100644 --- a/tests/inc/model/author/AuthorsMapper.php +++ b/tests/inc/model/author/AuthorsMapper.php @@ -3,10 +3,13 @@ namespace NextrasTests\Orm; -use Nextras\Orm\Mapper\Mapper; +use Nextras\Orm\Mapper\Dbal\DbalMapper; -final class AuthorsMapper extends Mapper +/** + * @phpstan-extends DbalMapper + */ +final class AuthorsMapper extends DbalMapper { public function getTableName(): string { diff --git a/tests/inc/model/author/AuthorsRepository.php b/tests/inc/model/author/AuthorsRepository.php index 52a4a376..1f33dab7 100644 --- a/tests/inc/model/author/AuthorsRepository.php +++ b/tests/inc/model/author/AuthorsRepository.php @@ -7,6 +7,9 @@ use Nextras\Orm\Repository\Repository; +/** + * @extends Repository + */ final class AuthorsRepository extends Repository { static function getEntityClassNames(): array @@ -16,7 +19,7 @@ static function getEntityClassNames(): array /** - * @return Author[]|ICollection + * @return Author[]|ICollection */ public function findByTags(string $name): ICollection { diff --git a/tests/inc/model/book/BooksMapper.php b/tests/inc/model/book/BooksMapper.php index 4600f494..fba63aeb 100644 --- a/tests/inc/model/book/BooksMapper.php +++ b/tests/inc/model/book/BooksMapper.php @@ -6,12 +6,15 @@ use Nextras\Orm\Collection\ICollection; use Nextras\Orm\Entity\IEntity; use Nextras\Orm\Mapper\Dbal\Conventions\IConventions; -use Nextras\Orm\Mapper\Mapper; +use Nextras\Orm\Mapper\Dbal\DbalMapper; -final class BooksMapper extends Mapper +/** + * @phpstan-extends DbalMapper + */ +final class BooksMapper extends DbalMapper { - /** @return Book[]|ICollection */ + /** @return Book[]|ICollection */ public function findBooksWithEvenId(): ICollection { return $this->toCollection($this->builder()->where('id % 2 = 0')); diff --git a/tests/inc/model/book/BooksRepository.php b/tests/inc/model/book/BooksRepository.php index a526b3d7..2123beab 100644 --- a/tests/inc/model/book/BooksRepository.php +++ b/tests/inc/model/book/BooksRepository.php @@ -8,8 +8,9 @@ /** - * @method ICollection|Book[] findBooksWithEvenId() + * @method ICollection|Book[] findBooksWithEvenId() * @method Book|null findFirstBook() + * @extends Repository */ final class BooksRepository extends Repository { @@ -19,7 +20,7 @@ static function getEntityClassNames(): array } - /** @return Book[]|ICollection */ + /** @return Book[]|ICollection */ public function findLatest(): ICollection { return $this->findAll() @@ -28,7 +29,7 @@ public function findLatest(): ICollection } - /** @return Book[]|ICollection */ + /** @return Book[]|ICollection */ public function findByTags(string $name): ICollection { return $this->findBy(['tags->name' => $name]); diff --git a/tests/inc/model/bookCollection/BookCollectionsMapper.php b/tests/inc/model/bookCollection/BookCollectionsMapper.php index bb6377f8..cb2265e0 100644 --- a/tests/inc/model/bookCollection/BookCollectionsMapper.php +++ b/tests/inc/model/bookCollection/BookCollectionsMapper.php @@ -7,6 +7,9 @@ use Nextras\Orm\Mapper\Dbal\IPersistAutoupdateMapper; +/** + * @phpstan-extends DbalMapper + */ class BookCollectionsMapper extends DbalMapper implements IPersistAutoupdateMapper { public function getAutoupdateReselectExpression(): array diff --git a/tests/inc/model/bookCollection/BookCollectionsRepository.php b/tests/inc/model/bookCollection/BookCollectionsRepository.php index 8874cf36..0569fabb 100644 --- a/tests/inc/model/bookCollection/BookCollectionsRepository.php +++ b/tests/inc/model/bookCollection/BookCollectionsRepository.php @@ -6,6 +6,9 @@ use Nextras\Orm\Repository\Repository; +/** + * @extends Repository + */ class BookCollectionsRepository extends Repository { public static function getEntityClassNames(): array diff --git a/tests/inc/model/contents/ContentsMapper.php b/tests/inc/model/contents/ContentsMapper.php index cb683430..a88dffc5 100644 --- a/tests/inc/model/contents/ContentsMapper.php +++ b/tests/inc/model/contents/ContentsMapper.php @@ -3,9 +3,12 @@ namespace NextrasTests\Orm; -use Nextras\Orm\Mapper\Mapper; +use Nextras\Orm\Mapper\Dbal\DbalMapper; -class ContentsMapper extends Mapper +/** + * @phpstan-extends DbalMapper + */ +class ContentsMapper extends DbalMapper { } diff --git a/tests/inc/model/contents/ContentsRepository.php b/tests/inc/model/contents/ContentsRepository.php index 961849d8..953cea0c 100644 --- a/tests/inc/model/contents/ContentsRepository.php +++ b/tests/inc/model/contents/ContentsRepository.php @@ -7,7 +7,7 @@ /** - * @method Thread|Comment|NULL getById($id) + * @extends Repository */ class ContentsRepository extends Repository { diff --git a/tests/inc/model/ean/EansMapper.php b/tests/inc/model/ean/EansMapper.php index 72949bc2..7bcd25ce 100644 --- a/tests/inc/model/ean/EansMapper.php +++ b/tests/inc/model/ean/EansMapper.php @@ -3,9 +3,12 @@ namespace NextrasTests\Orm; -use Nextras\Orm\Mapper\Mapper; +use Nextras\Orm\Mapper\Dbal\DbalMapper; -final class EansMapper extends Mapper +/** + * @phpstan-extends DbalMapper + */ +final class EansMapper extends DbalMapper { } diff --git a/tests/inc/model/ean/EansRepository.php b/tests/inc/model/ean/EansRepository.php index d726ce2e..f62ca01a 100644 --- a/tests/inc/model/ean/EansRepository.php +++ b/tests/inc/model/ean/EansRepository.php @@ -6,6 +6,9 @@ use Nextras\Orm\Repository\Repository; +/** + * @extends Repository + */ final class EansRepository extends Repository { static function getEntityClassNames(): array diff --git a/tests/inc/model/log/LogsMapper.php b/tests/inc/model/log/LogsMapper.php index 56a4f736..a43638d0 100644 --- a/tests/inc/model/log/LogsMapper.php +++ b/tests/inc/model/log/LogsMapper.php @@ -3,9 +3,12 @@ namespace NextrasTests\Orm; -use Nextras\Orm\Mapper\Mapper; +use Nextras\Orm\Mapper\Dbal\DbalMapper; -final class LogsMapper extends Mapper +/** + * @phpstan-extends DbalMapper + */ +final class LogsMapper extends DbalMapper { } diff --git a/tests/inc/model/log/LogsRepository.php b/tests/inc/model/log/LogsRepository.php index 69395014..99464942 100644 --- a/tests/inc/model/log/LogsRepository.php +++ b/tests/inc/model/log/LogsRepository.php @@ -6,6 +6,9 @@ use Nextras\Orm\Repository\Repository; +/** + * @extends Repository + */ final class LogsRepository extends Repository { static function getEntityClassNames(): array diff --git a/tests/inc/model/photo/PhotosMapper.php b/tests/inc/model/photo/PhotosMapper.php index 6c09fd64..45a9e63b 100644 --- a/tests/inc/model/photo/PhotosMapper.php +++ b/tests/inc/model/photo/PhotosMapper.php @@ -3,9 +3,12 @@ namespace NextrasTests\Orm; -use Nextras\Orm\Mapper\Mapper; +use Nextras\Orm\Mapper\Dbal\DbalMapper; -final class PhotosMapper extends Mapper +/** + * @phpstan-extends DbalMapper + */ +final class PhotosMapper extends DbalMapper { } diff --git a/tests/inc/model/photo/PhotosRepository.php b/tests/inc/model/photo/PhotosRepository.php index 8bb6f6a0..57d69d72 100644 --- a/tests/inc/model/photo/PhotosRepository.php +++ b/tests/inc/model/photo/PhotosRepository.php @@ -6,6 +6,9 @@ use Nextras\Orm\Repository\Repository; +/** + * @extends Repository + */ final class PhotosRepository extends Repository { static function getEntityClassNames(): array diff --git a/tests/inc/model/photoAlbum/PhotoAlbumsMapper.php b/tests/inc/model/photoAlbum/PhotoAlbumsMapper.php index 68dd20ba..ce865320 100644 --- a/tests/inc/model/photoAlbum/PhotoAlbumsMapper.php +++ b/tests/inc/model/photoAlbum/PhotoAlbumsMapper.php @@ -3,9 +3,12 @@ namespace NextrasTests\Orm; -use Nextras\Orm\Mapper\Mapper; +use Nextras\Orm\Mapper\Dbal\DbalMapper; -final class PhotoAlbumsMapper extends Mapper +/** + * @phpstan-extends DbalMapper + */ +final class PhotoAlbumsMapper extends DbalMapper { } diff --git a/tests/inc/model/photoAlbum/PhotoAlbumsRepository.php b/tests/inc/model/photoAlbum/PhotoAlbumsRepository.php index 7c4c21bf..155131d7 100644 --- a/tests/inc/model/photoAlbum/PhotoAlbumsRepository.php +++ b/tests/inc/model/photoAlbum/PhotoAlbumsRepository.php @@ -6,6 +6,9 @@ use Nextras\Orm\Repository\Repository; +/** + * @extends Repository + */ final class PhotoAlbumsRepository extends Repository { static function getEntityClassNames(): array diff --git a/tests/inc/model/publisher/PublishersMapper.php b/tests/inc/model/publisher/PublishersMapper.php index 46244e92..909ac618 100644 --- a/tests/inc/model/publisher/PublishersMapper.php +++ b/tests/inc/model/publisher/PublishersMapper.php @@ -3,9 +3,12 @@ namespace NextrasTests\Orm; -use Nextras\Orm\Mapper\Mapper; +use Nextras\Orm\Mapper\Dbal\DbalMapper; -final class PublishersMapper extends Mapper +/** + * @phpstan-extends DbalMapper + */ +final class PublishersMapper extends DbalMapper { } diff --git a/tests/inc/model/publisher/PublishersRepository.php b/tests/inc/model/publisher/PublishersRepository.php index 02bed3a9..2a00ae73 100644 --- a/tests/inc/model/publisher/PublishersRepository.php +++ b/tests/inc/model/publisher/PublishersRepository.php @@ -6,6 +6,9 @@ use Nextras\Orm\Repository\Repository; +/** + * @extends Repository + */ final class PublishersRepository extends Repository { static function getEntityClassNames(): array diff --git a/tests/inc/model/tag/TagsMapper.php b/tests/inc/model/tag/TagsMapper.php index 2739588d..571345d7 100644 --- a/tests/inc/model/tag/TagsMapper.php +++ b/tests/inc/model/tag/TagsMapper.php @@ -4,10 +4,13 @@ use Nextras\Orm\Mapper\Dbal\Conventions\IConventions; -use Nextras\Orm\Mapper\Mapper; +use Nextras\Orm\Mapper\Dbal\DbalMapper; -final class TagsMapper extends Mapper +/** + * @phpstan-extends DbalMapper + */ +final class TagsMapper extends DbalMapper { protected function createConventions(): IConventions { diff --git a/tests/inc/model/tag/TagsRepository.php b/tests/inc/model/tag/TagsRepository.php index 700ef65e..2712695d 100644 --- a/tests/inc/model/tag/TagsRepository.php +++ b/tests/inc/model/tag/TagsRepository.php @@ -6,6 +6,9 @@ use Nextras\Orm\Repository\Repository; +/** + * @extends Repository + */ final class TagsRepository extends Repository { static function getEntityClassNames(): array diff --git a/tests/inc/model/tagFollower/TagFollowersMapper.php b/tests/inc/model/tagFollower/TagFollowersMapper.php index 8a3bda43..ea07c12c 100644 --- a/tests/inc/model/tagFollower/TagFollowersMapper.php +++ b/tests/inc/model/tagFollower/TagFollowersMapper.php @@ -3,9 +3,12 @@ namespace NextrasTests\Orm; -use Nextras\Orm\Mapper\Mapper; +use Nextras\Orm\Mapper\Dbal\DbalMapper; -final class TagFollowersMapper extends Mapper +/** + * @phpstan-extends DbalMapper + */ +final class TagFollowersMapper extends DbalMapper { } diff --git a/tests/inc/model/tagFollower/TagFollowersRepository.php b/tests/inc/model/tagFollower/TagFollowersRepository.php index f34588cb..28900687 100644 --- a/tests/inc/model/tagFollower/TagFollowersRepository.php +++ b/tests/inc/model/tagFollower/TagFollowersRepository.php @@ -6,6 +6,9 @@ use Nextras\Orm\Repository\Repository; +/** + * @extends Repository + */ final class TagFollowersRepository extends Repository { static function getEntityClassNames(): array diff --git a/tests/inc/model/user/UsersMapper.php b/tests/inc/model/user/UsersMapper.php index 1882c197..d6373e05 100644 --- a/tests/inc/model/user/UsersMapper.php +++ b/tests/inc/model/user/UsersMapper.php @@ -3,9 +3,12 @@ namespace NextrasTests\Orm; -use Nextras\Orm\Mapper\Mapper; +use Nextras\Orm\Mapper\Dbal\DbalMapper; -final class UsersMapper extends Mapper +/** + * @phpstan-extends DbalMapper + */ +final class UsersMapper extends DbalMapper { } diff --git a/tests/inc/model/user/UsersRepository.php b/tests/inc/model/user/UsersRepository.php index 9e968c94..d7236371 100644 --- a/tests/inc/model/user/UsersRepository.php +++ b/tests/inc/model/user/UsersRepository.php @@ -6,6 +6,9 @@ use Nextras\Orm\Repository\Repository; +/** + * @extends Repository + */ final class UsersRepository extends Repository { static function getEntityClassNames(): array diff --git a/tests/inc/model/userStat/UserStatsMapper.php b/tests/inc/model/userStat/UserStatsMapper.php index 5c487a5c..882dc040 100644 --- a/tests/inc/model/userStat/UserStatsMapper.php +++ b/tests/inc/model/userStat/UserStatsMapper.php @@ -3,9 +3,12 @@ namespace NextrasTests\Orm; -use Nextras\Orm\Mapper\Mapper; +use Nextras\Orm\Mapper\Dbal\DbalMapper; -final class UserStatsMapper extends Mapper +/** + * @phpstan-extends DbalMapper + */ +final class UserStatsMapper extends DbalMapper { } diff --git a/tests/inc/model/userStat/UserStatsRepository.php b/tests/inc/model/userStat/UserStatsRepository.php index 08489fe6..6229c240 100644 --- a/tests/inc/model/userStat/UserStatsRepository.php +++ b/tests/inc/model/userStat/UserStatsRepository.php @@ -6,6 +6,9 @@ use Nextras\Orm\Repository\Repository; +/** + * @extends Repository + */ final class UserStatsRepository extends Repository { static function getEntityClassNames(): array