Skip to content

Instantly share code, notes, and snippets.

@Jibbarth
Created August 27, 2023 15:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jibbarth/8df2224e9e3de25576d62164c4f4b4e6 to your computer and use it in GitHub Desktop.
Save Jibbarth/8df2224e9e3de25576d62164c4f4b4e6 to your computer and use it in GitHub Desktop.
[DOCTRINE] Automatically remove mappedSuperClass when resolveTargetEntity target the root model
<?php
declare(strict_types=1);
namespace App\Doctrine;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Tools\ResolveTargetEntityListener;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
#[AsDecorator('doctrine.orm.listeners.resolve_target_entity')]
final class ResolveTargetEntityListenerDecorator extends ResolveTargetEntityListener
{
private array $targetEntities = [];
public function __construct(private ResolveTargetEntityListener $decorated)
{
}
public function loadClassMetadata(LoadClassMetadataEventArgs $args): void
{
$this->decorated->loadClassMetadata($args);
$metadata = $args->getClassMetadata();
if (!$metadata->isMappedSuperclass) {
return;
}
$targetEntities = $this->getTargetEntities();
$targetEntities = array_reduce($targetEntities, static function (array $carry, array $item) {
$carry[] = $item['targetEntity'];
return $carry;
}, []);
// search if this class has been defined as a targetEntity.
// If so, we need to remove the MappedSuperclass flag
if (\in_array($metadata->getName(), $targetEntities, true)) {
$metadata->isMappedSuperclass = false;
}
}
private function getTargetEntities(): array
{
if ([] !== $this->targetEntities) {
return $this->targetEntities;
}
$this->targetEntities = \Closure::bind(
fn (ResolveTargetEntityListener $decorated) => $decorated->resolveTargetEntities,
null,
ResolveTargetEntityListener::class
)($this->decorated);
return $this->targetEntities;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment