Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement isUninitializedObject() in ObjectManagerDecorator #369

Merged
merged 1 commit into from
May 24, 2024
Merged
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
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"phpstan/phpstan-strict-rules": "^1.1",
"doctrine/coding-standard": "^12",
"doctrine/common": "^3.0",
"phpunit/phpunit": "^8.5 || ^9.5",
"phpunit/phpunit": "^8.5.38 || ^9.5",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

old versions of PHPUnit seem to struggle with @requires annotation that are included in a single-line comment.

"symfony/cache": "^4.4 || ^5.4 || ^6.0",
"vimeo/psalm": "4.30.0 || 5.24.0"
},
Expand Down
5 changes: 5 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ parameters:
count: 1
path: src/Persistence/Mapping/Driver/StaticPHPDriver.php

-
message: "#^Call to function method_exists\\(\\) with TObjectManager of Doctrine\\\\Persistence\\\\ObjectManager and 'isUninitializedObje…' will always evaluate to true\\.$#"
count: 1
path: src/Persistence/ObjectManagerDecorator.php

-
message: "#^Doctrine\\\\Persistence\\\\Reflection\\\\EnumReflectionProperty\\:\\:__construct\\(\\) does not call parent constructor from ReflectionProperty\\.$#"
count: 1
Expand Down
28 changes: 28 additions & 0 deletions src/Persistence/ObjectManagerDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@

namespace Doctrine\Persistence;

use BadMethodCallException;
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\Persistence\Mapping\ClassMetadataFactory;

use function get_class;
use function method_exists;
use function sprintf;

/**
* Base class to simplify ObjectManager decorators
*
Expand Down Expand Up @@ -82,6 +87,29 @@ public function initializeObject(object $obj)
$this->wrapped->initializeObject($obj);
}

/** @param mixed $value */
public function isUninitializedObject($value): bool
{
if (! method_exists($this->wrapped, 'isUninitializedObject')) {
$wrappedClass = get_class($this->wrapped);

throw new BadMethodCallException(sprintf(
<<<'EXCEPTION'
Context: Trying to call %s
Problem: The wrapped ObjectManager, an instance of %s does not implement this method.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__METHOD__ does also contain the FQCN. You could shorten the "instance of" Exception text if you like.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, since the FQCN at hand is not the same as the one referred to in the "Problem" part. In the context part, I say we are calling the decorator, in the problem part, I talk about the decorated class.

Solution: Implement %s::isUninitializedObject() with a signature compatible with this one:
public function isUninitializedObject(mixed $value): bool
EXCEPTION
,
__METHOD__,
$wrappedClass,
$wrappedClass
));
}

return $this->wrapped->isUninitializedObject($value);
derrabus marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* {@inheritDoc}
*/
Expand Down
32 changes: 32 additions & 0 deletions tests/Persistence/ObjectManagerDecoratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Doctrine\Tests\Persistence;

use BadMethodCallException;
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\Persistence\Mapping\ClassMetadataFactory;
use Doctrine\Persistence\ObjectManager;
Expand Down Expand Up @@ -155,6 +156,37 @@ public function testContains(): void

self::assertTrue($this->decorated->contains($object));
}

/** @requires PHP 8.0 */
public function testIsUninitializedObject(): void
{
$object = new TestObject();

$wrapped = $this->createMock(ObjectManagerV4::class);
$decorated = new NullObjectManagerDecorator($wrapped);
$wrapped->expects(self::once())
->method('isUninitializedObject')
->with($object)
->willReturn(false);

self::assertFalse($decorated->isUninitializedObject($object));
}

/** @requires PHP 8.0 */
public function testIsThrowsWhenTheWrappedObjectManagerDoesNotImplementObjectManagerV4(): void
{
$object = new TestObject();

$this->expectException(BadMethodCallException::class);
$decorated = new NullObjectManagerDecorator($this->createMock(ObjectManager::class));

self::assertFalse($decorated->isUninitializedObject($object));
}
}

interface ObjectManagerV4 extends ObjectManager
{
public function isUninitializedObject(mixed $object): bool;
}

/** @extends ObjectManagerDecorator<ObjectManager&MockObject> */
Expand Down