Skip to content

Commit

Permalink
Merge pull request #11745 from greg0ire/3.4.x
Browse files Browse the repository at this point in the history
Merge 3.3.x up into 3.4.x
  • Loading branch information
greg0ire authored Dec 3, 2024
2 parents 0a635c1 + 6c70d11 commit 5d73458
Show file tree
Hide file tree
Showing 19 changed files with 247 additions and 31 deletions.
9 changes: 7 additions & 2 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Upgrade to 3.4

Using the same class several times in a discriminator map is deprecated.
In 4.0, this will be an error.

# Upgrade to 3.3

## Deprecate `DatabaseDriver`
Expand Down Expand Up @@ -747,7 +752,7 @@ Use `toIterable()` instead.

Output walkers should implement the new `\Doctrine\ORM\Query\OutputWalker` interface and create
`Doctrine\ORM\Query\Exec\SqlFinalizer` instances instead of `Doctrine\ORM\Query\Exec\AbstractSqlExecutor`s.
The output walker must not base its workings on the query `firstResult`/`maxResult` values, so that the
The output walker must not base its workings on the query `firstResult`/`maxResult` values, so that the
`SqlFinalizer` can be kept in the query cache and used regardless of the actual `firstResult`/`maxResult` values.
Any operation dependent on `firstResult`/`maxResult` should take place within the `SqlFinalizer::createExecutor()`
method. Details can be found at https://github.com/doctrine/orm/pull/11188.
Expand All @@ -760,7 +765,7 @@ change in behavior.

Progress on this is tracked at https://github.com/doctrine/orm/issues/11624 .

## PARTIAL DQL syntax is undeprecated
## PARTIAL DQL syntax is undeprecated

Use of the PARTIAL keyword is not deprecated anymore in DQL, because we will be
able to support PARTIAL objects with PHP 8.4 Lazy Objects and
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"doctrine/inflector": "^1.4 || ^2.0",
"doctrine/instantiator": "^1.3 || ^2",
"doctrine/lexer": "^3",
"doctrine/persistence": "^3.3.1",
"doctrine/persistence": "^3.3.1 || ^4",
"psr/cache": "^1 || ^2 || ^3",
"symfony/console": "^5.4 || ^6.0 || ^7.0",
"symfony/var-exporter": "^6.3.9 || ^7.0"
Expand Down
1 change: 1 addition & 0 deletions docs/en/tutorials/extra-lazy-associations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ can be called without triggering a full load of the collection:
- ``Collection#contains($entity)``
- ``Collection#containsKey($key)``
- ``Collection#count()``
- ``Collection#first()``
- ``Collection#get($key)``
- ``Collection#isEmpty()``
- ``Collection#slice($offset, $length = null)``
Expand Down
2 changes: 2 additions & 0 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
</rule>

