Skip to content

Commit

Permalink
[Translatable] Remove mapId() magic (#480)
Browse files Browse the repository at this point in the history
[Translatable] Remove mapId() magic
  • Loading branch information
TomasVotruba authored Jan 1, 2020
2 parents e5650d1 + 1befb48 commit b3bb9f6
Showing 1 changed file with 11 additions and 52 deletions.
63 changes: 11 additions & 52 deletions src/EventSubscriber/TranslatableSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,21 @@
namespace Knp\DoctrineBehaviors\EventSubscriber;

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Events;
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
use Doctrine\ORM\Mapping\ClassMetadataFactory;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Knp\DoctrineBehaviors\Contract\Entity\TranslatableInterface;
use Knp\DoctrineBehaviors\Contract\Entity\TranslationInterface;
use Knp\DoctrineBehaviors\Contract\Provider\LocaleProviderInterface;
use Symplify\PackageBuilder\Reflection\PrivatesCaller;

final class TranslatableSubscriber implements EventSubscriber
{
/**
* @var string
*/
public const LOCALE = 'locale';

/**
* @var int
*/
Expand All @@ -34,18 +35,11 @@ final class TranslatableSubscriber implements EventSubscriber
*/
private $localeProvider;

/**
* @var EntityManagerInterface
*/
private $entityManager;

public function __construct(
EntityManagerInterface $entityManager,
LocaleProviderInterface $localeProvider,
string $translatableFetchMode,
string $translationFetchMode
) {
$this->entityManager = $entityManager;
$this->localeProvider = $localeProvider;
$this->translatableFetchMode = $this->convertFetchString($translatableFetchMode);
$this->translationFetchMode = $this->convertFetchString($translationFetchMode);
Expand All @@ -62,13 +56,12 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataE
return;
}

if ($this->isTranslatable($classMetadata)) {
if (is_a($classMetadata->reflClass->getName(), TranslatableInterface::class, true)) {
$this->mapTranslatable($classMetadata);
}

if ($this->isTranslation($classMetadata)) {
if (is_a($classMetadata->reflClass->getName(), TranslationInterface::class, true)) {
$this->mapTranslation($classMetadata);
$this->mapId($classMetadata);
}
}

Expand Down Expand Up @@ -111,11 +104,6 @@ private function convertFetchString($fetchMode): int
}
}

private function isTranslatable(ClassMetadataInfo $classMetadataInfo): bool
{
return is_a($classMetadataInfo->reflClass->getName(), TranslatableInterface::class, true);
}

private function mapTranslatable(ClassMetadataInfo $classMetadataInfo): void
{
if ($classMetadataInfo->hasAssociation('translations')) {
Expand All @@ -125,7 +113,7 @@ private function mapTranslatable(ClassMetadataInfo $classMetadataInfo): void
$classMetadataInfo->mapOneToMany([
'fieldName' => 'translations',
'mappedBy' => 'translatable',
'indexBy' => 'locale',
'indexBy' => self::LOCALE,
'cascade' => ['persist', 'merge', 'remove'],
'fetch' => $this->translatableFetchMode,
'targetEntity' => $classMetadataInfo->getReflectionClass()->getMethod('getTranslationEntityClass')->invoke(
Expand All @@ -135,11 +123,6 @@ private function mapTranslatable(ClassMetadataInfo $classMetadataInfo): void
]);
}

private function isTranslation(ClassMetadataInfo $classMetadataInfo): bool
{
return is_a($classMetadataInfo->reflClass->getName(), TranslationInterface::class, true);
}

private function mapTranslation(ClassMetadataInfo $classMetadataInfo): void
{
if (! $classMetadataInfo->hasAssociation('translatable')) {
Expand All @@ -162,43 +145,19 @@ private function mapTranslation(ClassMetadataInfo $classMetadataInfo): void
$name = $classMetadataInfo->getTableName() . '_unique_translation';
if (! $this->hasUniqueTranslationConstraint($classMetadataInfo, $name)) {
$classMetadataInfo->table['uniqueConstraints'][$name] = [
'columns' => ['translatable_id', 'locale'],
'columns' => ['translatable_id', self::LOCALE],
];
}

if (! $classMetadataInfo->hasField('locale') && ! $classMetadataInfo->hasAssociation('locale')) {
if (! $classMetadataInfo->hasField(self::LOCALE) && ! $classMetadataInfo->hasAssociation(self::LOCALE)) {
$classMetadataInfo->mapField([
'fieldName' => 'locale',
'fieldName' => self::LOCALE,
'type' => 'string',
'length' => 5,
]);
}
}

/**
* Kept for BC-compatibility purposes : people expect this lib to map ids for
* translations.
*
* @see https://github.com/doctrine/doctrine2/blob/0bff6aadbc9f3fd8167a320d9f4f6cf269382da0/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php#L508
*/
private function mapId(ClassMetadataInfo $classMetadataInfo): void
{
// skip if already has id property
if ($classMetadataInfo->hasField('id')) {
return;
}

$builder = new ClassMetadataBuilder($classMetadataInfo);
$builder->createField('id', 'integer')
->makePrimaryKey()
->generatedValue()
->build();

$metadataFactory = $this->entityManager->getMetadataFactory();
$privatesCaller = new PrivatesCaller();
$privatesCaller->callPrivateMethod($metadataFactory, 'completeIdGeneratorMapping', $classMetadataInfo);
}

private function setLocales(LifecycleEventArgs $lifecycleEventArgs): void
{
$entity = $lifecycleEventArgs->getEntity();
Expand Down

0 comments on commit b3bb9f6

Please sign in to comment.