Reputation: 11
I'm developing site on Symfony 2.0 and get stuck with doctrine-translations. I've been googling through Google groups, Stackoverflow, but there is no suitable answer. So first of all, I wouldn't come across all my project only needed things. First of all, I've installed doctrine-extensions then Stof. On WAMMP the sluggable started to work withoout any questions (but on Linux I had to copy and the config_dev.yml was broken). But I can't find decision how to make translatable work. So I found on Google http://gediminasm.org/article/translatable-behavior-extension-for-doctrine-2 Created the entities and translation entities.
Here goes the code:
<?php
namespace AV\TradeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Translatable\Translatable;
use Doctrine\Common\Collections\ArrayCollection;
/**
* AV\TradeBundle\Entity\Countries
*
* @ORM\Table(name="countries")
* @ORM\Entity
* @Gedmo\TranslationEntity(class="AV\TradeBundle\Entity\CountryTranslation")
*/
class Countries implements Translatable
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string $country
* @Gedmo\Translatable
* @ORM\Column(name="country", type="string", length=255, nullable=false)
*/
private $country;
/**
* @Gedmo\Locale
* Used locale to override Translation listener`s locale
* this is not a mapped field of entity metadata, just a simple property
*/
private $locale;
/**
* @ORM\OneToMany(
* targetEntity="CountryTranslation",
* mappedBy="object",
* cascade={"persist", "remove"}
* )
*/
private $translations;
public function __construct()
{
$this->translations = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set country
*
* @param string $country
*/
public function setCountry($country)
{
$this->country = $country;
}
/**
* Get country
*
* @return string
*/
public function getCountry()
{
return $this->country;
}
public function setTranslatableLocale($locale)
{
$this->locale = $locale;
}
public function getTranslations()
{
return $this->translations;
}
public function addTranslation(CountryTranslation $t)
{
if (!$this->translations->contains($t)) {
$this->translations[] = $t;
$t->setObject($this);
}
}
public function __toString() {
return $this->getCountry();
}
}
And here goes forward to aas mentioned on that blog such translation Entity
<?php
namespace AV\TradeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Translatable\Entity\MappedSuperclass\AbstractPersonalTranslation;
/**
* @ORM\Entity
* @ORM\Table(name="country_translations",
* uniqueConstraints={@ORM\UniqueConstraint(name="lookup_unique_idx", columns={
* "locale", "object_id", "field"
* })}
* )
*/
class CountryTranslation extends AbstractPersonalTranslation
{
/**
* Convinient constructor
*
* @param string $locale
* @param string $field
* @param string $value
*/
public function __construct($locale, $field, $value)
{
$this->setLocale($locale);
$this->setField($field);
$this->setContent($value);
}
/**
* @ORM\ManyToOne(targetEntity="Countries", inversedBy="translations")
* @ORM\JoinColumn(name="object_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $object;
}
?>
And finally but not the last one $em = $this->getDoctrine()->getEntityManager();
$query = $em->createQuery(
" SELECT c FROM AVTradeBundle:Companies c " .
" ORDER BY c.title ASC "
)->setHint(
\Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE,'en');
I see no translation only the default language for item (LEFT JOIN companies on countries). Maybe I should upgrade the version of Symfony to 2.1 but there a lot of bundles freezed with my 2.0.
Please do see my question. On symfony's forum there is no at all answeres.
BTW, I didn't registered any kernel listener because I use Stof. Thanks, beforehands, Alex
Upvotes: 1
Views: 8013
Reputation: 1096
You misunderstood the use of Translatable in doctrine extensions bundle. The hint you apply to the query is when you want the translations for all fields to be automatically join (so you don't have to do your LEFT JOIN), so you could use ordering filtering or whatever you want on translated fields instead of original record fields. See section "Using ORM query hint" of the translatable documentation. So by applying the hint to the query, in your case, all it does is that your country will be automatically translated in your results. Also, you provide \Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE,'en'
as hint, which means that your result will always be translated in English. I really doubt that's the behaviour you are looking for. Use
$query->setHint(
\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER,
'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker'
);
if you want your results translated in the user's locale. You only need to use \Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE
when you use apc or memcache because the queries will be cached with a first used locale. Then you need to use this hint with the current user locale and NOT always 'en'. Again, this is all in the documentation.
So if you want your translations, you need to fetch them by yourself. If you don't care about your country's name being automatically translated then don't apply the hint and do a LEFT JOIN on your country's translations (here I see that you are querying the company table, so you would have to LEFT JOIN the country first). These will be available through $country->getTranslations()
. If you apply the hint then the LEFT JOIN is implicit, but the name will be translated.
Upvotes: 3