diff --git a/code/CMSMain.php b/code/CMSMain.php
index 84478a60..b20f4009 100644
--- a/code/CMSMain.php
+++ b/code/CMSMain.php
@@ -49,7 +49,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
'rollback',
'sidereport',
'submit',
- 'switchlanguage',
'unpublish',
'versions',
'EditForm',
@@ -79,17 +78,27 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
public function init() {
parent::init();
+ // Locale" attribute is either explicitly added by LeftAndMain Javascript logic,
+ // or implied on a translated record (see {@link Translatable->updateCMSFields()}).
if(Translatable::is_enabled()) {
- $this->Lang = $this->requestParams["lang"] ? $this->requestParams["lang"] : Translatable::default_lang();
- Translatable::set_reading_lang($this->Lang);
+ // $Lang serves as a "context" which can be inspected by Translatable - hence it
+ // has the same name as the database property on Translatable.
+ if($this->getRequest()->requestVar("Locale")) {
+ $this->Locale = $this->getRequest()->requestVar("Locale");
+ } elseif($this->getRequest()->requestVar("locale")) {
+ $this->Locale = $this->getRequest()->requestVar("locale");
+ } else {
+ $this->Locale = Translatable::default_locale();
+ }
+ Translatable::set_reading_locale($this->Locale);
}
// collect languages for TinyMCE spellchecker plugin
if(Translatable::is_enabled()) {
$spellcheckLangs = Translatable::get_existing_content_languages();
} else {
- $defaultLang = Translatable::default_lang();
- $spellcheckLangs = array($defaultLang => i18n::get_language_name($defaultLang));
+ $defaultLang = Translatable::default_locale();
+ $spellcheckLangs = array($defaultLang => i18n::get_locale_name($defaultLang));
}
$spellcheckSpec = array();
foreach($spellcheckLangs as $lang => $title) $spellcheckSpec[] = "{$title}={$lang}";
@@ -348,9 +357,9 @@ JS;
}
/**
- * Get a databsae record to be managed by the CMS
+ * Get a database record to be managed by the CMS
*/
- public function getRecord($id) {
+ public function getRecord($id) {
$treeClass = $this->stat('tree_class');
@@ -453,6 +462,7 @@ JS;
if(!singleton($className)->canCreate()) return Security::permissionFailure($this);
$p = $this->getNewItem("new-$className-$parent".$suffix, false);
+ $p->Locale = $_REQUEST['Locale'];
$p->write();
return $this->returnItemToUser($p);
@@ -464,18 +474,6 @@ JS;
public function getNewItem($id, $setID = true) {
list($dummy, $className, $parentID, $suffix) = array_pad(explode('-',$id),4,null);
- if(Translatable::is_enabled()) {
- if (!Translatable::is_default_lang()) {
- $originalItem = Translatable::get_original($className,Session::get("{$id}_originalLangID"));
- if ($setID) $originalItem->ID = $id;
- else {
- $originalItem->ID = null;
- Translatable::creating_from(Session::get($id.'_originalLangID'));
- }
- return $originalItem;
- }
- }
-
$newItem = new $className();
if( !$suffix ) {
@@ -1099,14 +1097,18 @@ JS;
foreach( $this->PageTypes() as $arrayData ) {
$pageTypes[$arrayData->getField('ClassName')] = $arrayData->getField('AddAction');
}
-
- return new Form($this, "AddPageOptionsForm", new FieldSet(
+
+ $fields = new FieldSet(
new HiddenField("ParentID"),
+ new HiddenField("Locale", 'Locale', Translatable::current_locale()),
new DropdownField("PageType", "", $pageTypes, 'Page')
- ),
- new FieldSet(
+ );
+
+ $actions = new FieldSet(
new FormAction("addpage", _t('CMSMain.GO',"Go"))
- ));
+ );
+
+ return new Form($this, "AddPageOptionsForm", $fields, $actions);
}
/**
@@ -1236,107 +1238,35 @@ JS;
}
}
- /**
- * Switch the cms language and reload the site tree
- *
- */
- function switchlanguage($lang, $donotcreate = null) {
- //is it's a clean switch (to an existing language deselect the current page)
- if (is_string($lang)) $dontunloadPage = true;
- $lang = (is_string($lang) ? $lang : urldecode($this->urlParams['ID']));
- if ($lang != Translatable::default_lang()) {
- Translatable::set_reading_lang(Translatable::default_lang());
- $tree_class = $this->stat('tree_class');
- $obj = new $tree_class;
- $allIDs = $obj->getDescendantIDList();
- $allChildren = $obj->AllChildren();
- $classesMap = $allChildren->map('ID','ClassName');
- $titlesMap = $allChildren->map();
- Translatable::set_reading_lang($lang);
- $obj = new $tree_class;
- $languageIDs = $obj->getDescendantIDList();
- $notcreatedlist = array_diff($allIDs,$languageIDs);
- FormResponse::add("$('addpage').getElementsByTagName('button')[0].disabled=true;");
- //FormResponse::add("$('Form_AddPageOptionsForm').getElementsByTagName('div')[1].getElementsByTagName('input')[0].disabled=true;");
- FormResponse::add("$('Translating_Message').innerHTML = 'Translating mode - ".i18n::get_language_name($lang)."';");
- FormResponse::add("Element.removeClassName('Translating_Message','nonTranslating');");
- } else {
- Translatable::set_reading_lang($lang);
- FormResponse::add("$('addpage').getElementsByTagName('button')[0].disabled=false;");
- //FormResponse::add("$('Form_AddPageOptionsForm').getElementsByTagName('div')[1].getElementsByTagName('input')[0].disabled=false;");
- FormResponse::add("Element.addClassName('Translating_Message','nonTranslating');");
- }
- $obj = singleton($this->stat('tree_class'));
- $obj->markPartialTree();
- $siteTree = $obj->getChildrenAsUL("", '
- "
ID\" class=\"" . $child->CMSTreeClasses($extraArg) . "\">" .
- "Link(),0,-1), "show", $child->ID) . "\" " . (($child->canEdit() || $child->canAddChildren()) ? "" : "class=\"disabled\"") . " title=\"' . _t('LeftAndMain.PAGETYPE') . '".$child->class."\" >" .
- (Convert::raw2js($child->TreeTitle())) .
- ""
-'
- ,$this, true);
- $rootLink = $this->Link() . '0';
- $siteTree = "" .
- _t('LeftAndMain.SITECONTENT') . ""
- . $siteTree . "";
- FormResponse::add("$('sitetree').innerHTML ='". ereg_replace("[\n]","\\\n",$siteTree) ."';");
- FormResponse::add("SiteTree.applyTo('#sitetree');");
- if (isset($notcreatedlist)) {
- foreach ($notcreatedlist as $notcreated) {
- if ($notcreated == $donotcreate) continue;
- $id = "new-{$classesMap[$notcreated]}-0-$notcreated";
- Session::set($id . '_originalLangID',$notcreated);
- $treeTitle = Convert::raw2js($titlesMap[$notcreated]);
- $response = <<getRecord($originalLangID);
- $temporalID = "new-$record->RecordClassName-$record->ParentID-$originalLangID";
- Session::set($temporalID . '_originalLangID',$originalLangID);
- $tree = $this->switchlanguage($langCode, $originalLangID);
- FormResponse::add(<<ID = $temporalID;
+
+ $this->Locale = $langCode;
+ Translatable::set_reading_locale($langCode);
+
+ // Create a new record in the database - this is different
+ // to the usual "create page" pattern of storing the record
+ // in-memory until a "save" is performed by the user, mainly
+ // to simplify things a bit.
+ // @todo Allow in-memory creation of translations that don't persist in the database before the user requests it
+ $translatedRecord = $record->createTranslation($langCode);
- return $this->returnItemToUser($newrecord);
+ $url = sprintf(
+ "%s/%d/?locale=%s",
+ $this->Link('show'),
+ $translatedRecord->ID,
+ $langCode
+ );
+ FormResponse::add(sprintf('window.location.href = "%s";', $url));
+ return FormResponse::respond();
}
/**
@@ -1367,16 +1297,35 @@ JS
}
/**
- * Return a dropdown with existing languages
- */
- function LangSelector() {
- $langs = Translatable::get_existing_content_languages('SiteTree');
-
- return new DropdownField("LangSelector","Language",$langs,Translatable::current_lang());
- }
+ * Returns all languages with languages already used appearing first.
+ * Called by the SSViewer when rendering the template.
+ */
+ function LangSelector() {
+ $member = Member::currentUser(); //check to see if the current user can switch langs or not
+ if(Permission::checkMember($member, 'VIEW_LANGS')) {
+ $allKey = _t('Form.LANGAOTHER', "Other languages");
+ $all = i18n::get_common_locales(); //all languages
+ $used = Translatable::get_existing_content_languages(); //languages currently in use
+ if( $used && count($used) ) {
+ foreach($used as $index => $code) {
+ if(!$code) continue;
+ $available[$index] = $all[$index];
+ unset($all[$index]);
+ }
+ $langs[ _t('Form.LANGAVAIL', "Available languages") ] = (isset( $available )) ? $available : array();
+ }
+ $langs[ _t('Form.LANGAOTHER', "Other languages") ] = $all;
+ return new GroupedDropdownField('LangSelector', 'Language', $langs, Translatable::current_locale());
+ }
+
+ //user doesn't have permission to switch langs so just show a string displaying current language
+ return i18n::get_locale_name( Translatable::current_locale() );
+ }
/**
- * Determine if there are more than one languages in our site tree
+ * Determine if there are more than one languages in our site tree.
+ *
+ * @return boolean
*/
function MultipleLanguages() {
$langs = Translatable::get_existing_content_languages('SiteTree');
@@ -1384,12 +1333,19 @@ JS
return (count($langs) > 1);
}
+ /**
+ * @return boolean
+ */
+ function IsTranslatableEnabled() {
+ return Translatable::is_enabled();
+ }
+
/**
* Get the name of the language that we are translating in
*/
function EditingLang() {
- if(!Translatable::is_default_lang()) {
- return i18n::get_language_name(Translatable::current_lang());
+ if(!Translatable::is_default_locale()) {
+ return i18n::get_locale_name(Translatable::current_locale());
} else {
return false;
}
diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php
index d8d02d5d..5f7807ee 100644
--- a/code/LeftAndMain.php
+++ b/code/LeftAndMain.php
@@ -116,7 +116,7 @@ class LeftAndMain extends Controller {
// set reading lang
if(Translatable::is_enabled() && !Director::is_ajax()) {
- Translatable::choose_site_lang(array_keys(Translatable::get_existing_content_languages('SiteTree')));
+ Translatable::choose_site_locale(array_keys(Translatable::get_existing_content_languages('SiteTree')));
}
// Allow customisation of the access check by a decorator
@@ -844,16 +844,17 @@ JS;
}
public function EditForm() {
- $id = isset($_REQUEST['ID']) ? $_REQUEST['ID'] : $this->currentPageID();
-
- if(!$id) return false;
-
- if(is_numeric($id)) {
- $record = DataObject::get_by_id($this->stat('tree_class'), $id);
- if($record && !$record->canView()) return Security::permissionFailure($this);
+ if(isset($_REQUEST['ID'])) {
+ $record = DataObject::get_by_id($this->stat('tree_class'), $_REQUEST['ID']);
+ } else {
+ $record = $this->CurrentPage();
}
+
+ if(!$record) return false;
+
+ if($record && !$record->canView()) return Security::permissionFailure($this);
- return $this->getEditForm($id);
+ return $this->getEditForm($record->ID);
}
public function myprofile() {
@@ -900,7 +901,12 @@ JS;
public function currentPage() {
$id = $this->currentPageID();
if($id && is_numeric($id)) {
- return DataObject::get_by_id($this->stat('tree_class'), $id);
+ $page = DataObject::get_by_id($this->stat('tree_class'), $id);
+ if($page && Translatable::is_enabled() && $page->Locale && $page->Locale != Translatable::current_locale()) {
+ return false;
+ } else {
+ return $page;
+ }
}
}
diff --git a/css/cms_left.css b/css/cms_left.css
index 24baae3f..911e7fab 100644
--- a/css/cms_left.css
+++ b/css/cms_left.css
@@ -358,9 +358,9 @@ ul.contextMenu li a:hover {
text-decoration: none;
}
-ul.tree li.untranslated a:link,
-ul.tree li.untranslated a:hover,
-ul.tree li.untranslated a:visited {
+ul.tree span.untranslated a:link,
+ul.tree span.untranslated a:hover,
+ul.tree span.untranslated a:visited {
color: #ccc
}
@@ -458,11 +458,5 @@ ul.tree li.untranslated a:visited {
background-color: #EEEEEE;
border-bottom: 1px solid #CCCCCC;
border-top: 1px solid #CCCCCC;
- padding: 5px;
-}
-#LangSelector_holder select {
- width: 70%;
-}
-#LangSelector_holder.onelang {
- display: none;
+ padding: 3px 0 3px 7px;
}
diff --git a/css/layout.css b/css/layout.css
index 4decc024..c6832029 100644
--- a/css/layout.css
+++ b/css/layout.css
@@ -32,6 +32,10 @@ body {
#TreeActions li {
float: left;
}
+
+ #TreeActions button.disabled {
+ color: #aaa;
+ }
.ajaxActions input,
.actions input,
diff --git a/javascript/LangSelector.js b/javascript/LangSelector.js
index caad1ea5..36353082 100755
--- a/javascript/LangSelector.js
+++ b/javascript/LangSelector.js
@@ -8,19 +8,14 @@ LangSelectorClass.prototype = {
initialize: function() {
if(this.selectedIndex != 0) {
- this.showlangtree();
_TRANSLATING_LANG = this.value;
}
},
- onshow: function() {
- if(this.value) this.showlangtree();
- },
-
onchange: function(e, val) {
if(this.value != _TRANSLATING_LANG) {
_TRANSLATING_LANG = this.value;
- this.showlangtree();
+ document.location = 'admin/?locale=' + this.value;
}
},
@@ -37,17 +32,6 @@ LangSelectorClass.prototype = {
}
this.value = lang;
}
- },
-
- showlangtree: function() {
- if(this.value) {
- $('sitetree').innerHTML='
-
@@ -110,9 +112,6 @@
-
<% else %> class="onelang"<% end_if %>>
- Language: $LangSelector
-