<rule ref="PSR1.Classes.ClassDeclaration.MultipleClasses">
<exclude-pattern>src/Mapping/Driver/LoadMappingFileImplementation.php</exclude-pattern>
<exclude-pattern>src/Mapping/GetReflectionClassImplementation.php</exclude-pattern>
<exclude-pattern>tests/*</exclude-pattern>
</rule>

Expand Down
7 changes: 6 additions & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ parameters:
path: src/EntityManager.php

-
message: "#^Method Doctrine\\\\ORM\\\\EntityManager\\:\\:isUninitializedObject\\(\\) has parameter \\$obj with no type specified\\.$#"
message: "#^Method Doctrine\\\\ORM\\\\EntityManager\\:\\:isUninitializedObject\\(\\) has parameter \\$value with no type specified\\.$#"
count: 1
path: src/EntityManager.php

Expand Down Expand Up @@ -755,6 +755,11 @@ parameters:
count: 4
path: src/Mapping/ClassMetadata.php

-
message: "#^If condition is always true\\.$#"
count: 1
path: src/Mapping/ClassMetadata.php

-
message: "#^Method Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata\\:\\:inlineEmbeddable\\(\\) has parameter \\$embeddable with generic class Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata but does not specify its types\\: T$#"
count: 1
Expand Down
5 changes: 5 additions & 0 deletions phpstan-dbal3.neon
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ parameters:
message: '~deprecated class Doctrine\\DBAL\\Tools\\Console\\Command\\ReservedWordsCommand\:~'
path: src/Tools/Console/ConsoleRunner.php

# Compatibility with Persistence 3
-
message: '#Expression on left side of \?\? is not nullable.#'
path: src/Mapping/Driver/AttributeDriver.php

-
message: '~^Method Doctrine\\ORM\\Persisters\\Entity\\BasicEntityPersister\:\:getArrayBindingType\(\) never returns .* so it can be removed from the return type\.$~'
path: src/Persisters/Entity/BasicEntityPersister.php
Expand Down
5 changes: 5 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ parameters:
message: '#Negated boolean expression is always false\.#'
paths:
- src/Mapping/Driver/AttributeDriver.php

# Compatibility with Persistence 3
-
message: '#Expression on left side of \?\? is not nullable.#'
path: src/Mapping/Driver/AttributeDriver.php
23 changes: 17 additions & 6 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -298,15 +298,9 @@
<code><![CDATA[$mapping]]></code>
<code><![CDATA[$overrideMapping]]></code>
</InvalidArgument>
<InvalidNullableReturnType>
<code><![CDATA[ReflectionClass|null]]></code>
</InvalidNullableReturnType>
<InvalidPropertyAssignmentValue>
<code><![CDATA[$definition]]></code>
</InvalidPropertyAssignmentValue>
<NullableReturnStatement>
<code><![CDATA[$this->reflClass]]></code>
</NullableReturnStatement>
<ParamNameMismatch>
<code><![CDATA[$entity]]></code>
</ParamNameMismatch>
Expand Down Expand Up @@ -340,6 +334,7 @@
<RedundantCondition>
<code><![CDATA[$mapping !== false]]></code>
<code><![CDATA[$mapping !== false]]></code>
<code><![CDATA[$this->reflClass]]></code>
</RedundantCondition>
<RedundantFunctionCall>
<code><![CDATA[array_values]]></code>
Expand Down Expand Up @@ -474,6 +469,14 @@
<code><![CDATA[getIndexes]]></code>
</PossiblyNullReference>
</file>
<file src="src/Mapping/Driver/LoadMappingFileImplementation.php">
<LessSpecificImplementedReturnType>
<code><![CDATA[array]]></code>
</LessSpecificImplementedReturnType>
<MissingParamType>
<code><![CDATA[$file]]></code>
</MissingParamType>
</file>
<file src="src/Mapping/Driver/SimplifiedXmlDriver.php">
<MissingParamType>
<code><![CDATA[$fileExtension]]></code>
Expand Down Expand Up @@ -526,6 +529,14 @@
<code><![CDATA[$metadata]]></code>
</MoreSpecificImplementedParamType>
</file>
<file src="src/Mapping/GetReflectionClassImplementation.php">
<ImplementedReturnTypeMismatch>
<code><![CDATA[ReflectionClass]]></code>
</ImplementedReturnTypeMismatch>
<InvalidNullableReturnType>
<code><![CDATA[ReflectionClass]]></code>
</InvalidNullableReturnType>
</file>
<file src="src/Mapping/ManyToManyInverseSideMapping.php">
<PropertyNotSetInConstructor>
<code><![CDATA[ManyToManyInverseSideMapping]]></code>
Expand Down
4 changes: 2 additions & 2 deletions src/EntityManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -565,9 +565,9 @@ public function initializeObject(object $obj): void
/**
* {@inheritDoc}
*/
public function isUninitializedObject($obj): bool
public function isUninitializedObject($value): bool
{
return $this->unitOfWork->isUninitializedObject($obj);
return $this->unitOfWork->isUninitializedObject($value);
}

public function getFilters(): FilterCollection
Expand Down
32 changes: 22 additions & 10 deletions src/Mapping/ClassMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@
use Stringable;

