Skip to content

Commit

Permalink
[Mapping] Fix inherited classes metadata collection (#2651)
Browse files Browse the repository at this point in the history
* fix: use isTransient to assert that class should have been loaded

* Update changelog

* Move changelog statement around

* Fix coding standard issue

* Update tests/Gedmo/Mapping/MappingEventSubscriberTest.php

* Update tests/Gedmo/Mapping/MappingEventSubscriberTest.php

---------

Co-authored-by: Gaël Reyrol <me@gaelreyrol.dev>
Co-authored-by: Fran Moreno <franmomu@gmail.com>
  • Loading branch information
3 people committed Aug 19, 2023
1 parent 4fd6a62 commit 351caed
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ a release.
### Changed
- Add conflict with "doctrine/orm" >=2.16 (temporary change until code is fixed)

### Fixed
- Fix bug collecting metadata for inherited mapped classes

## [3.12.0] - 2023-07-08
### Added
- Tree: `setSibling()` and `getSibling()` methods in the `Node` interface through the BC `@method` annotation
Expand Down
2 changes: 1 addition & 1 deletion src/Mapping/ExtensionMetadataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public function getExtensionMetadata($meta)
if (null !== $meta->reflClass) {
foreach (array_reverse(class_parents($meta->getName())) as $parentClass) {
// read only inherited mapped classes
if ($cmf->hasMetadataFor($parentClass)) {
if ($cmf->hasMetadataFor($parentClass) || !$cmf->isTransient($parentClass)) {
assert(class_exists($parentClass));

$class = $this->objectManager->getClassMetadata($parentClass);
Expand Down
54 changes: 54 additions & 0 deletions tests/Gedmo/Mapping/Fixture/MappedSuperClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Doctrine Behavioral Extensions package.
* (c) Gediminas Morkevicius <gediminas.morkevicius@gmail.com> http://www.gediminasm.org
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Gedmo\Tests\Mapping\Fixture;

use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Tests\Mapping\Mock\Extension\Encoder\Mapping as Ext;

/**
* @ORM\MappedSuperclass
*/
#[ORM\MappedSuperclass]
class MappedSuperClass
{
/**
* @var int|null
*
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: Types::INTEGER)]
private $id;

/**
* @var string|null
*
* @ORM\Column(length=32)
* @Ext\Encode(type="md5")
*/
#[ORM\Column(length: 32)]
private $content;

public function setContent(?string $content): void
{
$this->content = $content;
}

public function getContent(): ?string
{
return $this->content;
}
}
39 changes: 39 additions & 0 deletions tests/Gedmo/Mapping/Fixture/SuperClassExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Doctrine Behavioral Extensions package.
* (c) Gediminas Morkevicius <gediminas.morkevicius@gmail.com> http://www.gediminasm.org
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Gedmo\Tests\Mapping\Fixture;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
*/
#[ORM\Entity]
class SuperClassExtension extends MappedSuperClass
{
/**
* @var string|null
*
* @ORM\Column(length=128)
*/
#[ORM\Column(length: 128)]
private $title;

public function setTitle(?string $title): void
{
$this->title = $title;
}

public function getTitle(): ?string
{
return $this->title;
}
}
52 changes: 51 additions & 1 deletion tests/Gedmo/Mapping/MappingEventSubscriberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
use Gedmo\Mapping\ExtensionMetadataFactory;
use Gedmo\Sluggable\SluggableListener;
use Gedmo\Tests\Mapping\Fixture\Sluggable;
use Gedmo\Tests\Mapping\Fixture\SuperClassExtension;
use Gedmo\Tests\Mapping\Mock\Extension\Encoder\EncoderListener;
use Gedmo\Tests\SoftDeleteable\Fixture\Entity\MappedSuperclass;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;

final class MappingEventSubscriberTest extends ORMMappingTestCase
{
Expand All @@ -44,7 +48,7 @@ protected function setUp(): void
$this->em = EntityManager::create($conn, $config, new EventManager());
}

public function testGetMetadataFactoryCacheFromDoctrine(): void
public function testGetMetadataFactoryCacheFromDoctrineForSluggable(): void
{
$metadataFactory = $this->em->getMetadataFactory();
$getCache = \Closure::bind(static function (AbstractClassMetadataFactory $metadataFactory): ?CacheItemPoolInterface {
Expand All @@ -64,10 +68,56 @@ public function testGetMetadataFactoryCacheFromDoctrine(): void
static::assertTrue($cache->hasItem($cacheKey));
}

public function testGetMetadataFactoryCacheFromDoctrineForSuperClassExtension(): void
{
$metadataFactory = $this->em->getMetadataFactory();
$getCache = \Closure::bind(static function (AbstractClassMetadataFactory $metadataFactory): ?CacheItemPoolInterface {
return $metadataFactory->getCache();
}, null, \get_class($metadataFactory));

/** @var CacheItemPoolInterface $cache */
$cache = $getCache($metadataFactory);

$cacheKey = ExtensionMetadataFactory::getCacheId(SuperClassExtension::class, 'Gedmo\Tests\Mapping\Mock\Extension\Encoder');

static::assertFalse($cache->hasItem($cacheKey));

$subscriber = new EncoderListener();
$classMetadata = $this->em->getClassMetadata(SuperClassExtension::class);

$config = $subscriber->getExtensionMetadataFactory($this->em)->getExtensionMetadata($classMetadata);

static::assertSame([
'content' => [
'type' => 'md5',
'secret' => null,
],
], $config['encode']);

// Create new configuration to use new array cache
$config = $this->getBasicConfiguration();
$config->setMetadataDriverImpl(new AnnotationDriver(new AnnotationReader()));
$config->setMetadataCache(new ArrayAdapter());
$this->em = EntityManager::create([
'driver' => 'pdo_sqlite',
'memory' => true,
], $config, new EventManager());

$config = $subscriber->getExtensionMetadataFactory($this->em)->getExtensionMetadata($classMetadata);

static::assertSame([
'content' => [
'type' => 'md5',
'secret' => null,
],
], $config['encode']);
}

protected function getUsedEntityFixtures(): array
{
return [
Sluggable::class,
MappedSuperclass::class,
];
}
}

0 comments on commit 351caed

Please sign in to comment.