Open mpdude opened 7 months ago
Thank you for the wonderful library.
I am now refactoring an application where the primary language of the entity is stored in different entity (😐) and this issue is a blocker for me to use this nice library. I was thinking of two approaches to this. Just ideas and I would like to discuss them before implementing them.
DynamicLocaleEntity
(just placeholder name for now)DynamicLocaleEntity
and has attribute at same timeDynamicLocaleEntity
in TranslatableClassMetadata::injectNewPersistentTranslatables
getLocale()
value instead the attribute value
interface DynamicLocaleEntity
{
public function getLocale(): string;
}
public function injectNewPersistentTranslatables(object $entity, EntityManager $entityManager, DefaultLocaleProvider $defaultLocaleProvider): void
{
foreach ($this->translatedProperties as $fieldName => $property) {
$persistentTranslatable = new PersistentTranslatable(
$entityManager->getUnitOfWork(),
$this->class,
$entity,
// Handle case of missing #[Locale] attribute while no being instance of DynamicLocaleEntity
$entity instanceof DynamicLocaleEntity ? $entity->getLocale() : $this->primaryLocale,
$defaultLocaleProvider,
$this->translationFieldMapping[$fieldName],
$this->translationsCollectionProperty,
$this->translationClass,
$this->translationLocaleProperty,
$this->translationMappingProperty,
$property,
$this->logger
);
$persistentTranslatable->inject();
}
}
Questions:
Is the Locale attribute needed? The getLocale()
could return literal string.
method
and property
to Locale
attributeprimaryLocale
, method
or property
is definedprimaryLocaleMethod
and primaryLocaleProperty
properties to TranslatableClassMetadata
Include logic for fetching the primaryLocale to injectNewPersistentTranslatables
#[Entity]
#[Locale(method: 'getEventLanguage')]
class Event
{
public function getEventLanguage(): string
{
return $this->...
}
}
#[Entity]
#[Locale(property: 'locale')]
class Event
{
public string $locale;
}
public function injectNewPersistentTranslatables(object $entity, EntityManager $entityManager, DefaultLocaleProvider $defaultLocaleProvider): void
{
// More robust error handling needed to include reason and how to fixit → Method Event::getLocale() does not exist. Implement it or check if method specified in attribute #[Locale] of App\Entity\Event exists.
$entityLocale = match (true) {
$this->primaryLocale !== null => $this->primaryLocale,
$this->primaryLocaleMethod !== null => call_user_func([$entity, 'primaryLocaleMethod']),
$this->primaryLocaleProperty !== null => $entity->{$this->primaryLocaleProperty},
default => throw new LogicException('...'), // Should be checked by the Locale attribute
};
foreach ($this->translatedProperties as $fieldName => $property) {
$persistentTranslatable = new PersistentTranslatable(
$entityManager->getUnitOfWork(),
$this->class,
$entity,
$entityLocale,
$defaultLocaleProvider,
$this->translationFieldMapping[$fieldName],
$this->translationsCollectionProperty,
$this->translationClass,
$this->translationLocaleProperty,
$this->translationMappingProperty,
$property,
$this->logger
);
$persistentTranslatable->inject();
}
}
Pro: more versatile and useful. Does not pollute every translatable entity with interface implementation Con: calling method/getting property based on a string is a bit yikes and it may be very error-prone (would it not be nice if PHP supported first class callable syntax in attributes? 😁).
Questions:
Which of these two approaches would have better chance of getting merged if i were to implement it? Am I missing something critical @mpdude ?
Thank you!
For now, each entity class has one fixed primary locale, expressed through the
Locale
attribute.We have encountered cases in which some records were only available in a language different from the primary locale.
Therefore, it would be nice if we could remove the primary locale attribute and retrieve this information from a property, on a per-entity instance level. This would allow every entity instance to define its own primary locale.