use function array_column;
use function array_count_values;
use function array_diff;
use function array_filter;
use function array_flip;
use function array_intersect;
use function array_key_exists;
use function array_keys;
Expand All @@ -39,6 +42,7 @@
use function defined;
use function enum_exists;
use function explode;
use function implode;
use function in_array;
use function interface_exists;
use function is_string;
Expand Down Expand Up @@ -73,6 +77,8 @@
*/
class ClassMetadata implements PersistenceClassMetadata, Stringable
{
use GetReflectionClassImplementation;

/* The inheritance mapping types */
/**
* NONE means the class does not participate in an inheritance hierarchy
Expand Down Expand Up @@ -932,16 +938,6 @@ public function validateLifecycleCallbacks(ReflectionService $reflService): void
}
}

/**
* {@inheritDoc}
*
* Can return null when using static reflection, in violation of the LSP
*/
public function getReflectionClass(): ReflectionClass|null
{
return $this->reflClass;
}

/** @psalm-param array{usage?: mixed, region?: mixed} $cache */
public function enableCache(array $cache): void
{
Expand Down Expand Up @@ -2190,6 +2186,22 @@ final public function getDiscriminatorColumn(): DiscriminatorColumnMapping
*/
public function setDiscriminatorMap(array $map): void
{
if (count(array_flip($map)) !== count($map)) {
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/issues/3519',
<<<'DEPRECATION'
Mapping a class to multiple discriminator values is deprecated,
and the discriminator mapping of %s contains duplicate values
for the following discriminator values: %s.
DEPRECATION,
$this->name,
implode(', ', array_keys(array_filter(array_count_values($map), static function (int $value): bool {
return $value > 1;
}))),
);
}

foreach ($map as $value => $className) {
$this->addDiscriminatorMapClass($value, $className);
}
Expand Down
35 changes: 35 additions & 0 deletions src/Mapping/Driver/LoadMappingFileImplementation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace Doctrine\ORM\Mapping\Driver;

use Doctrine\Persistence\Mapping\StaticReflectionService;

use function class_exists;

if (! class_exists(StaticReflectionService::class)) {
/** @internal */
trait LoadMappingFileImplementation
{
/**
* {@inheritDoc}
*/
protected function loadMappingFile($file): array
{
return $this->doLoadMappingFile($file);
}
}
} else {
/** @internal */
trait LoadMappingFileImplementation
{
/**
* {@inheritDoc}
*/
protected function loadMappingFile($file)
{
return $this->doLoadMappingFile($file);
}
}
}
8 changes: 4 additions & 4 deletions src/Mapping/Driver/XmlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
*/
class XmlDriver extends FileDriver
{
use LoadMappingFileImplementation;

public const DEFAULT_FILE_EXTENSION = '.dcm.xml';

/**
Expand Down Expand Up @@ -878,10 +880,8 @@ private function getCascadeMappings(SimpleXMLElement $cascadeElement): array
return $cascades;
}

/**
* {@inheritDoc}
*/
protected function loadMappingFile($file)
/** @return array<class-string, SimpleXMLElement> */
private function doLoadMappingFile(string $file): array
{
$this->validateMapping($file);
$result = [];
Expand Down
33 changes: 33 additions & 0 deletions src/Mapping/GetReflectionClassImplementation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Doctrine\ORM\Mapping;

use Doctrine\Persistence\Mapping\StaticReflectionService;
use ReflectionClass;

use function class_exists;

if (! class_exists(StaticReflectionService::class)) {
trait GetReflectionClassImplementation
{
public function getReflectionClass(): ReflectionClass
{
return $this->reflClass;
}
}
} else {
trait GetReflectionClassImplementation
{
/**
* {@inheritDoc}
*
* Can return null when using static reflection, in violation of the LSP
*/
public function getReflectionClass(): ReflectionClass|null
{
return $this->reflClass;
}
}
}
14 changes: 14 additions & 0 deletions src/PersistentCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,20 @@ public function __wakeup(): void
$this->em = null;
}

/**
* {@inheritDoc}
*/
public function first()
{
if (! $this->initialized && ! $this->isDirty && $this->getMapping()->fetch === ClassMetadata::FETCH_EXTRA_LAZY) {
$persister = $this->getUnitOfWork()->getCollectionPersister($this->getMapping());

return array_values($persister->slice($this, 0, 1))[0] ?? false;
}

return parent::first();
}

/**
* Extracts a slice of $length elements starting at position $offset from the Collection.
*
Expand Down
8 changes: 8 additions & 0 deletions tests/Performance/Mock/NonProxyLoadingEntityManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,12 @@ public function contains(object $object): bool
{
return $this->realEntityManager->contains($object);
}

/**
* {@inheritDoc}
*/
public function isUninitializedObject($value): bool
{
return $this->realEntityManager->isUninitializedObject($value);
}
}
6 changes: 3 additions & 3 deletions tests/Tests/Mocks/MetadataDriverMock.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,22 @@ class MetadataDriverMock implements MappingDriver
/**
* {@inheritDoc}
*/
public function loadMetadataForClass($className, ClassMetadata $metadata)
public function loadMetadataForClass($className, ClassMetadata $metadata): void
{
}

/**
* {@inheritDoc}
*/
public function isTransient($className)
public function isTransient($className): bool
{
return false;
}

/**
* {@inheritDoc}
*/
public function getAllClassNames()
public function getAllClassNames(): array
{
return [];
}
Expand Down
Loading

0 comments on commit 5d73458

Please sign in to comment.