Merge remote-tracking branch 'origin/2.1'

# Conflicts:
#	.travis.yml
#	README.md
#	code/model/Translatable.php
#	composer.json
This commit is contained in:
Ingo Schommer 2015-04-30 08:51:21 +12:00
commit fcabda4188
9 changed files with 135 additions and 35 deletions

View File

@ -1,11 +1,10 @@
# Translatable module for SilverStripe CMS #
[![Build Status](https://secure.travis-ci.org/silverstripe/silverstripe-translatable.png)](http://travis-ci.org/silverstripe/silverstripe-translatable)
[![Build Status](https://secure.travis-ci.org/silverstripe/silverstripe-translatable.png?branch=2.1)](http://travis-ci.org/silverstripe/silverstripe-translatable)
## Introduction ##
Allows translation of DataObject and SiteTree records into multiple languages.
Note: This module was originally part of the SilverStripe CMS 2.x codebase.
## Usage

View File

@ -561,10 +561,10 @@ class Translatable extends DataExtension implements PermissionProvider {
if($this->owner && $this->translatableFields === null) {
$this->translatableFields = array_merge(
array_keys($this->owner->db()),
array_keys($this->owner->has_many()),
array_keys($this->owner->many_many())
array_keys($this->owner->hasMany()),
array_keys($this->owner->manyMany())
);
foreach (array_keys($this->owner->has_one()) as $fieldname) {
foreach (array_keys($this->owner->hasOne()) as $fieldname) {
$this->translatableFields[] = $fieldname.'ID';
}
}
@ -582,6 +582,30 @@ class Translatable extends DataExtension implements PermissionProvider {
return $config;
}
/**
* Check if a given SQLQuery filters on the Locale field
*
* @param SQLQuery $query
* @return boolean
*/
protected function filtersOnLocale($query) {
foreach($query->getWhere() as $condition) {
// Compat for 3.1/3.2 where syntax
if(is_array($condition)) {
// In >=3.2 each $condition is a single length array('condition' => array('params'))
reset($condition);
$condition = key($condition);
}
// >=3.2 allows conditions to be expressed as evaluatable objects
if(interface_exists('SQLConditionGroup') && ($condition instanceof SQLConditionGroup)) {
$condition = $condition->conditionSQL($params);
}
if(preg_match('/("|\'|`)Locale("|\'|`)/', $condition)) return true;
}
}
/**
* Changes any SELECT query thats not filtering on an ID
* to limit by the current language defined in {@link get_current_locale()}.
@ -666,7 +690,7 @@ class Translatable extends DataExtension implements PermissionProvider {
/**
* @todo Find more appropriate place to hook into database building
*/
function requireDefaultRecords() {
public function requireDefaultRecords() {
// @todo This relies on the Locale attribute being on the base data class, and not any subclasses
if($this->owner->class != ClassInfo::baseDataClass($this->owner->class)) return false;
@ -699,7 +723,7 @@ class Translatable extends DataExtension implements PermissionProvider {
))->column();
if(!$idsWithoutLocale) return;
if(class_exists('SiteTree') && $this->owner->class == 'SiteTree') {
if(class_exists('SiteTree') && $this->owner->class == 'SiteTree') {
foreach(array('Stage', 'Live') as $stage) {
foreach($idsWithoutLocale as $id) {
$obj = Versioned::get_one_by_stage(
@ -707,7 +731,7 @@ class Translatable extends DataExtension implements PermissionProvider {
$stage,
sprintf('"SiteTree"."ID" = %d', $id)
);
if(!$obj) continue;
if(!$obj || $obj->ObsoleteClassName) continue;
$obj->Locale = Translatable::default_locale();
@ -724,7 +748,7 @@ class Translatable extends DataExtension implements PermissionProvider {
} else {
foreach($idsWithoutLocale as $id) {
$obj = DataObject::get_by_id($this->owner->class, $id);
if(!$obj) continue;
if(!$obj || $obj->ObsoleteClassName) continue;
$obj->Locale = Translatable::default_locale();
$obj->write();
@ -1446,6 +1470,7 @@ class Translatable extends DataExtension implements PermissionProvider {
$newTranslation->ID = 0;
$newTranslation->Locale = $locale;
$newTranslation->Version = 0;
$originalPage = $this->getTranslation(self::default_locale());
if ($originalPage) {
@ -1458,7 +1483,7 @@ class Translatable extends DataExtension implements PermissionProvider {
if(Config::inst()->get('Translatable', 'enforce_global_unique_urls')) {
$newTranslation->URLSegment = $urlSegment . '-' . i18n::convert_rfc1766($locale);
}
// hacky way to set an existing translation group in onAfterWrite()
$translationGroupID = $this->getTranslationGroup();
$newTranslation->_TranslationGroupID = $translationGroupID ? $translationGroupID : $this->owner->ID;
@ -1810,11 +1835,13 @@ class Translatable extends DataExtension implements PermissionProvider {
$IDFilter = ($this->owner->ID) ? "AND \"SiteTree\".\"ID\" <> {$this->owner->ID}" : null;
$parentFilter = null;
if (Config::inst()->get('SiteTree', 'nested_urls')) {
if($this->owner->ParentID) {
$parentFilter = " AND \"SiteTree\".\"ParentID\" = {$this->owner->ParentID}";
} else {
$parentFilter = ' AND "SiteTree"."ParentID" = 0';
}
}
$existingPage = SiteTree::get()
// disable get_one cache, as this otherwise may pick up results from when locale_filter was on

View File

@ -128,6 +128,37 @@ See http://www.w3.org/International/articles/language-tags/ for a detailed descr
To ensure that your template declares the correct content language, please see [i18n](i18n#declaring_the_content_language_in_html).
### User Permissions
Permissions to view and create translations are managed through the CMS, based on security groups
defined in the "Security" section (`admin/security`). By default, all CMS users with rights to create and edit pages
can also create translations. This can be restricted by removing the "Translate into all available languages" permission,
and replacing it with language specific permissions.
You can further restrict viewing and editing rights on a specific language through the "Settings" section (`admin/settings`).
Each language has its own configuration "translation", and you can configure access to groups there.
Here's an example setup which allows content authors to write only English master content,
while translators can only write German translations, but still see readonly versions of the English master content.
Group: Administrator
* Has "Full administrative rights" permission
Group: Content Author English
* Has "View language dropdown" permission
* Has "Translate into English" permission
* Is part of "Who can edit pages?" in "Settings" for "English"
* Is part of "Who can create pages?" in "Settings" for "English"
Group: Translator German
* Has "View language dropdown" permission
* Has "Translate into German" permission
* Is part of "Who can edit pages?" in "Settings" for "German"
* Is part of "Who can create pages?" in "Settings" for "German"
### Usage
Getting a translation for an existing instance:

22
lang/eo.yml Normal file
View File

@ -0,0 +1,22 @@
eo:
CMSMain:
LANGUAGEDROPDOWNLABEL: Lingvo
CMSMain_left:
GO: Ek
Form:
LANGAOTHER: 'Aliaj lingvoj'
LANGAVAIL: 'Disponeblaj lingvoj'
Translatable:
ALLCREATED: 'Kreis ĉiujn permesitajn tradukojn.'
CREATE: 'Krei novan tradukon'
CREATEBUTTON: Krei
EXISTING: 'Ekzistantaj tradukoj'
NEWLANGUAGE: 'Nova lingvo'
NOTICENEWPAGE: 'Bonvole konservu ĉi tiun paĝon antaŭ ol krei tradukon'
TRANSLATEALLPERMISSION: 'Traduki en ĉiujn disponeblajn lingvojn'
TRANSLATEPERMISSION: 'Tradukti je %s'
TRANSLATEVIEWLANGS: 'Vidigi lingvan falliston'
TRANSLATIONS: Tradukoj
Translatable_Transform:
OriginalCheckboxLabel: 'Origina: {value}'
OriginalFieldLabel: 'Origina: {title}'

14
lang/id.yml Normal file
View File

@ -0,0 +1,14 @@
id:
CMSMain:
LANGUAGEDROPDOWNLABEL: Bahasa
CMSMain_left:
GO: Lanjut
Form:
LANGAOTHER: 'Bahasa lain'
LANGAVAIL: 'Bahasa yang tersedia'
Translatable:
CREATE: 'Buat terjemahan baru'
CREATEBUTTON: Buat
EXISTING: 'Terjemahan yang ada'
NEWLANGUAGE: 'Bahasa baru'
TRANSLATEPERMISSION: 'Terjemahan %s'

View File

@ -5,13 +5,18 @@ nl:
GO: Gaan
Form:
LANGAOTHER: 'Overige talen'
LANGAVAIL: 'Beschikbare talen'
Translatable:
ALLCREATED: 'Alle beschikbare vertalingen zijn aangemaakt'
ALLCREATED: 'Alle toegelaten vertalingen zijn aangemaakt. '
CREATE: 'Voeg nieuwe vertaling toe'
CREATEBUTTON: Toevoegen
EXISTING: 'Bestaande vertalingen'
NEWLANGUAGE: 'Nieuwe taal'
NOTICENEWPAGE: 'Sla deze pagina op voordat u een nieuwe vertaling toevoegd'
NOTICENEWPAGE: 'Sla deze pagina op voor u een nieuwe vertaling toevoegt'
TRANSLATEALLPERMISSION: 'Vertaal in alle beschikbare talen'
TRANSLATEPERMISSION: 'Vertaal %s'
TRANSLATEVIEWLANGS: 'Toon dropdown met talen'
TRANSLATIONS: Vertalingen
Translatable_Transform:
OriginalCheckboxLabel: 'Origineel: {value}'
OriginalFieldLabel: 'Originele {title}'

20
lang/pl.yml Normal file
View File

@ -0,0 +1,20 @@
pl:
CMSMain:
LANGUAGEDROPDOWNLABEL: Język
CMSMain_left:
GO: Przejdź
Form:
LANGAOTHER: 'Inne języki'
LANGAVAIL: 'Dostępne języki'
Translatable:
ALLCREATED: 'Wszystkie dozwolone tłumaczenia zostały stworzone.'
CREATE: 'Stwórz nowe tłumaczenie'
CREATEBUTTON: Stwórz
EXISTING: 'Istniejące tłumaczenia'
NEWLANGUAGE: 'Nowy język'
NOTICENEWPAGE: 'Zapisz tą stronę zanim ją przetłumaczysz'
TRANSLATEPERMISSION: 'Tłumaczenie %s'
TRANSLATIONS: Tłumaczenia
Translatable_Transform:
OriginalCheckboxLabel: 'Oryginalny: {value}'
OriginalFieldLabel: 'Oryginalny: {title}'

View File

@ -12,7 +12,11 @@ pl_PL:
CREATEBUTTON: Stwórz
EXISTING: 'Istniejące tłumaczenia'
NEWLANGUAGE: 'Nowy język'
NOTICENEWPAGE: 'Zapisz stronę przet stworzeniem tłumaczenia'
NOTICENEWPAGE: 'Zapisz stronę przed stworzeniem tłumaczenia'
TRANSLATEALLPERMISSION: 'Przetłumacz na wszystkie dostępne języki'
TRANSLATEPERMISSION: 'Tłumacz %s'
TRANSLATEVIEWLANGS: 'Pokaż listę rozwijaną języka'
TRANSLATIONS: Tłumaczenia
Translatable_Transform:
OriginalCheckboxLabel: 'Oryginalny: {value}'
OriginalFieldLabel: 'Oryginalny {title}'

View File

@ -1,22 +0,0 @@
sr@latin:
CMSMain:
LANGUAGEDROPDOWNLABEL: Jezik
CMSMain_left:
GO: Idi
Form:
LANGAOTHER: 'Drugi jezici'
LANGAVAIL: 'Raspoloživi jezici'
Translatable:
ALLCREATED: 'Svi dozvoljeni prevodi su kreirani.'
CREATE: 'Kreiraj novi prevod'
CREATEBUTTON: Kreiraj
EXISTING: 'Postojeći prevodi'
NEWLANGUAGE: 'Novi jezik'
NOTICENEWPAGE: 'Molimo Vas da pre kreiranja prevoda snimite stranicu'
TRANSLATEALLPERMISSION: 'Prevedi na sve raspoložive jezike'
TRANSLATEPERMISSION: 'Prevedi %s'
TRANSLATEVIEWLANGS: 'Pogledaj padajući meni za izbor jezika'
TRANSLATIONS: Prevodi
Translatable_Transform:
OriginalCheckboxLabel: 'Original: {value}'
OriginalFieldLabel: 'Original {title}'