1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
<?php
declare(strict_types=1);
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
use Doctrine\ORM\Mapping\MappingException;
use Doctrine\Tests\Models\PropertyHooks\MappingVirtualProperty;
use Doctrine\Tests\Models\PropertyHooks\User;
use Doctrine\Tests\OrmFunctionalTestCase;
use PHPUnit\Framework\Attributes\RequiresPhp;
#[RequiresPhp('>= 8.4.0')]
class PropertyHooksTest extends OrmFunctionalTestCase
{
protected function setUp(): void
{
parent::setUp();
if ($this->_em->getConnection()->getDatabasePlatform() instanceof AbstractMySQLPlatform) {
self::markTestSkipped('MySQL/MariaDB is case-insensitive by default, and the logic of this test relies on case sensitivity.');
}
if (! $this->_em->getConfiguration()->isNativeLazyObjectsEnabled()) {
$this->markTestSkipped('Property hooks require native lazy objects to be enabled.');
}
$this->createSchemaForModels(
User::class,
);
}
public function testMapPropertyHooks(): void
{
$user = new User();
$user->fullName = 'John Doe';
$user->language = 'EN';
$this->_em->persist($user);
$this->_em->flush();
$this->_em->clear();
$user = $this->_em->find(User::class, $user->id);
self::assertEquals('John', $user->first);
self::assertEquals('Doe', $user->last);
self::assertEquals('John Doe', $user->fullName);
self::assertEquals('EN', $user->language, 'The property hook uppercases the language.');
$language = $this->_em->createQuery('SELECT u.language FROM ' . User::class . ' u WHERE u.id = :id')
->setParameter('id', $user->id)
->getSingleScalarResult();
$this->assertEquals('en', $language, 'Selecting a field from DQL does not go through the property hook, accessing raw data.');
$this->_em->clear();
$user = $this->_em->getRepository(User::class)->findOneBy(['language' => 'EN']);
self::assertNull($user);
$user = $this->_em->getRepository(User::class)->findOneBy(['language' => 'en']);
self::assertNotNull($user);
}
public function testTriggerLazyLoadingWhenAccessingPropertyHooks(): void
{
$user = new User();
$user->fullName = 'Ludwig von Beethoven';
$user->language = 'DE';
$this->_em->persist($user);
$this->_em->flush();
$this->_em->clear();
$user = $this->_em->getReference(User::class, $user->id);
$this->assertTrue($this->_em->getUnitOfWork()->isUninitializedObject($user));
self::assertEquals('Ludwig', $user->first);
self::assertEquals('von Beethoven', $user->last);
self::assertEquals('Ludwig von Beethoven', $user->fullName);
self::assertEquals('DE', $user->language, 'The property hook uppercases the language.');
$this->assertFalse($this->_em->getUnitOfWork()->isUninitializedObject($user));
$this->_em->clear();
$user = $this->_em->getReference(User::class, $user->id);
self::assertEquals('Ludwig von Beethoven', $user->fullName);
}
public function testMappingVirtualPropertyIsNotSupported(): void
{
$this->expectException(MappingException::class);
$this->expectExceptionMessage('Mapping virtual property "fullName" on entity "Doctrine\Tests\Models\PropertyHooks\MappingVirtualProperty" is not allowed.');
$this->_em->getClassMetadata(MappingVirtualProperty::class);
}
}
|