Reputation: 953
i've implemented the tanslatable behaviour through entity's relationships, so i have a topic
entity with id property with a OneToMany
relation to topic_i18n
with topic_id,
lang_code and content.
Could i set a private $locale; property to topic
entity in order to make topic's entity __toString() method show the content/name or whatever from topic_i18n
entity? How could
i accomplish that?
Another doubt i have, which can be extended to any context where OneToMany
relationships happens, is when i want to insert a new topic_i18n
object i first need to create or
currently have a topic
object and then create the i18n one. I'm no experienced with entities service layers/managers but i think i could use the paradigm to be able to manage
both entities as one, but don't know how to proceed or if it's the right way to go. Could some one give a hint, opinion or something based on his experience?
Thanks in advanced!
PD:I know about doctrine behaviours bundle, but right now is not a possibility.
Upvotes: 0
Views: 291
Reputation: 8915
I think the way you did it is pretty good.
You can add/override some methods to get your i18n data, like getTitle($locale) (or get*Whatever*), which add some logic finding the good value in the topic_i18n collection.
// in your Topic class
public function getTitle()
{
return $this
->getTopicI18nCollection()
->findByLocale($this->getLocale()) // actually findByLocale does not exist, you will have to find another way, like iterating over all collection
->getTitle()
;
}
The problem with automation of __toString or others is with locale switching, or how to define the default locale to use by default.
This could be resolved using a doctrine postLoad event listener that set the current locale to any entity fetched by your EntityManager ( http://www.doctrine-project.org/docs/orm/2.1/en/reference/events.html#lifecycle-events ), using request or session information for example.
Using symfony2, it could look like this:
# app/config/config.yml
services:
postload.listener:
class: Translatable\LocaleInitializer
arguments: [@session]
tags:
- { name: doctrine.event_listener, event: postLoad }
// src/Translatable/LocaleInitalizer.php
class LocaleInitializer
{
public function __construct(Session $session)
{
$this->session = $session;
}
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if ($entity implements TranslatableInterface) { // or whatever check
$entity->setLocale($this->session->getLocale());
}
}
}
And finally, you don't have to get a topic object to create a new topic_i18n object, you can simply insert the i18n object independantly. (but you will have to refresh previously fetched collections).
Upvotes: 3