Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jobs:
- "8.2"
- "8.3"
- "8.4"
- "8.5"
dbal-version:
- "default"
extension:
Expand Down Expand Up @@ -115,6 +116,7 @@ jobs:
- "8.2"
- "8.3"
- "8.4"
- "8.5"
dbal-version:
- "default"
- "3@dev"
Expand Down Expand Up @@ -189,6 +191,7 @@ jobs:
- "8.2"
- "8.3"
- "8.4"
- "8.5"
dbal-version:
- "default"
- "3@dev"
Expand Down Expand Up @@ -260,6 +263,7 @@ jobs:
- "8.2"
- "8.3"
- "8.4"
- "8.5"
dbal-version:
- "default"
- "3@dev"
Expand Down
103 changes: 103 additions & 0 deletions src/Mapping/ClassMetadataInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,109 @@
return $serialized;
}

public function __serialize(): array

Check failure on line 1067 in src/Mapping/ClassMetadataInfo.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (PHP: 8.4)

Method \Doctrine\ORM\Mapping\ClassMetadataInfo::__serialize() does not have @return annotation for its traversable return value.
{
// This metadata is always serialized/cached.
$serialized = [
'associationMappings' => $this->associationMappings,
'columnNames' => $this->columnNames, //TODO: 3.0 Remove this. Can use fieldMappings[$fieldName]['columnName']

Check failure on line 1072 in src/Mapping/ClassMetadataInfo.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (2.13, default)

Access to deprecated property $columnNames of class Doctrine\ORM\Mapping\ClassMetadataInfo: 3.0 Remove this.

Check failure on line 1072 in src/Mapping/ClassMetadataInfo.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, default)

Access to deprecated property $columnNames of class Doctrine\ORM\Mapping\ClassMetadataInfo: 3.0 Remove this.

Check failure on line 1072 in src/Mapping/ClassMetadataInfo.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, 2.5)

Access to deprecated property $columnNames of class Doctrine\ORM\Mapping\ClassMetadataInfo: 3.0 Remove this.
'fieldMappings' => $this->fieldMappings,
'fieldNames' => $this->fieldNames,
'embeddedClasses' => $this->embeddedClasses,
'identifier' => $this->identifier,
'isIdentifierComposite' => $this->isIdentifierComposite, // TODO: REMOVE
'name' => $this->name,
'namespace' => $this->namespace, // TODO: REMOVE
'table' => $this->table,
'rootEntityName' => $this->rootEntityName,
'idGenerator' => $this->idGenerator, //TODO: Does not really need to be serialized. Could be moved to runtime.
];

// The rest of the metadata is only serialized if necessary.
if ($this->changeTrackingPolicy !== self::CHANGETRACKING_DEFERRED_IMPLICIT) {
$serialized['changeTrackingPolicy'] = $this->changeTrackingPolicy;
}

if ($this->customRepositoryClassName) {
$serialized['customRepositoryClassName'] = $this->customRepositoryClassName;
}

if ($this->inheritanceType !== self::INHERITANCE_TYPE_NONE) {
$serialized['inheritanceType'] = $this->inheritanceType;

Check failure on line 1095 in src/Mapping/ClassMetadataInfo.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (PHP: 8.4)

Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space
$serialized['discriminatorColumn'] = $this->discriminatorColumn;
$serialized['discriminatorValue'] = $this->discriminatorValue;

Check failure on line 1097 in src/Mapping/ClassMetadataInfo.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (PHP: 8.4)

Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space
$serialized['discriminatorMap'] = $this->discriminatorMap;

Check failure on line 1098 in src/Mapping/ClassMetadataInfo.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (PHP: 8.4)

Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space
$serialized['parentClasses'] = $this->parentClasses;

Check failure on line 1099 in src/Mapping/ClassMetadataInfo.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (PHP: 8.4)

Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space
$serialized['subClasses'] = $this->subClasses;

Check failure on line 1100 in src/Mapping/ClassMetadataInfo.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (PHP: 8.4)

Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space
}

