diff --git a/phpstan.neon b/phpstan.neon index 6f358e4b..27ffe6d2 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -6,6 +6,7 @@ includes: parameters: level: 7 + checkMissingOverrideMethodAttribute: true phpVersion: 80400 paths: diff --git a/src/AbstractManagerRegistry.php b/src/AbstractManagerRegistry.php index 23ce6854..0538914f 100644 --- a/src/AbstractManagerRegistry.php +++ b/src/AbstractManagerRegistry.php @@ -5,6 +5,7 @@ namespace Doctrine\Persistence; use InvalidArgumentException; +use Override; use ReflectionClass; use function assert; @@ -22,8 +23,8 @@ abstract class AbstractManagerRegistry implements ManagerRegistry */ public function __construct( private readonly string $name, - private array $connections, - private array $managers, + private readonly array $connections, + private readonly array $managers, private readonly string $defaultConnection, private readonly string $defaultManager, private readonly string|null $proxyInterfaceName = null, @@ -56,6 +57,7 @@ public function getName(): string return $this->name; } + #[Override] public function getConnection(string|null $name = null): object { if ($name === null) { @@ -74,6 +76,7 @@ public function getConnection(string|null $name = null): object /** * {@inheritDoc} */ + #[Override] public function getConnectionNames(): array { return $this->connections; @@ -82,6 +85,7 @@ public function getConnectionNames(): array /** * {@inheritDoc} */ + #[Override] public function getConnections(): array { $connections = []; @@ -92,11 +96,13 @@ public function getConnections(): array return $connections; } + #[Override] public function getDefaultConnectionName(): string { return $this->defaultConnection; } + #[Override] public function getDefaultManagerName(): string { return $this->defaultManager; @@ -107,6 +113,7 @@ public function getDefaultManagerName(): string * * @throws InvalidArgumentException */ + #[Override] public function getManager(string|null $name = null): ObjectManager { if ($name === null) { @@ -125,6 +132,7 @@ public function getManager(string|null $name = null): ObjectManager return $service; } + #[Override] public function getManagerForClass(string $class): ObjectManager|null { $proxyClass = new ReflectionClass($class); @@ -157,6 +165,7 @@ public function getManagerForClass(string $class): ObjectManager|null /** * {@inheritDoc} */ + #[Override] public function getManagerNames(): array { return $this->managers; @@ -165,6 +174,7 @@ public function getManagerNames(): array /** * {@inheritDoc} */ + #[Override] public function getManagers(): array { $managers = []; @@ -178,6 +188,7 @@ public function getManagers(): array return $managers; } + #[Override] public function getRepository( string $persistentObject, string|null $persistentManagerName = null, @@ -187,6 +198,7 @@ public function getRepository( ->getRepository($persistentObject); } + #[Override] public function resetManager(string|null $name = null): ObjectManager { if ($name === null) { diff --git a/src/Mapping/AbstractClassMetadataFactory.php b/src/Mapping/AbstractClassMetadataFactory.php index fd4f8cc7..fd8a9e32 100644 --- a/src/Mapping/AbstractClassMetadataFactory.php +++ b/src/Mapping/AbstractClassMetadataFactory.php @@ -6,6 +6,7 @@ use Doctrine\Persistence\Mapping\Driver\MappingDriver; use Doctrine\Persistence\Proxy; +use Override; use Psr\Cache\CacheItemPoolInterface; use ReflectionClass; use ReflectionException; @@ -76,6 +77,7 @@ public function getLoadedMetadata(): array /** * {@inheritDoc} */ + #[Override] public function getAllMetadata(): array { if (! $this->initialized) { @@ -153,6 +155,7 @@ private function normalizeClassName(string $className): string * @throws ReflectionException * @throws MappingException */ + #[Override] public function getMetadataFor(string $className): ClassMetadata { $className = $this->normalizeClassName($className); @@ -223,6 +226,7 @@ public function getMetadataFor(string $className): ClassMetadata return $this->loadedMetadata[$className]; } + #[Override] public function hasMetadataFor(string $className): bool { $className = $this->normalizeClassName($className); @@ -238,6 +242,7 @@ public function hasMetadataFor(string $className): bool * @phpstan-param class-string $className * @phpstan-param CMTemplate $class */ + #[Override] public function setMetadataFor(string $className, ClassMetadata $class): void { $this->loadedMetadata[$this->normalizeClassName($className)] = $class; @@ -375,6 +380,7 @@ abstract protected function doLoadMetadata( */ abstract protected function newClassMetadataInstance(string $className): ClassMetadata; + #[Override] public function isTransient(string $className): bool { if (! $this->initialized) { @@ -444,6 +450,7 @@ private function createDefaultProxyClassNameResolver(): void * * @template T of object */ + #[Override] public function resolveClassName(string $className): string { $pos = strrpos($className, '\\' . Proxy::MARKER . '\\'); diff --git a/src/Mapping/Driver/ClassNames.php b/src/Mapping/Driver/ClassNames.php index 3b2c57f3..9014ddd9 100644 --- a/src/Mapping/Driver/ClassNames.php +++ b/src/Mapping/Driver/ClassNames.php @@ -4,10 +4,12 @@ namespace Doctrine\Persistence\Mapping\Driver; +use Override; + /** * Basic implementation of ClassLocator that passes a list of class names. */ -final class ClassNames implements ClassLocator +final readonly class ClassNames implements ClassLocator { /** @param list $classNames */ public function __construct( @@ -16,6 +18,7 @@ public function __construct( } /** @return list */ + #[Override] public function getClassNames(): array { return $this->classNames; diff --git a/src/Mapping/Driver/DefaultFileLocator.php b/src/Mapping/Driver/DefaultFileLocator.php index 691a023d..f8df1f1d 100644 --- a/src/Mapping/Driver/DefaultFileLocator.php +++ b/src/Mapping/Driver/DefaultFileLocator.php @@ -5,6 +5,7 @@ namespace Doctrine\Persistence\Mapping\Driver; use Doctrine\Persistence\Mapping\MappingException; +use Override; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; @@ -22,8 +23,6 @@ * * This behavior is independent of the actual content of the file. It just detects * the file which is responsible for the given class name. - * - * @final since 4.2 */ final class DefaultFileLocator implements FileLocator { @@ -32,10 +31,7 @@ final class DefaultFileLocator implements FileLocator * * @var array */ - protected array $paths = []; - - /** The file extension of mapping documents. */ - protected string|null $fileExtension; + private array $paths = []; /** * Initializes a new FileDriver that looks in the given path(s) for mapping @@ -46,8 +42,10 @@ final class DefaultFileLocator implements FileLocator * @param string|null $fileExtension The file extension of mapping documents, * usually prefixed with a dot. */ - public function __construct(string|array $paths, string|null $fileExtension = null) - { + public function __construct( + string|array $paths, + private string|null $fileExtension = null, + ) { $this->addPaths((array) $paths); $this->fileExtension = $fileExtension; } @@ -67,12 +65,14 @@ public function addPaths(array $paths): void * * @return array */ + #[Override] public function getPaths(): array { return $this->paths; } /** Gets the file extension used to look for mapping files under. */ + #[Override] public function getFileExtension(): string|null { return $this->fileExtension; @@ -88,6 +88,7 @@ public function setFileExtension(string|null $fileExtension): void $this->fileExtension = $fileExtension; } + #[Override] public function findMappingFile(string $className): string { $fileName = str_replace('\\', '.', $className) . $this->fileExtension; @@ -105,6 +106,7 @@ public function findMappingFile(string $className): string /** * {@inheritDoc} */ + #[Override] public function getAllClassNames(string $globalBasename): array { if ($this->paths === []) { @@ -142,6 +144,7 @@ public function getAllClassNames(string $globalBasename): array return $classes; } + #[Override] public function fileExists(string $className): bool { $fileName = str_replace('\\', '.', $className) . $this->fileExtension; diff --git a/src/Mapping/Driver/FileClassLocator.php b/src/Mapping/Driver/FileClassLocator.php index dae77929..09d5e534 100644 --- a/src/Mapping/Driver/FileClassLocator.php +++ b/src/Mapping/Driver/FileClassLocator.php @@ -10,6 +10,7 @@ use FilesystemIterator; use InvalidArgumentException; use Iterator; +use Override; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use ReflectionClass; @@ -34,7 +35,7 @@ * * It is compatible with the Symfony Finder component, but does not require it. */ -final class FileClassLocator implements ClassLocator +final readonly class FileClassLocator implements ClassLocator { /** @param iterable $files An iterable of files to include. */ public function __construct( @@ -43,6 +44,7 @@ public function __construct( } /** @return list */ + #[Override] public function getClassNames(): array { $includedFiles = []; diff --git a/src/Mapping/Driver/FileDriver.php b/src/Mapping/Driver/FileDriver.php index a56ae5cc..e19eb2b2 100644 --- a/src/Mapping/Driver/FileDriver.php +++ b/src/Mapping/Driver/FileDriver.php @@ -5,6 +5,7 @@ namespace Doctrine\Persistence\Mapping\Driver; use Doctrine\Persistence\Mapping\MappingException; +use Override; use function array_keys; use function array_unique; @@ -95,6 +96,7 @@ public function getElement(string $className): mixed return $result[$className]; } + #[Override] public function isTransient(string $className): bool { if ($this->classCache === null) { @@ -111,6 +113,7 @@ public function isTransient(string $className): bool /** * {@inheritDoc} */ + #[Override] public function getAllClassNames(): array { if ($this->classCache === null) { diff --git a/src/Mapping/Driver/MappingDriverChain.php b/src/Mapping/Driver/MappingDriverChain.php index 2a7c4fc3..ed773443 100644 --- a/src/Mapping/Driver/MappingDriverChain.php +++ b/src/Mapping/Driver/MappingDriverChain.php @@ -6,6 +6,7 @@ use Doctrine\Persistence\Mapping\ClassMetadata; use Doctrine\Persistence\Mapping\MappingException; +use Override; use function array_keys; use function spl_object_id; @@ -14,8 +15,6 @@ /** * The DriverChain allows you to add multiple other mapping drivers for * certain namespaces. - * - * @final since 4.2 */ final class MappingDriverChain implements MappingDriver { @@ -55,6 +54,7 @@ public function getDrivers(): array return $this->drivers; } + #[Override] public function loadMetadataForClass(string $className, ClassMetadata $metadata): void { foreach ($this->drivers as $namespace => $driver) { @@ -77,6 +77,7 @@ public function loadMetadataForClass(string $className, ClassMetadata $metadata) /** * {@inheritDoc} */ + #[Override] public function getAllClassNames(): array { $classNames = []; @@ -107,6 +108,7 @@ public function getAllClassNames(): array return array_keys($classNames); } + #[Override] public function isTransient(string $className): bool { foreach ($this->drivers as $namespace => $driver) { diff --git a/src/Mapping/Driver/PHPDriver.php b/src/Mapping/Driver/PHPDriver.php index 31d2dd90..91a5362a 100644 --- a/src/Mapping/Driver/PHPDriver.php +++ b/src/Mapping/Driver/PHPDriver.php @@ -7,13 +7,13 @@ use Closure; use Doctrine\Persistence\Mapping\ClassMetadata; use Doctrine\Persistence\Mapping\MappingException; +use Override; /** * The PHPDriver includes php files which just populate ClassMetadataInfo * instances with plain PHP code. * * @template-extends FileDriver> - * @final since 4.2 */ final class PHPDriver extends FileDriver { @@ -26,6 +26,7 @@ public function __construct(string|array|FileLocator $locator) parent::__construct($locator, '.php'); } + #[Override] public function loadMetadataForClass(string $className, ClassMetadata $metadata): void { $this->metadata = $metadata; @@ -36,6 +37,7 @@ public function loadMetadataForClass(string $className, ClassMetadata $metadata) /** * {@inheritDoc} */ + #[Override] protected function loadMappingFile(string $file): array { $callback = Closure::bind(static function (string $file): mixed { diff --git a/src/Mapping/Driver/StaticPHPDriver.php b/src/Mapping/Driver/StaticPHPDriver.php index 5aa4ec85..95bfb210 100644 --- a/src/Mapping/Driver/StaticPHPDriver.php +++ b/src/Mapping/Driver/StaticPHPDriver.php @@ -6,6 +6,7 @@ use Doctrine\Persistence\Mapping\ClassMetadata; use Doctrine\Persistence\Mapping\MappingException; +use Override; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use ReflectionClass; @@ -20,8 +21,6 @@ /** * The StaticPHPDriver calls a static loadMetadata() method on your entity * classes where you can manually populate the ClassMetadata instance. - * - * @final since 4.2 */ final class StaticPHPDriver implements MappingDriver { @@ -52,6 +51,7 @@ public function addPaths(array $paths): void $this->paths = array_unique([...$this->paths, ...$paths]); } + #[Override] public function loadMetadataForClass(string $className, ClassMetadata $metadata): void { $className::loadMetadata($metadata); @@ -63,6 +63,7 @@ public function loadMetadataForClass(string $className, ClassMetadata $metadata) * @todo Same code exists in ColocatedMappingDriver, should we re-use it * somehow or not worry about it? */ + #[Override] public function getAllClassNames(): array { if ($this->classNames !== null) { @@ -116,6 +117,7 @@ public function getAllClassNames(): array return $classes; } + #[Override] public function isTransient(string $className): bool { return ! method_exists($className, 'loadMetadata'); diff --git a/src/Mapping/Driver/SymfonyFileLocator.php b/src/Mapping/Driver/SymfonyFileLocator.php index 9cbc3823..21473394 100644 --- a/src/Mapping/Driver/SymfonyFileLocator.php +++ b/src/Mapping/Driver/SymfonyFileLocator.php @@ -6,6 +6,7 @@ use Doctrine\Persistence\Mapping\MappingException; use InvalidArgumentException; +use Override; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use RuntimeException; @@ -30,8 +31,6 @@ * The Symfony File Locator makes a simplifying assumptions compared * to the DefaultFileLocator. By assuming paths only contain entities of a certain * namespace the mapping files consists of the short classname only. - * - * @final since 4.2 */ final class SymfonyFileLocator implements FileLocator { @@ -101,11 +100,13 @@ public function getNamespacePrefixes(): array /** * {@inheritDoc} */ + #[Override] public function getPaths(): array { return $this->paths; } + #[Override] public function getFileExtension(): string|null { return $this->fileExtension; @@ -121,6 +122,7 @@ public function setFileExtension(string $fileExtension): void $this->fileExtension = $fileExtension; } + #[Override] public function fileExists(string $className): bool { $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension; @@ -153,6 +155,7 @@ public function fileExists(string $className): bool /** * {@inheritDoc} */ + #[Override] public function getAllClassNames(string|null $globalBasename = null): array { if ($this->paths === []) { @@ -201,6 +204,7 @@ public function getAllClassNames(string|null $globalBasename = null): array return $classes; } + #[Override] public function findMappingFile(string $className): string { $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension; diff --git a/src/Mapping/RuntimeReflectionService.php b/src/Mapping/RuntimeReflectionService.php index eccbafce..f81108fe 100644 --- a/src/Mapping/RuntimeReflectionService.php +++ b/src/Mapping/RuntimeReflectionService.php @@ -6,6 +6,7 @@ use Doctrine\Persistence\Reflection\RuntimeReflectionProperty; use Doctrine\Persistence\Reflection\TypedNoDefaultReflectionProperty; +use Override; use ReflectionClass; use ReflectionException; use ReflectionMethod; @@ -17,14 +18,13 @@ /** * PHP Runtime Reflection Service. - * - * @final since 4.2 */ final class RuntimeReflectionService implements ReflectionService { /** * {@inheritDoc} */ + #[Override] public function getParentClasses(string $class): array { if (! class_exists($class)) { @@ -38,6 +38,7 @@ public function getParentClasses(string $class): array return $parents; } + #[Override] public function getClassShortName(string $class): string { $reflectionClass = new ReflectionClass($class); @@ -45,6 +46,7 @@ public function getClassShortName(string $class): string return $reflectionClass->getShortName(); } + #[Override] public function getClassNamespace(string $class): string { $reflectionClass = new ReflectionClass($class); @@ -59,11 +61,13 @@ public function getClassNamespace(string $class): string * * @template T of object */ + #[Override] public function getClass(string $class): ReflectionClass { return new ReflectionClass($class); } + #[Override] public function getAccessibleProperty(string $class, string $property): RuntimeReflectionProperty { $reflectionProperty = new RuntimeReflectionProperty($class, $property); @@ -75,6 +79,7 @@ public function getAccessibleProperty(string $class, string $property): RuntimeR return $reflectionProperty; } + #[Override] public function hasPublicMethod(string $class, string $method): bool { try { diff --git a/src/ObjectManagerDecorator.php b/src/ObjectManagerDecorator.php index dabdcdb2..b4c4c104 100644 --- a/src/ObjectManagerDecorator.php +++ b/src/ObjectManagerDecorator.php @@ -6,6 +6,7 @@ use Doctrine\Persistence\Mapping\ClassMetadata; use Doctrine\Persistence\Mapping\ClassMetadataFactory; +use Override; /** * Base class to simplify ObjectManager decorators @@ -20,67 +21,80 @@ abstract class ObjectManagerDecorator implements ObjectManager /** * {@inheritDoc} */ + #[Override] public function find(string $className, $id): object|null { return $this->wrapped->find($className, $id); } + #[Override] public function persist(object $object): void { $this->wrapped->persist($object); } + #[Override] public function remove(object $object): void { $this->wrapped->remove($object); } + #[Override] public function clear(): void { $this->wrapped->clear(); } + #[Override] public function detach(object $object): void { $this->wrapped->detach($object); } + #[Override] public function refresh(object $object): void { $this->wrapped->refresh($object); } + #[Override] public function flush(): void { $this->wrapped->flush(); } + #[Override] public function getRepository(string $className): ObjectRepository { return $this->wrapped->getRepository($className); } + #[Override] public function getClassMetadata(string $className): ClassMetadata { return $this->wrapped->getClassMetadata($className); } /** @phpstan-return ClassMetadataFactory> */ + #[Override] public function getMetadataFactory(): ClassMetadataFactory { return $this->wrapped->getMetadataFactory(); } + #[Override] public function initializeObject(object $obj): void { $this->wrapped->initializeObject($obj); } + #[Override] public function isUninitializedObject(mixed $value): bool { return $this->wrapped->isUninitializedObject($value); } + #[Override] public function contains(object $object): bool { return $this->wrapped->contains($object); diff --git a/src/Reflection/EnumReflectionProperty.php b/src/Reflection/EnumReflectionProperty.php index 3a812f9e..1095337f 100644 --- a/src/Reflection/EnumReflectionProperty.php +++ b/src/Reflection/EnumReflectionProperty.php @@ -5,6 +5,7 @@ namespace Doctrine\Persistence\Reflection; use BackedEnum; +use Override; use ReflectionProperty; use function array_map; @@ -13,8 +14,6 @@ /** * PHP Enum Reflection Property - special override for backed enums. - * - * @final since 4.2 */ final class EnumReflectionProperty extends ReflectionProperty { @@ -33,6 +32,7 @@ public function __construct(private readonly ReflectionProperty $originalReflect * * @return int|string|int[]|string[]|null */ + #[Override] public function getValue($object = null): int|string|array|null { if ($object === null) { @@ -53,6 +53,7 @@ public function getValue($object = null): int|string|array|null * * @param object|null $object */ + #[Override] public function setValue(mixed $object, mixed $value = null): void { if ($value !== null) { diff --git a/src/Reflection/RuntimeReflectionProperty.php b/src/Reflection/RuntimeReflectionProperty.php index db3e59f2..5338847a 100644 --- a/src/Reflection/RuntimeReflectionProperty.php +++ b/src/Reflection/RuntimeReflectionProperty.php @@ -5,6 +5,7 @@ namespace Doctrine\Persistence\Reflection; use Doctrine\Persistence\Proxy; +use Override; use ReflectionProperty; use function ltrim; @@ -30,6 +31,7 @@ public function __construct(string $class, string $name) $this->key = $this->isPrivate() ? "\0" . ltrim($class, '\\') . "\0" . $name : ($this->isProtected() ? "\0*\0" . $name : $name); } + #[Override] public function getValue(object|null $object = null): mixed { if ($object === null) { @@ -44,6 +46,7 @@ public function getValue(object|null $object = null): mixed * * @param object|null $object */ + #[Override] public function setValue(mixed $object, mixed $value = null): void { if (! ($object instanceof Proxy && ! $object->__isInitialized())) { diff --git a/src/Reflection/TypedNoDefaultReflectionProperty.php b/src/Reflection/TypedNoDefaultReflectionProperty.php index ae3a22bc..d17335c9 100644 --- a/src/Reflection/TypedNoDefaultReflectionProperty.php +++ b/src/Reflection/TypedNoDefaultReflectionProperty.php @@ -5,13 +5,12 @@ namespace Doctrine\Persistence\Reflection; use Closure; +use Override; use function assert; /** * PHP Typed No Default Reflection Property - special override for typed properties without a default value. - * - * @final since 4.2 */ final class TypedNoDefaultReflectionProperty extends RuntimeReflectionProperty { @@ -22,6 +21,7 @@ final class TypedNoDefaultReflectionProperty extends RuntimeReflectionProperty * This is necessary to avoid PHP error "Error: Typed property must not be accessed before initialization". * Should be used only for reflecting typed properties without a default value. */ + #[Override] public function getValue(object|null $object = null): mixed { return $object !== null && $this->isInitialized($object) ? parent::getValue($object) : null; @@ -37,6 +37,7 @@ public function getValue(object|null $object = null): mixed * * @param object|null $object */ + #[Override] public function setValue(mixed $object, mixed $value = null): void { if ($value === null && $this->hasType() && ! $this->getType()->allowsNull()) { diff --git a/tests/ManagerRegistryTest.php b/tests/ManagerRegistryTest.php index c796d658..7f0d17ec 100644 --- a/tests/ManagerRegistryTest.php +++ b/tests/ManagerRegistryTest.php @@ -12,6 +12,7 @@ use Doctrine\Persistence\ObjectRepository; use Doctrine\Persistence\Proxy; use Doctrine\Tests\Persistence\Mapping\TestClassMetadataFactory; +use Override; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -24,6 +25,7 @@ class ManagerRegistryTest extends TestCase { private TestManagerRegistry $mr; + #[Override] protected function setUp(): void { $this->mr = new TestManagerRegistry( @@ -48,11 +50,13 @@ public function testGetManagerForClass(): void public function testGetManagerForClassAnonymous(): void { $anonymousClass = new class extends TestObject implements Proxy { + #[Override] public function __isInitialized(): bool { return true; } + #[Override] public function __load(): void { } @@ -100,11 +104,13 @@ public function testGetManagerForWithoutProxyInterface(): void self::assertNull($mr->getManagerForClass(TestObjectProxy::class)); $anonymousClass = new class extends TestObject implements Proxy { + #[Override] public function __isInitialized(): bool { return true; } + #[Override] public function __load(): void { } @@ -251,6 +257,7 @@ public function __construct( ); } + #[Override] protected function getService(string $name): ObjectManager { if (! isset($this->services[$name])) { @@ -260,6 +267,7 @@ protected function getService(string $name): ObjectManager return $this->services[$name]; } + #[Override] protected function resetService(string $name): void { unset($this->services[$name]); diff --git a/tests/Mapping/AbstractClassMetadataFactoryTest.php b/tests/Mapping/AbstractClassMetadataFactoryTest.php index a76e5219..45647138 100644 --- a/tests/Mapping/AbstractClassMetadataFactoryTest.php +++ b/tests/Mapping/AbstractClassMetadataFactoryTest.php @@ -9,6 +9,7 @@ use Doctrine\Persistence\Mapping\Driver\MappingDriver; use Doctrine\Persistence\Mapping\MappingException; use Doctrine\Persistence\Mapping\ReflectionService; +use Override; use PHPUnit\Framework\TestCase; use RuntimeException; @@ -139,32 +140,38 @@ public function __construct( ) { } + #[Override] protected function initialize(): void { $this->initialized = true; } + #[Override] protected function getDriver(): MappingDriver { return $this->driver ?? throw new RuntimeException('Driver not set'); } + #[Override] protected function wakeupReflection(ClassMetadata $class, ReflectionService $reflService): void { // No-op for tests } + #[Override] protected function initializeReflection(ClassMetadata $class, ReflectionService $reflService): void { // No-op for tests } + #[Override] protected function isEntity(ClassMetadata $class): bool { return true; } /** @param list $nonSuperclassParents */ + #[Override] protected function doLoadMetadata( ClassMetadata $class, ClassMetadata|null $parent, @@ -174,6 +181,7 @@ protected function doLoadMetadata( // No-op for tests - metadata loading is handled by driver } + #[Override] protected function newClassMetadataInstance(string $className): ClassMetadata { if ($this->newClassMetadataInstanceCallback !== null) { diff --git a/tests/Mapping/ClassMetadataFactoryTest.php b/tests/Mapping/ClassMetadataFactoryTest.php index 0e57fe55..d8a6346a 100644 --- a/tests/Mapping/ClassMetadataFactoryTest.php +++ b/tests/Mapping/ClassMetadataFactoryTest.php @@ -9,6 +9,7 @@ use Doctrine\Persistence\Mapping\Driver\MappingDriver; use Doctrine\Persistence\Mapping\MappingException; use Foo; +use Override; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; @@ -24,6 +25,7 @@ class ClassMetadataFactoryTest extends TestCase /** @phpstan-var TestClassMetadataFactory> */ private TestClassMetadataFactory $cmf; + #[Override] protected function setUp(): void { $driver = $this->createMock(MappingDriver::class); diff --git a/tests/Mapping/ColocatedMappingDriverTest.php b/tests/Mapping/ColocatedMappingDriverTest.php index 7b9eebe4..0f901781 100644 --- a/tests/Mapping/ColocatedMappingDriverTest.php +++ b/tests/Mapping/ColocatedMappingDriverTest.php @@ -13,6 +13,7 @@ use Doctrine\Tests\Persistence\Mapping\_files\colocated\EntityFixture; use Doctrine\Tests\Persistence\Mapping\_files\colocated\TestClass; use Generator; +use Override; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; @@ -137,10 +138,12 @@ public function __construct(array|ClassLocator $paths) /** * {@inheritDoc} */ + #[Override] public function loadMetadataForClass($className, ClassMetadata $metadata): void { } + #[Override] public function isTransient(string $className): bool { return $className === TestClass::class; diff --git a/tests/Mapping/FileDriverTest.php b/tests/Mapping/FileDriverTest.php index a9955c48..6018fd2d 100644 --- a/tests/Mapping/FileDriverTest.php +++ b/tests/Mapping/FileDriverTest.php @@ -11,6 +11,7 @@ use Doctrine\Tests\Persistence\Mapping\Fixtures\GlobalClass; use Doctrine\Tests\Persistence\Mapping\Fixtures\NotLoadedClass; use Doctrine\Tests\Persistence\Mapping\Fixtures\TestClassMetadata; +use Override; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use stdClass; @@ -210,6 +211,7 @@ class TestFileDriver extends FileDriver /** * {@inheritDoc} */ + #[Override] protected function loadMappingFile(string $file): array { if (str_contains($file, 'global.yml')) { @@ -223,6 +225,7 @@ protected function loadMappingFile(string $file): array } /** @param ClassMetadata $metadata */ + #[Override] public function loadMetadataForClass(string $className, ClassMetadata $metadata): void { } diff --git a/tests/Mapping/Fixtures/TestClassMetadata.php b/tests/Mapping/Fixtures/TestClassMetadata.php index 5667fd5a..9179c345 100644 --- a/tests/Mapping/Fixtures/TestClassMetadata.php +++ b/tests/Mapping/Fixtures/TestClassMetadata.php @@ -6,6 +6,7 @@ use Doctrine\Persistence\Mapping\ClassMetadata; use LogicException; +use Override; use ReflectionClass; /** @@ -19,6 +20,7 @@ public function __construct(private readonly string $className) { } + #[Override] public function getName(): string { return $this->className; @@ -27,36 +29,43 @@ public function getName(): string /** * {@inheritDoc} */ + #[Override] public function getIdentifier(): array { return ['id']; } + #[Override] public function getReflectionClass(): ReflectionClass { return new ReflectionClass($this->getName()); } + #[Override] public function isIdentifier(string $fieldName): bool { return false; } + #[Override] public function hasField(string $fieldName): bool { return false; } + #[Override] public function hasAssociation(string $fieldName): bool { return false; } + #[Override] public function isSingleValuedAssociation(string $fieldName): bool { return false; } + #[Override] public function isCollectionValuedAssociation(string $fieldName): bool { return false; @@ -65,6 +74,7 @@ public function isCollectionValuedAssociation(string $fieldName): bool /** * {@inheritDoc} */ + #[Override] public function getFieldNames(): array { return []; @@ -73,6 +83,7 @@ public function getFieldNames(): array /** * {@inheritDoc} */ + #[Override] public function getIdentifierFieldNames(): array { return []; @@ -81,26 +92,31 @@ public function getIdentifierFieldNames(): array /** * {@inheritDoc} */ + #[Override] public function getAssociationNames(): array { return []; } + #[Override] public function getTypeOfField(string $fieldName): never { throw new LogicException('Not implemented'); } + #[Override] public function getAssociationTargetClass(string $assocName): never { throw new LogicException('Not implemented'); } + #[Override] public function isAssociationInverseSide(string $assocName): bool { return false; } + #[Override] public function getAssociationMappedByTargetField(string $assocName): never { throw new LogicException('Not implemented'); @@ -109,6 +125,7 @@ public function getAssociationMappedByTargetField(string $assocName): never /** * {@inheritDoc} */ + #[Override] public function getIdentifierValues(object $object): array { return []; diff --git a/tests/Mapping/RuntimeReflectionServiceTest.php b/tests/Mapping/RuntimeReflectionServiceTest.php index c6e54b7f..e9f18235 100644 --- a/tests/Mapping/RuntimeReflectionServiceTest.php +++ b/tests/Mapping/RuntimeReflectionServiceTest.php @@ -8,6 +8,7 @@ use Doctrine\Persistence\Mapping\RuntimeReflectionService; use Doctrine\Persistence\Reflection\RuntimeReflectionProperty; use Doctrine\Persistence\Reflection\TypedNoDefaultReflectionProperty; +use Override; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; use ReflectionProperty; @@ -31,6 +32,7 @@ class RuntimeReflectionServiceTest extends TestCase public string $nonTypedNoDefaultPublicProperty; public string $nonTypedDefaultPublicProperty = ''; + #[Override] protected function setUp(): void { $this->reflectionService = new RuntimeReflectionService(); diff --git a/tests/Mapping/TestClassMetadataFactory.php b/tests/Mapping/TestClassMetadataFactory.php index 0aefd359..b0b30e66 100644 --- a/tests/Mapping/TestClassMetadataFactory.php +++ b/tests/Mapping/TestClassMetadataFactory.php @@ -8,6 +8,7 @@ use Doctrine\Persistence\Mapping\ClassMetadata; use Doctrine\Persistence\Mapping\Driver\MappingDriver; use Doctrine\Persistence\Mapping\ReflectionService; +use Override; /** * @template CMTemplate of ClassMetadata @@ -26,6 +27,7 @@ public function __construct(public MappingDriver $driver, public ClassMetadata $ /** * {@inheritDoc} */ + #[Override] protected function doLoadMetadata( ClassMetadata $class, ClassMetadata|null $parent, @@ -34,33 +36,40 @@ protected function doLoadMetadata( ): void { } + #[Override] protected function initialize(): void { } + #[Override] protected function newClassMetadataInstance(string $className): ClassMetadata { return $this->metadata; } + #[Override] protected function getDriver(): MappingDriver { return $this->driver; } + #[Override] protected function wakeupReflection(ClassMetadata $class, ReflectionService $reflService): void { } + #[Override] protected function initializeReflection(ClassMetadata $class, ReflectionService $reflService): void { } + #[Override] protected function isEntity(ClassMetadata $class): bool { return true; } + #[Override] protected function onNotFoundMetadata(string $className): ClassMetadata|null { if ($this->fallbackCallback === null) { @@ -70,11 +79,13 @@ protected function onNotFoundMetadata(string $className): ClassMetadata|null return ($this->fallbackCallback)(); } + #[Override] public function isTransient(string $className): bool { return $className !== $this->metadata->getName(); } + #[Override] public function getCacheKey(string $realClassName): string { return parent::getCacheKey($realClassName); diff --git a/tests/ObjectManagerDecoratorTest.php b/tests/ObjectManagerDecoratorTest.php index ba13da0d..4f15d53c 100644 --- a/tests/ObjectManagerDecoratorTest.php +++ b/tests/ObjectManagerDecoratorTest.php @@ -9,6 +9,7 @@ use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectManagerDecorator; use Doctrine\Persistence\ObjectRepository; +use Override; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -18,6 +19,7 @@ class ObjectManagerDecoratorTest extends TestCase private NullObjectManagerDecorator $decorated; + #[Override] protected function setUp(): void { $this->wrapped = $this->createMock(ObjectManager::class); diff --git a/tests/RuntimeReflectionPropertyTest.php b/tests/RuntimeReflectionPropertyTest.php index eeead9f2..90a7241d 100644 --- a/tests/RuntimeReflectionPropertyTest.php +++ b/tests/RuntimeReflectionPropertyTest.php @@ -7,6 +7,7 @@ use Closure; use Doctrine\Persistence\Proxy; use Doctrine\Persistence\Reflection\RuntimeReflectionProperty; +use Override; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; @@ -97,10 +98,12 @@ public function __construct(protected Closure|null $initializer = null) { } + #[Override] public function __load(): void { } + #[Override] public function __isInitialized(): bool { return $this->initialized; diff --git a/tests/TestObjectProxy.php b/tests/TestObjectProxy.php index bde79ca6..933b7427 100644 --- a/tests/TestObjectProxy.php +++ b/tests/TestObjectProxy.php @@ -5,14 +5,17 @@ namespace Doctrine\Tests\Persistence; use Doctrine\Persistence\Proxy; +use Override; /** @implements Proxy */ class TestObjectProxy extends TestObject implements Proxy { + #[Override] public function __load(): void { } + #[Override] public function __isInitialized(): bool { return true;