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
This commit is contained in:
Ingo Schommer 2009-04-23 04:41:49 +00:00
parent 16293cf1d4
commit bac89fd2c5
2 changed files with 37 additions and 16 deletions

View File

@ -441,7 +441,7 @@ class Translatable extends DataObjectDecorator {
// @todo Isn't this always the case?! // @todo Isn't this always the case?!
&& array_search($baseTable, array_keys($query->from)) !== false && 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) // 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() //&& !$query->filtersOnFK()
) { ) {
$qry = "\"Locale\" = '$lang'"; $qry = "\"Locale\" = '$lang'";
@ -577,6 +577,8 @@ class Translatable extends DataObjectDecorator {
// If page has untranslated parents, create (unpublished) translations // If page has untranslated parents, create (unpublished) translations
// of those as well to avoid having inaccessible children in the sitetree. // 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 // 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->hasField('ParentID')) {
if( if(
!$this->owner->ID !$this->owner->ID
@ -897,8 +899,21 @@ class Translatable extends DataObjectDecorator {
$class = $this->owner->class; $class = $this->owner->class;
$newTranslation = new $class; $newTranslation = new $class;
// copy all fields from owner (apart from ID) // copy all fields from owner (apart from ID)
$newTranslation->update($this->owner->toMap()); $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->ID = 0;
$newTranslation->Locale = $locale; $newTranslation->Locale = $locale;
// hacky way to set an existing translation group in onAfterWrite() // hacky way to set an existing translation group in onAfterWrite()

View File

@ -522,9 +522,19 @@ class TranslatableTest extends FunctionalTest {
$this->assertFalse($parentPage->hasTranslation('de_DE')); $this->assertFalse($parentPage->hasTranslation('de_DE'));
$translatedGrandChildPage = $grandchildPage->createTranslation('de_DE'); $translatedGrandChildPage = $grandchildPage->createTranslation('de_DE');
$this->assertTrue($grandchildPage->hasTranslation('de_DE')); $this->assertTrue($grandchildPage->hasTranslation('de_DE'));
$this->assertTrue($child1Page->hasTranslation('de_DE')); $this->assertTrue($child1Page->hasTranslation('de_DE'));
$this->assertTrue($parentPage->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() { function testHierarchyAllChildrenIncludingDeleted() {
@ -590,27 +600,22 @@ class TranslatableTest extends FunctionalTest {
SiteTree::flush_and_destroy_cache(); SiteTree::flush_and_destroy_cache();
$parentPage = $this->objFromFixture('Page', 'parent'); $parentPage = $this->objFromFixture('Page', 'parent');
$this->assertEquals( $this->assertEquals(
$parentPage->AllChildrenIncludingDeleted()->column('ID'), $translatedParentPage->AllChildrenIncludingDeleted()->column('ID'),
array( array(
$child2PageTranslatedID, $child2PageTranslatedID,
$child1PageTranslatedID // $child1PageTranslated was deleted from stage, so the original record doesn't have the ID set $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() Translatable::set_reading_locale('de_DE');
// // on translated page in translation mode using getTranslation() SiteTree::flush_and_destroy_cache();
// SiteTree::flush_and_destroy_cache(); $parentPage = $this->objFromFixture('Page', 'parent');
// $parentPage = $this->objFromFixture('Page', 'parent'); $this->assertEquals(
// $translatedParentPage = $parentPage->getTranslation('de_DE'); $parentPage->AllChildrenIncludingDeleted()->column('ID'),
// $this->assertEquals( array(),
// $translatedParentPage->AllChildrenIncludingDeleted()->column('ID'), "Showing AllChildrenIncludingDeleted() in translation mode with parent page in translated language shows children in default language"
// array( );
// $child2PageTranslatedID,
// $child1PageTranslatedID,
// ),
// "Showing AllChildrenIncludingDeleted() in translation mode with translated parent page shows only translated children"
// );
// reset language // reset language
Translatable::set_reading_locale('en_US'); Translatable::set_reading_locale('en_US');
@ -650,6 +655,7 @@ class TranslatableTest extends FunctionalTest {
Translatable::set_reading_locale('en_US'); Translatable::set_reading_locale('en_US');
$_SERVER['HTTP_HOST'] = $_originalHost; $_SERVER['HTTP_HOST'] = $_originalHost;
} }
} }
class TranslatableTest_DataObject extends DataObject implements TestOnly { class TranslatableTest_DataObject extends DataObject implements TestOnly {