FEATURE Respects 'lang' stored in cookies

ENHANCEMENT choose_site_lang() accepts $availableLang (useful to check if a certain page has a translation, and fall back to default language)
ENHANCEMENT Added documentation
BUGFIX Rewrote Member->Lang to Member->Locale (CMS-translations are stored in locales as well), limited Locale Varchar to 6 characters, changed profile dropdown accordingly

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@43659 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2007-10-21 19:53:57 +00:00
parent 3a7727d853
commit ba85ce7a0b
2 changed files with 72 additions and 31 deletions

View File

@ -1,8 +1,29 @@
<?php <?php
/** /**
* The Translatable decorator allows your DataObjects to have versions in different languages, * The {Translatable} decorator allows your DataObjects to have versions in different languages,
* defining which fields are can be translated. * defining which fields are can be translated.
*
* Common language names (e.g. 'en') are used in {Translatable} for
* database-entities. On the other hand, the file-based i18n-translations
* always have a "locale" (e.g. 'en_US').
*
* You can enable {Translatabe} for any DataObject-subclass:
* <example>
* static $extensions = array(
* "Translatable('MyTranslatableVarchar', 'OtherTranslatableText')"
* );
* </example>
*
* Caution: Does not apply any character-set conversion, it is assumed that all content
* is stored and represented in UTF-8 (Unicode). Please make sure your database and
* HTML-templates adjust to this.
*
* Caution: Further decorations of DataObject might conflict with this implementation,
* e.g. when overriding the get_one()-calls (which are already extended by {Translatable}).
*
* @author Bernat Foj Capell <bernat@silverstripe.com>
*
*/ */
class Translatable extends DataObjectDecorator { class Translatable extends DataObjectDecorator {
@ -79,21 +100,43 @@ class Translatable extends DataObjectDecorator {
/** /**
* Choose the language the site is currently on. * Choose the language the site is currently on.
* If $_GET['lang'] is set, then it will use that language, and store it in the session. * If $_GET['lang'] or $_COOKIE['lang'] is set, then it will use that language, and store it in the session.
* Otherwise it checks the session for a possible stored language. The final option is the member preference. * Otherwise it checks the session for a possible stored language. The final option is the member preference.
*
* @param $langsAvailable array A numerical array of languages which are valid choices (optional)
* @return string Selected language (also saved in $reading_lang).
*/ */
static function choose_site_lang() { static function choose_site_lang($langsAvailable = null) {
if(isset($_GET['lang'])) { if(is_array($langsAvailable)) {
$_GET['lang'] = strtolower($_GET['lang']); if(isset($_GET['lang']) && in_array(strtolower($_GET['lang']),$langsAvailable)) {
self::set_reading_lang($_GET['lang']); self::set_reading_lang($_GET['lang']);
} } elseif(isset($_COOKIE['lang']) && in_array(strtolower($_COOKIE['lang']),$langsAvailable)) {
else if($lang = Session::get('currentLang')) { self::set_reading_lang($_COOKIE['lang']);
} else if($lang = Session::get('currentLang') && in_array(strtolower($lang),$langsAvailable)) {
self::set_reading_lang($lang); self::set_reading_lang($lang);
} } else if (($member = Member::currentUser()) && ($lang = $member->Locale)
else if (($member = Member::currentUser()) && ($lang = $member->Lang)) { && in_array(strtolower($lang),$langsAvailable)
) {
self::set_reading_lang($lang); self::set_reading_lang($lang);
} else {
self::set_reading_lang(self::default_lang());
}
} else {
if(isset($_GET['lang'])) {
self::set_reading_lang($_GET['lang']);
} elseif(isset($_COOKIE['lang'])) {
self::set_reading_lang($_COOKIE['lang']);
} else if($lang = Session::get('currentLang')) {
self::set_reading_lang($lang);
} else if (($member = Member::currentUser()) && ($lang = $member->Locale)) {
self::set_reading_lang($lang);
} else {
self::set_reading_lang(self::default_lang());
}
} }
self::$language_decided = true; self::$language_decided = true;
return self::$reading_lang;
} }
/** /**
@ -110,7 +153,7 @@ class Translatable extends DataObjectDecorator {
* @paran $lang String * @paran $lang String
*/ */
static function set_default_lang($lang) { static function set_default_lang($lang) {
self::$default_lang = $lang; self::$default_lang = strtolower($lang);
} }
/** /**
@ -135,8 +178,8 @@ class Translatable extends DataObjectDecorator {
* @param string $lang New reading language. * @param string $lang New reading language.
*/ */
static function set_reading_lang($lang) { static function set_reading_lang($lang) {
Session::set('currentLang',$lang); Session::set('currentLang',strtolower($lang));
self::$reading_lang = $lang; self::$reading_lang = strtolower($lang);
} }
/** /**
@ -162,7 +205,8 @@ class Translatable extends DataObjectDecorator {
* @return DataObject * @return DataObject
*/ */
static function get_one($callerClass, $filter = "") { static function get_one($callerClass, $filter = "") {
self::$language_decided = true;self::$reading_lang = self::default_lang(); self::$language_decided = true;
self::$reading_lang = self::default_lang();
$record = DataObject::get_one($callerClass, $filter); $record = DataObject::get_one($callerClass, $filter);
if (!$record) { if (!$record) {
self::$bypass = true; self::$bypass = true;
@ -172,13 +216,7 @@ class Translatable extends DataObjectDecorator {
} else { } else {
$langsAvailable = (array)self::get_langs_by_id($callerClass, $record->ID); $langsAvailable = (array)self::get_langs_by_id($callerClass, $record->ID);
$langsAvailable[] = self::default_lang(); $langsAvailable[] = self::default_lang();
if(isset($_GET['lang']) && array_search(strtolower($_GET['lang']),$langsAvailable) !== false) { $lang = self::choose_site_lang($langsAvailable);
$lang = strtolower($_GET['lang']);
} else if(($possible = Session::get('currentLang')) && array_search($possible,$langsAvailable)) {
$lang = $possible;
} else if (($member = Member::currentUser()) && ($possible = $member->PreferredLang)) {
$lang = $possible;
}
if (isset($lang)) { if (isset($lang)) {
$transrecord = self::get_one_by_lang($callerClass, $lang, "`$callerClass`.ID = $record->ID"); $transrecord = self::get_one_by_lang($callerClass, $lang, "`$callerClass`.ID = $record->ID");
if ($transrecord) { if ($transrecord) {
@ -228,7 +266,8 @@ class Translatable extends DataObjectDecorator {
*/ */
static function get_langs_by_id($class, $id) { static function get_langs_by_id($class, $id) {
$query = new SQLQuery('Lang',"{$class}_lang","(`{$class}_lang`.OriginalLangID =$id)"); $query = new SQLQuery('Lang',"{$class}_lang","(`{$class}_lang`.OriginalLangID =$id)");
return $query->execute()->column(); $langs = $query->execute()->column();
return ($langs) ? array_values($langs) : false;
} }
/** /**
@ -358,7 +397,7 @@ class Translatable extends DataObjectDecorator {
* the original table (was renamed to _lang) since some fields that we require may be there * the original table (was renamed to _lang) since some fields that we require may be there
*/ */
if ($query->select[0][0] == '`') $query->select = array_merge(array("`$table`.*"),$query->select); if ($query->select[0][0] == '`') $query->select = array_merge(array("`$table`.*"),$query->select);
} else unset($query->from[$table]);//var_dump($query);echo'<br><br>'; } else unset($query->from[$table]);
} else { } else {
$query->from[$table] = str_replace("`{$table}`.OriginalLangID","`{$table}`.ID",$query->from[$table]); $query->from[$table] = str_replace("`{$table}`.OriginalLangID","`{$table}`.ID",$query->from[$table]);
} }

View File

@ -24,8 +24,8 @@ class Member extends DataObject {
'AutoLoginExpired' => 'Datetime', 'AutoLoginExpired' => 'Datetime',
'BlacklistedEmail' => 'Boolean', 'BlacklistedEmail' => 'Boolean',
'PasswordEncryption' => "Enum('none', 'none')", 'PasswordEncryption' => "Enum('none', 'none')",
'Salt' => "Varchar(50)", 'Salt' => 'Varchar(50)',
'Lang' => "Varchar(12)" 'Locale' => 'Varchar(6)',
); );
static $belongs_many_many = array( static $belongs_many_many = array(
@ -704,6 +704,8 @@ class Member extends DataObject {
* editing this member. * editing this member.
*/ */
public function getCMSFields() { public function getCMSFields() {
$locale = ($this->Locale) ? $this->Locale : i18n::get_locale();
$fields = new FieldSet( $fields = new FieldSet(
//new TextField("Salutation", "Title"), //new TextField("Salutation", "Title"),
new HeaderField( "Personal Details" ), new HeaderField( "Personal Details" ),
@ -711,7 +713,7 @@ class Member extends DataObject {
new TextField("Surname", "Surname"), new TextField("Surname", "Surname"),
new HeaderField( "User Details" ), new HeaderField( "User Details" ),
new TextField("Email", "Email"), new TextField("Email", "Email"),
new DropdownField("Lang", "Interface Language", i18n::get_existing_translations()), new DropdownField("Locale", "Interface Language", i18n::get_existing_translations(), $locale),
new PasswordField("Password", "Password") new PasswordField("Password", "Password")
//new TextareaField("Address","Address"), //new TextareaField("Address","Address"),
//new TextField("JobTitle", "Job Title"), //new TextField("JobTitle", "Job Title"),
@ -1026,8 +1028,8 @@ class Member_ProfileForm extends Form {
} }
} }
if($SQL_data['Lang'] != $member->Lang) { if($SQL_data['Locale'] != $member->Locale) {
$form->addErrorMessage("Generic", _t('CMSMain.REFRESHLANG'),"good"); $form->addErrorMessage("Generic", _t('Member.REFRESHLANG'),"good");
} }
$form->saveInto($member); $form->saveInto($member);