if ($this->generatorType !== self::GENERATOR_TYPE_NONE) {
$serialized['generatorType'] = $this->generatorType;
if ($this->generatorType === self::GENERATOR_TYPE_SEQUENCE) {
$serialized['sequenceGeneratorDefinition'] = $this->sequenceGeneratorDefinition;
}
}

if ($this->isMappedSuperclass) {
$serialized['isMappedSuperclass'] = $this->isMappedSuperclass;
}

if ($this->isEmbeddedClass) {
$serialized['isEmbeddedClass'] = $this->isEmbeddedClass;
}

if ($this->containsForeignIdentifier) {
$serialized['containsForeignIdentifier'] = $this->containsForeignIdentifier;
}

if ($this->containsEnumIdentifier) {
$serialized['containsEnumIdentifier'] = $this->containsEnumIdentifier;
}

if ($this->isVersioned) {
$serialized['isVersioned'] = $this->isVersioned;

Check failure on line 1127 in src/Mapping/ClassMetadataInfo.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (PHP: 8.4)

Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space
$serialized['versionField'] = $this->versionField;
}

if ($this->lifecycleCallbacks) {
$serialized['lifecycleCallbacks'] = $this->lifecycleCallbacks;
}

if ($this->entityListeners) {
$serialized['entityListeners'] = $this->entityListeners;
}

if ($this->namedQueries) {
$serialized['namedQueries'] = $this->namedQueries;
}

if ($this->namedNativeQueries) {
$serialized['namedNativeQueries'] = $this->namedNativeQueries;
}

if ($this->sqlResultSetMappings) {
$serialized['sqlResultSetMappings'] = $this->sqlResultSetMappings;
}

if ($this->isReadOnly) {
$serialized['isReadOnly'] = $this->isReadOnly;
}

if ($this->customGeneratorDefinition) {
$serialized['customGeneratorDefinition'] = $this->customGeneratorDefinition;
}

if ($this->cache) {
$serialized['cache'] = $this->cache;
}

if ($this->requiresFetchAfterChange) {
$serialized['requiresFetchAfterChange'] = $this->requiresFetchAfterChange;
}

return $serialized;
}

/**
* Creates a new instance of the mapped class, without invoking the constructor.
*
Expand Down
8 changes: 8 additions & 0 deletions src/PersistentCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,14 @@
return ['collection', 'initialized'];
}

public function __serialize(): array

Check failure on line 591 in src/PersistentCollection.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (PHP: 8.4)

Method \Doctrine\ORM\PersistentCollection::__serialize() does not have @return annotation for its traversable return value.
{
return [
'collection' => $this->collection,
'initialized' => $this->initialized,
];
}

/**
* Extracts a slice of $length elements starting at position $offset from the Collection.
*
Expand Down
2 changes: 1 addition & 1 deletion src/Persisters/Entity/JoinedSubclassPersister.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ protected function getDiscriminatorColumnTableName()
*/
private function getVersionedClassMetadata(): ClassMetadata
{
if (isset($this->class->fieldMappings[$this->class->versionField]['inherited'])) {
if ($this->class->versionField !== null && isset($this->class->fieldMappings[$this->class->versionField]['inherited'])) {
$definingClassName = $this->class->fieldMappings[$this->class->versionField]['inherited'];

return $this->em->getClassMetadata($definingClassName);
Expand Down
21 changes: 21 additions & 0 deletions src/Query/Exec/AbstractSqlExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,20 @@
}, array_keys((array) $this)), ['_sqlStatements']));
}

public function __serialize(): array

Check failure on line 95 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (PHP: 8.4)

Method \Doctrine\ORM\Query\Exec\AbstractSqlExecutor::__serialize() does not have @return annotation for its traversable return value.
{
$properties = array_values(array_diff(array_map(static function (string $prop): string {
return str_replace("\0*\0", '', $prop);
}, array_keys((array) $this)), ['_sqlStatements']));
$serialized = [];

foreach ($properties as $property) {
$serialized[$property] = $this->$property;
}

return $serialized;
}

