From bac89fd2c5dedf6f445f7aa903408e91c0e876f3 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Thu, 23 Apr 2009 04:41:49 +0000 Subject: [PATCH] BUGFIX Setting the correct ParentID for children with existing parents in Translatable->createTranslation() - see #3861 BUGFIX Fixed Locale duplication detection for queries in Translatable->augmentSQL() git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@75027 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- core/model/Translatable.php | 17 ++++++++++++++- tests/model/TranslatableTest.php | 36 +++++++++++++++++++------------- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/core/model/Translatable.php b/core/model/Translatable.php index 2b36fce3f..b35eccf7f 100755 --- a/core/model/Translatable.php +++ b/core/model/Translatable.php @@ -441,7 +441,7 @@ class Translatable extends DataObjectDecorator { // @todo Isn't this always the case?! && array_search($baseTable, array_keys($query->from)) !== false // or we're already filtering by Lang (either from an earlier augmentSQL() call or through custom SQL filters) - && !preg_match('/("|\')Lang("|\')/', $query->getFilter()) + && !preg_match('/("|\'|`)Locale("|\'|`)/', $query->getFilter()) //&& !$query->filtersOnFK() ) { $qry = "\"Locale\" = '$lang'"; @@ -577,6 +577,8 @@ class Translatable extends DataObjectDecorator { // If page has untranslated parents, create (unpublished) translations // of those as well to avoid having inaccessible children in the sitetree. // Caution: This logic is very sensitve to infinite loops when translation status isn't determined properly + // If a parent for the newly written translation was existing before this + // onBeforeWrite() call, it will already have been linked correctly through createTranslation() if($this->owner->hasField('ParentID')) { if( !$this->owner->ID @@ -897,8 +899,21 @@ class Translatable extends DataObjectDecorator { $class = $this->owner->class; $newTranslation = new $class; + // copy all fields from owner (apart from ID) $newTranslation->update($this->owner->toMap()); + + // If the object has Hierarchy extension, + // check for existing translated parents and assign + // their ParentID (and overwrite any existing ParentID relations + // to parents in other language). If no parent translations exist, + // they are automatically created in onBeforeWrite() + if($newTranslation->hasField('ParentID')) { + $origParent = $this->owner->Parent(); + $newTranslationParent = $origParent->getTranslation($locale); + if($newTranslationParent) $newTranslation->ParentID = $newTranslationParent->ID; + } + $newTranslation->ID = 0; $newTranslation->Locale = $locale; // hacky way to set an existing translation group in onAfterWrite() diff --git a/tests/model/TranslatableTest.php b/tests/model/TranslatableTest.php index 31a6a0727..c690b851f 100644 --- a/tests/model/TranslatableTest.php +++ b/tests/model/TranslatableTest.php @@ -522,9 +522,19 @@ class TranslatableTest extends FunctionalTest { $this->assertFalse($parentPage->hasTranslation('de_DE')); $translatedGrandChildPage = $grandchildPage->createTranslation('de_DE'); + $this->assertTrue($grandchildPage->hasTranslation('de_DE')); $this->assertTrue($child1Page->hasTranslation('de_DE')); $this->assertTrue($parentPage->hasTranslation('de_DE')); + + $this->assertEquals( + $grandchildPage->getTranslation('de_DE')->Parent()->ID, + $child1Page->getTranslation('de_DE')->ID + ); + $this->assertEquals( + $child1Page->getTranslation('de_DE')->Parent()->ID, + $parentPage->getTranslation('de_DE')->ID + ); } function testHierarchyAllChildrenIncludingDeleted() { @@ -590,27 +600,22 @@ class TranslatableTest extends FunctionalTest { SiteTree::flush_and_destroy_cache(); $parentPage = $this->objFromFixture('Page', 'parent'); $this->assertEquals( - $parentPage->AllChildrenIncludingDeleted()->column('ID'), + $translatedParentPage->AllChildrenIncludingDeleted()->column('ID'), array( $child2PageTranslatedID, $child1PageTranslatedID // $child1PageTranslated was deleted from stage, so the original record doesn't have the ID set ), - "Showing AllChildrenIncludingDeleted() in translation mode with parent page in default language shows children in default language" + "Showing AllChildrenIncludingDeleted() in translation mode with parent page in translated language shows children in translated language" ); - // @todo getTranslation() doesn't switch languages for future calls, its handled statically through set_reading_locale() - // // on translated page in translation mode using getTranslation() - // SiteTree::flush_and_destroy_cache(); - // $parentPage = $this->objFromFixture('Page', 'parent'); - // $translatedParentPage = $parentPage->getTranslation('de_DE'); - // $this->assertEquals( - // $translatedParentPage->AllChildrenIncludingDeleted()->column('ID'), - // array( - // $child2PageTranslatedID, - // $child1PageTranslatedID, - // ), - // "Showing AllChildrenIncludingDeleted() in translation mode with translated parent page shows only translated children" - // ); + Translatable::set_reading_locale('de_DE'); + SiteTree::flush_and_destroy_cache(); + $parentPage = $this->objFromFixture('Page', 'parent'); + $this->assertEquals( + $parentPage->AllChildrenIncludingDeleted()->column('ID'), + array(), + "Showing AllChildrenIncludingDeleted() in translation mode with parent page in translated language shows children in default language" + ); // reset language Translatable::set_reading_locale('en_US'); @@ -650,6 +655,7 @@ class TranslatableTest extends FunctionalTest { Translatable::set_reading_locale('en_US'); $_SERVER['HTTP_HOST'] = $_originalHost; } + } class TranslatableTest_DataObject extends DataObject implements TestOnly {