Skip to content

Commit

Permalink
Deprecate passing null to some ClassMetadata methods
Browse files Browse the repository at this point in the history
It can easily be avoided by callers.
  • Loading branch information
greg0ire committed Feb 24, 2024
1 parent 859e6af commit fec57c1
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 6 deletions.
7 changes: 7 additions & 0 deletions UPGRADE.md
@@ -1,5 +1,12 @@
# Upgrade to 3.1

## Deprecate passing null to several `ClassMetadata` methods

Passing `null` to the following methods is deprecated and will no longer be possible in 4.0:

- `Doctrine\ORM\ClassMetadata::fullyQualifiedClassName()`
- `Doctrine\ORM\ClassMetadata::setCustomRepositoryClass()`

## Deprecate array access

Using array access on instances of the following classes is deprecated:
Expand Down
2 changes: 1 addition & 1 deletion psalm-baseline.xml
Expand Up @@ -489,7 +489,7 @@
<ArgumentTypeCoercion>
<code>$mapping</code>
<code><![CDATA[(string) $xmlRoot['repository-class']]]></code>
<code><![CDATA[isset($xmlRoot['repository-class']) ? (string) $xmlRoot['repository-class'] : null]]></code>
<code><![CDATA[(string) $xmlRoot['repository-class']]]></code>
</ArgumentTypeCoercion>
<InvalidArgument>
<code>$columnDef</code>
Expand Down
19 changes: 19 additions & 0 deletions src/Mapping/ClassMetadata.php
Expand Up @@ -7,6 +7,7 @@
use BackedEnum;
use BadMethodCallException;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\Deprecations\Deprecation;
use Doctrine\Instantiator\Instantiator;
use Doctrine\Instantiator\InstantiatorInterface;
use Doctrine\ORM\Cache\Exception\NonCacheableEntityAssociation;
Expand Down Expand Up @@ -2003,6 +2004,17 @@ protected function _storeAssociationMapping(AssociationMapping $assocMapping): v
*/
public function setCustomRepositoryClass(string|null $repositoryClassName): void
{
if ($repositoryClassName === null) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/11294',
'Passing null to %s is deprecated and will not be supported in Doctrine ORM 4.0',
__METHOD__,
);

$this->customRepositoryClassName = null;
}

$this->customRepositoryClassName = $this->fullyQualifiedClassName($repositoryClassName);
}

Expand Down Expand Up @@ -2475,6 +2487,13 @@ public function getAssociationMappedByTargetField(string $assocName): string
public function fullyQualifiedClassName(string|null $className): string|null
{
if ($className === null) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/11294',
'Passing null to %s is deprecated and will not be supported in Doctrine ORM 4.0',
__METHOD__,
);

return null;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Mapping/ClassMetadataFactory.php
Expand Up @@ -153,7 +153,7 @@ protected function doLoadMetadata(
$class->setCustomGeneratorDefinition($parent->customGeneratorDefinition);
}

if ($parent->isMappedSuperclass) {
if ($parent->isMappedSuperclass && $parent->customRepositoryClassName !== null) {
$class->setCustomRepositoryClass($parent->customRepositoryClassName);
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/Mapping/Driver/AttributeDriver.php
Expand Up @@ -96,7 +96,10 @@ public function loadMetadataForClass(string $className, PersistenceClassMetadata
} elseif (isset($classAttributes[Mapping\MappedSuperclass::class])) {
$mappedSuperclassAttribute = $classAttributes[Mapping\MappedSuperclass::class];

$metadata->setCustomRepositoryClass($mappedSuperclassAttribute->repositoryClass);
if ($mappedSuperclassAttribute->repositoryClass !== null) {
$metadata->setCustomRepositoryClass($mappedSuperclassAttribute->repositoryClass);
}

$metadata->isMappedSuperclass = true;
} elseif (isset($classAttributes[Mapping\Embeddable::class])) {
$metadata->isEmbeddedClass = true;
Expand Down
7 changes: 4 additions & 3 deletions src/Mapping/Driver/XmlDriver.php
Expand Up @@ -87,9 +87,10 @@ public function loadMetadataForClass($className, PersistenceClassMetadata $metad
$metadata->markReadOnly();
}
} elseif ($xmlRoot->getName() === 'mapped-superclass') {
$metadata->setCustomRepositoryClass(
isset($xmlRoot['repository-class']) ? (string) $xmlRoot['repository-class'] : null,
);
if (isset($xmlRoot['repository-class'])) {
$metadata->setCustomRepositoryClass((string) $xmlRoot['repository-class']);
}

$metadata->isMappedSuperclass = true;
} elseif ($xmlRoot->getName() === 'embeddable') {
$metadata->isEmbeddedClass = true;
Expand Down
21 changes: 21 additions & 0 deletions tests/Tests/ORM/Mapping/ClassMetadataTest.php
Expand Up @@ -6,6 +6,7 @@

use ArrayObject;
use Doctrine\DBAL\Types\Types;
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
use Doctrine\ORM\Events;
use Doctrine\ORM\Mapping\ChainTypedFieldMapper;
use Doctrine\ORM\Mapping\ClassMetadata;
Expand Down Expand Up @@ -66,6 +67,8 @@

class ClassMetadataTest extends OrmTestCase
{
use VerifyDeprecations;

public function testClassMetadataInstanceSerialization(): void
{
$cm = new ClassMetadata(CmsUser::class);
Expand Down Expand Up @@ -1052,6 +1055,24 @@ public function testItAddingLifecycleCallbackOnEmbeddedClassIsIllegal(): void

$metadata->addLifecycleCallback('foo', 'bar');
}

public function testSettingANullRepositoryClassIsDeprecated(): void
{
$metadata = new ClassMetadata(self::class);

$this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/pull/11294');

$metadata->setCustomRepositoryClass(null);
}

public function testGettingAnFQCNForNullIsDeprecated(): void
{
$metadata = new ClassMetadata(self::class);

$this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/pull/11294');

$metadata->fullyQualifiedClassName(null);
}
}

#[MappedSuperclass]
Expand Down

0 comments on commit fec57c1

Please sign in to comment.