Fluent - how to get field value in a specific locale


#1

Hi all,

Hi there,

When using Fluent module, is it possible to get a field’s value in a specific locale?

For example accessing the field as normal will return its value in the current locale:

$myPage->Title

Is there a way to specify the locale on a case-by-case basis?

$myPage->localised('Title', 'en')

I asked this question on the fluent module’s github page and was advised to do this:

$englishTitle = FluentState::singleton()->withState(function (FluentState $newState) use ($myPage) {
    $newState->setLocale('en_EN');
    return $myPage->Title;
});

but I always get the field returned in the current locale regardless.

I ended up querying the localised tables directly:

/**
 * Get the value of a DB field in a specific locale
 * 
 * Accessing a field as normal (e.g. $page->Title) will always
 * return it's value in the current locale, as set on the front-end
 *
 * @param [type] $dataObjectClass - dataobject that the field is on 
 * @param [type] $fieldName - the field name
 * @param [type] $locale - a field can have 1 value per locale
 * @return void
 */
private function getLocalisedValue($dataObjectClass, $fieldName, $locale)
{
    $tableName = Config::inst()->get($dataObjectClass, 'table_name');

    $sqlQuery = $dataObjectClass::get()->dataQuery()->query()
        ->setSelect([
            'Locale' => '"' . $tableName . '_Localised"."Locale"',
            $fieldName . 'Localised' => '"' . $tableName . '_Localised"."' . $fieldName . '"',
            $fieldName . 'Fallback' => '"' . $tableName . '"."' . $fieldName . '"',
            '"SiteTree"."Sort"'
        ])
        ->addLeftJoin($tableName . '_Localised', '"' . $tableName . '"."ID" = "' . $tableName . '_Localised"."RecordID"')
        ->setWhere(['"' . $tableName . '"."ID"' => $this->ID]);

    $fieldValue = null;
    foreach ($sqlQuery->execute() as $row) {
        if (empty($fieldValue)) {
            $fieldValue = $row[$fieldName . 'Fallback'];
        }
        if ($row['Locale'] == $locale) {
            $fieldValue = $row[$fieldName . 'Localised'];
        }
    }

    return $fieldValue;
}

But this seems pretty convoluted. Is there a better way?

Thanks,
Barry


#2

It looks like there was some follow-up to your query on there. Just so there’s a record with the question on here:

$englishTitle = FluentState::singleton()->withState(function (FluentState $newState) use ($myPageID) {
    $newState->setLocale('en_EN');
    $myPage = MyPage::get()->byID($myPageID);
    return $myPage->Title;
});

Did this revised code solve the issue for you?