Skip to content

Commit 83a4f43

Browse files
Don't include static properties in skipped properties (#2972)
* Don't include static properties in skipped properties Otherwise, `skipLazyInitialization()` is called on the reflection of static properties, resulting in an error. * Add test in ProxyFactoryTest to ensure we have the same behavior for all proxy implementations
1 parent 12ac931 commit 83a4f43

File tree

4 files changed

+53
-0
lines changed

4 files changed

+53
-0
lines changed

src/Proxy/Factory/NativeLazyObjectFactory.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ private function getSkippedProperties(ClassMetadata $metadata): array
101101
continue;
102102
}
103103

104+
if ($property->isStatic()) {
105+
continue;
106+
}
107+
104108
$skippedProperties[] = $property;
105109
}
106110

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Documents;
6+
7+
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
8+
9+
#[ODM\Document]
10+
class DocumentWithStaticProperty
11+
{
12+
#[ODM\Id]
13+
public string $id;
14+
15+
public static string $foo = 'bar';
16+
17+
// We need at least one mapped field to avoid the native lazy object to be
18+
// switched to "initialized" state immediately after setting all its properties.
19+
#[ODM\Field]
20+
public string $mappedField;
21+
}

tests/Tests/Functional/ReferencesTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Doctrine\ODM\MongoDB\Tests\BaseTestCase;
1616
use Documents\Account;
1717
use Documents\Address;
18+
use Documents\DocumentWithStaticProperty;
1819
use Documents\DocumentWithUnmappedProperties;
1920
use Documents\Group;
2021
use Documents\Phonenumber;
@@ -38,6 +39,15 @@ public function testSkipInitializationForUnmappedProperties(): void
3839
self::assertTrue($this->dm->isUninitializedObject($loadedDocument));
3940
}
4041

42+
public function testSkipInitializationForStaticProperties(): void
43+
{
44+
$loadedDocument = $this->dm->getReference(DocumentWithStaticProperty::class, '123');
45+
$this->assertInstanceOf(DocumentWithStaticProperty::class, $loadedDocument);
46+
47+
self::assertSame('bar', $loadedDocument::$foo);
48+
self::assertTrue($this->dm->isUninitializedObject($loadedDocument));
49+
}
50+
4151
public function testManyDeleteReference(): void
4252
{
4353
$user = new User();

tests/Tests/Proxy/Factory/ProxyFactoryTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Doctrine\ODM\MongoDB\Proxy\InternalProxy;
1313
use Doctrine\ODM\MongoDB\Tests\BaseTestCase;
1414
use Documents\Cart;
15+
use Documents\DocumentWithStaticProperty;
1516
use Documents\DocumentWithUnmappedProperties;
1617
use MongoDB\Client;
1718
use MongoDB\Collection;
@@ -95,6 +96,23 @@ public function testCreateProxyForDocumentWithUnmappedProperties(): void
9596

9697
self::assertSame('bar', $proxy->foo);
9798
}
99+
100+
public function testCreateProxyForDocumentWithStaticProperties(): void
101+
{
102+
$proxy = $this->dm->getReference(DocumentWithStaticProperty::class, '123');
103+
self::assertTrue(self::isLazyObject($proxy));
104+
105+
// Disable initializer so we can access properties without initialising the object
106+
if ($proxy instanceof InternalProxy) {
107+
$proxy->__setInitialized(true);
108+
} elseif ($proxy instanceof GhostObjectInterface) {
109+
$proxy->setProxyInitializer(null);
110+
} elseif ($this->dm->getConfiguration()->isNativeLazyObjectEnabled()) {
111+
$this->dm->getClassMetadata($proxy::class)->getReflectionClass()->markLazyObjectAsInitialized($proxy);
112+
}
113+
114+
self::assertSame('bar', $proxy::$foo);
115+
}
98116
}
99117

100118
class DocumentNotFoundListener

0 commit comments

Comments
 (0)