public function __wakeup(): void
{
// @phpstan-ignore property.deprecated
Expand All @@ -103,4 +117,11 @@
// @phpstan-ignore property.deprecated
$this->_sqlStatements = &$this->sqlStatements;
}

public function __unserialize(array $data): void

Check failure on line 121 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (2.13, default)

Method Doctrine\ORM\Query\Exec\AbstractSqlExecutor::__unserialize() has parameter $data with no value type specified in iterable type array.

Check failure on line 121 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, default)

Method Doctrine\ORM\Query\Exec\AbstractSqlExecutor::__unserialize() has parameter $data with no value type specified in iterable type array.

Check failure on line 121 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, 2.5)

Method Doctrine\ORM\Query\Exec\AbstractSqlExecutor::__unserialize() has parameter $data with no value type specified in iterable type array.

Check failure on line 121 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (PHP: 8.4)

Method \Doctrine\ORM\Query\Exec\AbstractSqlExecutor::__unserialize() does not have @param annotation for its traversable parameter $data.
{
foreach ($data as $property => $value) {
$this->$property = $value;
}
}
}
4 changes: 3 additions & 1 deletion src/Tools/Pagination/LimitSubqueryOutputWalker.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ private function rebuildOrderByForRowNumber(SelectStatement $AST): void
$selectAliasToExpressionMap = [];
// Get any aliases that are available for select expressions.
foreach ($AST->selectClause->selectExpressions as $selectExpression) {
$selectAliasToExpressionMap[$selectExpression->fieldIdentificationVariable] = $selectExpression->expression;
if (is_string($selectExpression->fieldIdentificationVariable)) {
$selectAliasToExpressionMap[$selectExpression->fieldIdentificationVariable] = $selectExpression->expression;
}
}

// Rebuild string orderby expressions to use the select expression they're referencing
Expand Down
9 changes: 7 additions & 2 deletions tests/Tests/ORM/Cache/DefaultCacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

use function array_merge;

use const PHP_VERSION_ID;

