Let's say you have a class Title, and the title is translated in multiple languages using TitleTranslation classes.
To indicate which language the title is translated in, each translation has a Locale value object.
For readability, I am attempting to provide the Title class with a getTitle(Locale $locale) method, returning the correct translation.
The easy way to do this would be to loop over all translations, and check each translation's locale.
However, I would like to accomplish this using Criteria, so only a single TitleTranslation will be fetched and hydrated.
To illustrate the case, a simplified version of the classes I'm working with:
Title:
/** @ORM\Entity @ORM\Table */
class Title
{
/**
* @ORM\OneToMany(targetEntity="TitleTranslation", mappedBy="element")
*/
private $translations;
}
TitleTranslation:
/** @ORM\Entity @ORM\Table */
class TitleTranslation
{
/**
* @ORM\ManyToOne(targetEntity="Title", inversedBy="translations")
*/
private $title;
/**
* @ORM\Column(type="string")
*/
private $translation;
/**
* @ORM\Embedded(class="Locale")
*/
private $locale;
public function getTranslation() : string
{
return $this->translation;
}
}
Locale:
/** @Embeddable */
class Locale
{
/** @ORM\Column(type="string")
private $locale;
public function __toString()
{
return $this->locale;
}
}
I have made the following attempts, all of which are unsuccessful:
public function getTitle(Locale $locale)
{
$localeCriteria = Criteria::create()->where(Criteria::expr()->eq('locale', $locale));
/** @var TitleTranslation | bool $translation */
$translation = $this->translations->matching($translationCriteria)->first();
return $translation ? $translation->getTranslation() : null;
}
This approach fails with an ORMException "Unrecognized field: locale", which seems normal, as Embeddables should be queried as "locale.locale" (field in containing class.field in VO).
However, using this notation:
$localeCriteria = Criteria::create()->where(Criteria::expr()->eq('locale.locale', $locale));
Fails with Undefined property: TitleTranslation::$locale.locale
Am I missing something, or is this approach simply not possible?