From ca24365c6fac12762724f0db11da45ddff3d17a7 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Mon, 27 Apr 2009 05:57:11 +0000 Subject: [PATCH] BUGFIX Fixed Translatable->onBeforeWrite() to change ClassNames on all translations when the "master page" (default language) changes its class to avoid inconsistencies with saving translations (see #3487) BUGFIX Correctly showing the available languages dropdown in Translatable->getCMSFields() git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@75249 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- core/model/Translatable.php | 31 +++++++++++++++++++------------ tests/model/TranslatableTest.php | 30 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/core/model/Translatable.php b/core/model/Translatable.php index b35eccf7f..61eea69fa 100755 --- a/core/model/Translatable.php +++ b/core/model/Translatable.php @@ -602,6 +602,23 @@ class Translatable extends DataObjectDecorator { } } + // Has to be limited to the default locale, the assumption is that the "page type" + // dropdown is readonly on all translations. + if($this->owner->ID && $this->owner->Locale == Translatable::default_locale()) { + $changedFields = $this->owner->getChangedFields(); + if(isset($changedFields['ClassName'])) { + $this->owner->ClassName = $changedFields['ClassName']['before']; + $translations = $this->owner->getTranslations(); + $this->owner->ClassName = $changedFields['ClassName']['after']; + if($translations) foreach($translations as $translation) { + $translation->setClassName($this->owner->ClassName); + $translation = $translation->newClassInstance($translation->ClassName); + $translation->forceChange(); + $translation->write(); + } + } + } + // see onAfterWrite() if(!$this->owner->ID) { $this->owner->_TranslatableIsNewRecord = true; @@ -730,20 +747,10 @@ class Translatable extends DataObjectDecorator { // Show a dropdown to create a new translation. // This action is possible both when showing the "default language" - // and a translation. + // and a translation. Include the current locale (record might not be saved yet). $alreadyTranslatedLangs = $this->getTranslatedLangs(); + $alreadyTranslatedLangs[$this->owner->Locale] = $this->owner->Locale; - // We'd still want to show the default lang though, - // as records in this language might have NULL values in their $Lang property - // and otherwise wouldn't show up here - //$alreadyTranslatedLangs[Translatable::default_locale()] = i18n::get_locale_name(Translatable::default_locale()); - - // Exclude the current language from being shown. - if(Translatable::current_locale() != Translatable::default_locale()) { - $currentLangKey = array_search(Translatable::current_locale(), $alreadyTranslatedLangs); - if($currentLangKey) unset($alreadyTranslatedLangs[$currentLangKey]); - } - $fields->addFieldsToTab( 'Root', new Tab(_t('Translatable.TRANSLATIONS', 'Translations'), diff --git a/tests/model/TranslatableTest.php b/tests/model/TranslatableTest.php index c690b851f..fcad087b6 100644 --- a/tests/model/TranslatableTest.php +++ b/tests/model/TranslatableTest.php @@ -655,6 +655,36 @@ class TranslatableTest extends FunctionalTest { Translatable::set_reading_locale('en_US'); $_SERVER['HTTP_HOST'] = $_originalHost; } + + function testSiteTreeChangePageTypeInMaster() { + // create original + $origPage = new SiteTree(); + $origPage->Locale = 'en_US'; + $origPage->write(); + $origPageID = $origPage->ID; + + // create translation + $translatedPage = $origPage->createTranslation('de_DE'); + $translatedPageID = $translatedPage->ID; + + // change page type + $origPage->ClassName = 'RedirectorPage'; + $origPage->write(); + + // re-fetch original page with new instance + $origPageChanged = DataObject::get_by_id('RedirectorPage', $origPageID); + $this->assertEquals($origPageChanged->ClassName, 'RedirectorPage', + 'A ClassName change to an original page doesnt change original classname' + ); + + // re-fetch the translation with new instance + Translatable::set_reading_locale('de_DE'); + $translatedPageChanged = DataObject::get_by_id('RedirectorPage', $translatedPageID); + $translatedPageChanged = $origPageChanged->getTranslation('de_DE'); + $this->assertEquals($translatedPageChanged->ClassName, 'RedirectorPage', + 'ClassName change on an original page also changes ClassName attribute of translation' + ); + } }