/** @group DDC-2183 */
class DefaultCacheTest extends OrmTestCase
{
Expand Down Expand Up @@ -244,8 +246,11 @@ public function testToIdentifierArrayShouldLookupForEntityIdentifier(): void
$method = new ReflectionMethod($this->cache, 'toIdentifierArray');
$property = new ReflectionProperty($entity, 'id');

$property->setAccessible(true);
$method->setAccessible(true);
if (PHP_VERSION_ID < 80100) {
$property->setAccessible(true);
$method->setAccessible(true);
}

$property->setValue($entity, $identifier);

self::assertEquals(['id' => $identifier], $method->invoke($this->cache, $metadata, $identifier));
Expand Down
6 changes: 5 additions & 1 deletion tests/Tests/ORM/Cache/DefaultQueryCacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
use function microtime;
use function sprintf;

use const PHP_VERSION_ID;

/** @group DDC-2183 */
class DefaultQueryCacheTest extends OrmTestCase
{
Expand Down Expand Up @@ -585,7 +587,9 @@ public function testGetAssociationValue(): void
$rsm = new ResultSetMappingBuilder($this->em);
$key = new QueryCacheKey('query.key1', 0);

$reflection->setAccessible(true);
if (PHP_VERSION_ID < 80100) {
$reflection->setAccessible(true);
}

$germany = new Country('Germany');
$bavaria = new State('Bavaria', $germany);
Expand Down
15 changes: 12 additions & 3 deletions tests/Tests/ORM/Cache/FileLockRegionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use function unlink;

use const E_WARNING;
use const PHP_VERSION_ID;

/**
* @extends RegionTestCase<FileLockRegion>
Expand All @@ -46,7 +47,9 @@ private function getFileName(FileLockRegion $region, CacheKey $key): string
{
$reflection = new ReflectionMethod($region, 'getLockFileName');

$reflection->setAccessible(true);
if (PHP_VERSION_ID < 80100) {
$reflection->setAccessible(true);
}

return $reflection->invoke($region, $key);
}
Expand Down Expand Up @@ -227,7 +230,10 @@ public function testLockLifetime(): void
$file = $this->getFileName($this->region, $key);
$property = new ReflectionProperty($this->region, 'lockLifetime');

$property->setAccessible(true);
if (PHP_VERSION_ID < 80100) {
$property->setAccessible(true);
}

$property->setValue($this->region, -10);

self::assertFalse($this->region->contains($key));
Expand All @@ -253,7 +259,10 @@ public function testHandlesScanErrorsGracefullyOnEvictAll(): void
$region = $this->createRegion();
$reflectionDirectory = new ReflectionProperty($region, 'directory');

$reflectionDirectory->setAccessible(true);
if (PHP_VERSION_ID < 80100) {
$reflectionDirectory->setAccessible(true);
}

$reflectionDirectory->setValue($region, str_repeat('a', 10000));

set_error_handler(static function (): bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use Doctrine\Tests\Models\Cache\State;
use ReflectionProperty;

use const PHP_VERSION_ID;

/** @group DDC-2183 */
class ReadWriteCachedCollectionPersisterTest extends CollectionPersisterTestCase
{
Expand Down Expand Up @@ -121,7 +123,9 @@ public function testTransactionRollBackDeleteShouldClearQueue(): void
$key = new CollectionCacheKey(State::class, 'cities', ['id' => 1]);
$property = new ReflectionProperty(ReadWriteCachedCollectionPersister::class, 'queuedCache');

$property->setAccessible(true);
if (PHP_VERSION_ID < 80100) {
$property->setAccessible(true);
}

$this->region->expects(self::once())
->method('lock')
Expand Down Expand Up @@ -153,7 +157,9 @@ public function testTransactionRollBackUpdateShouldClearQueue(): void
$key = new CollectionCacheKey(State::class, 'cities', ['id' => 1]);
$property = new ReflectionProperty(ReadWriteCachedCollectionPersister::class, 'queuedCache');

$property->setAccessible(true);
if (PHP_VERSION_ID < 80100) {
$property->setAccessible(true);
}

$this->region->expects(self::once())
->method('lock')
Expand Down Expand Up @@ -185,7 +191,9 @@ public function testTransactionRollCommitDeleteShouldClearQueue(): void
$key = new CollectionCacheKey(State::class, 'cities', ['id' => 1]);
$property = new ReflectionProperty(ReadWriteCachedCollectionPersister::class, 'queuedCache');

$property->setAccessible(true);
if (PHP_VERSION_ID < 80100) {
$property->setAccessible(true);
}

$this->region->expects(self::once())
->method('lock')
Expand Down Expand Up @@ -217,7 +225,9 @@ public function testTransactionRollCommitUpdateShouldClearQueue(): void
$key = new CollectionCacheKey(State::class, 'cities', ['id' => 1]);
$property = new ReflectionProperty(ReadWriteCachedCollectionPersister::class, 'queuedCache');

$property->setAccessible(true);
if (PHP_VERSION_ID < 80100) {
$property->setAccessible(true);
}

$this->region->expects(self::once())
->method('lock')
Expand Down Expand Up @@ -248,7 +258,9 @@ public function testDeleteLockFailureShouldIgnoreQueue(): void
$key = new CollectionCacheKey(State::class, 'cities', ['id' => 1]);
$property = new ReflectionProperty(ReadWriteCachedCollectionPersister::class, 'queuedCache');

$property->setAccessible(true);
if (PHP_VERSION_ID < 80100) {
$property->setAccessible(true);
}

$this->region->expects(self::once())
->method('lock')
Expand All @@ -273,7 +285,9 @@ public function testUpdateLockFailureShouldIgnoreQueue(): void
$key = new CollectionCacheKey(State::class, 'cities', ['id' => 1]);
$property = new ReflectionProperty(ReadWriteCachedCollectionPersister::class, 'queuedCache');

$property->setAccessible(true);
if (PHP_VERSION_ID < 80100) {
$property->setAccessible(true);
}

$this->region->expects(self::once())
->method('lock')
Expand Down
Loading
Loading