BUGFIX Falling back to Translatable::current_lang() if no $context object is given, in augmentAllChildrenIncludingDeleted() and AllChildrenIncludingDeleted()

MINOR phpdoc for Translatable
MINOR Added more Translatable unit tests

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@70214 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2009-01-15 05:56:25 +00:00
parent 42fd02234d
commit d5339af47c
3 changed files with 201 additions and 48 deletions

View File

@ -326,10 +326,12 @@ class Translatable extends DataObjectDecorator {
// split the method into two calls, and overwrite the wrapper AllChildrenIncludingDeleted()
// Has to be executed even with Translatable disabled, as it overwrites the method with same name
// on Hierarchy class, and routes through to Hierarchy->doAllChildrenIncludingDeleted() instead.
// Caution: There's an additional method for augmentAllChildrenIncludingDeleted()
$this->createMethod("AllChildrenIncludingDeleted",
"
\$context = (isset(\$args[0])) ? \$args[0] : null;
if(\$context && \$obj->getLang() == \$context->Lang && \$obj->isTranslation()) {
\$lang = (\$context) ? \$context : Translatable::current_lang();
if(\$obj->getLang() == \$lang && \$obj->isTranslation()) {
// if the language matches the context (e.g. CMSMain), and object is translated,
// then call method on original language instead
return \$obj->getOwner()->getOriginalPage()->doAllChildrenIncludingDeleted(\$context);
@ -702,25 +704,39 @@ class Translatable extends DataObjectDecorator {
}
}
function augmentAllChildrenIncludingDeleted(DataObjectSet $children, $context = null) {
/**
* If called with default language, doesn't affect the results.
* Otherwise (called in translation mode) the method tries to find translations
* for each page in its original language and replace the original.
* The result will contain a mixture of translated and untranslated pages.
*
* Caution: We also create a method AllChildrenIncludingDeleted() dynamically in the class constructor.
*
* @param DataObjectSet $untranslatedChildren
* @param Object $context
*/
function augmentAllChildrenIncludingDeleted(DataObjectSet $untranslatedChildren, $context = null) {
if(!Translatable::is_enabled()) return false;
$find = array();
$replace = array();
// @todo check usage of $context
if($context && $context->Lang /*&& $this->owner->Lang != $context->Lang */&& $context->Lang != Translatable::default_lang()) {
if($children) {
foreach($children as $child) {
if($child->hasTranslation($context->Lang)) {
$trans = $child->getTranslation($context->Lang);
$find[] = $child;
$replace[] = $trans;
$lang = ($context) ? $context->Lang : Translatable::current_lang();
if($lang != Translatable::default_lang()) {
if($untranslatedChildren) {
foreach($untranslatedChildren as $untranslatedChild) {
// replace original language with translation (if one is present for this language)
if($untranslatedChild->hasTranslation($lang)) {
$translatedChild = $untranslatedChild->getTranslation($lang);
$find[] = $untranslatedChild;
$replace[] = $translatedChild;
}
}
foreach($find as $i => $found) {
$children->replace($found, $replace[$i]);
$untranslatedChildren->replace($found, $replace[$i]);
}
// at this point the set contains a mixture of translated and untranslated pages
}
}

View File

@ -42,35 +42,6 @@ class TranslatableTest extends FunctionalTest {
parent::tearDown();
}
function testTranslatablePropertiesOnDataObject() {
$origObj = $this->objFromFixture('TranslatableTest_DataObject', 'testobject_en');
$translatedObj = $origObj->createTranslation('fr');
$translatedObj->TranslatableProperty = 'Fr';
$translatedObj->TranslatableDecoratedProperty = 'Fr';
$translatedObj->write();
$this->assertEquals(
$origObj->TranslatableProperty,
'En',
'Creating a translation doesnt affect database field on original object'
);
$this->assertEquals(
$origObj->TranslatableDecoratedProperty,
'En',
'Creating a translation doesnt affect decorated database field on original object'
);
$this->assertEquals(
$translatedObj->TranslatableProperty,
'Fr',
'Translated object saves database field independently of original object'
);
$this->assertEquals(
$translatedObj->TranslatableDecoratedProperty,
'Fr',
'Translated object saves decorated database field independently of original object'
);
}
function testCreateTranslationOnSiteTree() {
$origPage = $this->objFromFixture('Page', 'testpage_en');
$translatedPage = $origPage->createTranslation('de');
@ -302,11 +273,169 @@ class TranslatableTest extends FunctionalTest {
$this->assertNotNull(DataObject::get_by_id('Page', $origPage->ID));
}
/*
function testSiteTreeHierarchyTranslation() {
//$parentPage = $this->objFromFixture();
function testHierarchyAllChildrenIncludingDeleted() {
$parentPage = $this->objFromFixture('Page', 'parent');
$translatedParentPage = $parentPage->createTranslation('de');
$child1Page = $this->objFromFixture('Page', 'child1');
$child1Page->publish('Stage', 'Live');
$child1PageOrigID = $child1Page->ID;
$child1Page->delete();
$child2Page = $this->objFromFixture('Page', 'child2');
$child3Page = $this->objFromFixture('Page', 'child3');
$grandchildPage = $this->objFromFixture('Page', 'grandchild');
$child1PageTranslated = $child1Page->createTranslation('de');
$child1PageTranslated->publish('Stage', 'Live');
$child1PageTranslatedOrigID = $child1PageTranslated->ID;
$child1PageTranslated->delete();
$child2PageTranslated = $child2Page->createTranslation('de');
Translatable::set_reading_lang('en');
$this->assertEquals(
$parentPage->AllChildrenIncludingDeleted()->column('ID'),
array(
$child2Page->ID,
$child3Page->ID,
$child1PageOrigID
),
"Showing AllChildrenIncludingDeleted() in default language doesnt show deleted children in other languages"
);
$parentPage->flushCache();
Translatable::set_reading_lang('de');
$this->assertEquals(
$parentPage->AllChildrenIncludingDeleted()->column('ID'),
array(
$child2Page->ID,
$child3Page->ID,
$child1PageOrigID
),
"Showing AllChildrenIncludingDeleted() in translation mode with parent page in default language shows children in default language"
);
$this->assertEquals(
$translatedParentPage->AllChildrenIncludingDeleted()->column('ID'),
array(
$child2PageTranslated->ID,
$child1PageTranslatedOrigID,
),
"Showing AllChildrenIncludingDeleted() in translation mode with translated parent page shows only translated children"
);
// reset language
Translatable::set_reading_lang('en');
}
*/
function testHierarchyChildren() {
$parentPage = $this->objFromFixture('Page', 'parent');
$child1Page = $this->objFromFixture('Page', 'child1');
$child2Page = $this->objFromFixture('Page', 'child2');
$child3Page = $this->objFromFixture('Page', 'child3');
$grandchildPage = $this->objFromFixture('Page', 'grandchild');
$child1PageTranslated = $child1Page->createTranslation('de');
Translatable::set_reading_lang('en');
$this->assertEquals(
$parentPage->Children()->column('ID'),
array(
$child1Page->ID,
$child2Page->ID,
$child3Page->ID
),
"Showing Children() in default language doesnt show children in other languages"
);
Translatable::set_reading_lang('de');
$parentPage->flushCache();
$this->assertEquals(
$parentPage->Children()->column('ID'),
array($child1PageTranslated->ID),
"Showing Children() in translation mode doesnt show children in default languages"
);
// reset language
Translatable::set_reading_lang('en');
}
function testHierarchyLiveStageChildren() {
$parentPage = $this->objFromFixture('Page', 'parent');
$child1Page = $this->objFromFixture('Page', 'child1');
$child1Page->publish('Stage', 'Live');
$child2Page = $this->objFromFixture('Page', 'child2');
$child3Page = $this->objFromFixture('Page', 'child3');
$grandchildPage = $this->objFromFixture('Page', 'grandchild');
$child1PageTranslated = $child1Page->createTranslation('de');
$child1PageTranslated->publish('Stage', 'Live');
$child2PageTranslated = $child2Page->createTranslation('de');
Translatable::set_reading_lang('en');
$this->assertEquals(
$parentPage->liveChildren()->column('ID'),
array(
$child1Page->ID
),
"Showing liveChildren() in default language doesnt show children in other languages"
);
$this->assertEquals(
$parentPage->stageChildren()->column('ID'),
array(
$child1Page->ID,
$child2Page->ID,
$child3Page->ID
),
"Showing stageChildren() in default language doesnt show children in other languages"
);
Translatable::set_reading_lang('de');
$parentPage->flushCache();
$this->assertEquals(
$parentPage->liveChildren()->column('ID'),
array($child1PageTranslated->ID),
"Showing liveChildren() in translation mode doesnt show children in default languages"
);
$this->assertEquals(
$parentPage->stageChildren()->column('ID'),
array(
$child2PageTranslated->ID,
$child1PageTranslated->ID,
),
"Showing stageChildren() in translation mode doesnt show children in default languages"
);
// reset language
Translatable::set_reading_lang('en');
}
function testTranslatablePropertiesOnDataObject() {
$origObj = $this->objFromFixture('TranslatableTest_DataObject', 'testobject_en');
$translatedObj = $origObj->createTranslation('fr');
$translatedObj->TranslatableProperty = 'Fr';
$translatedObj->TranslatableDecoratedProperty = 'Fr';
$translatedObj->write();
$this->assertEquals(
$origObj->TranslatableProperty,
'En',
'Creating a translation doesnt affect database field on original object'
);
$this->assertEquals(
$origObj->TranslatableDecoratedProperty,
'En',
'Creating a translation doesnt affect decorated database field on original object'
);
$this->assertEquals(
$translatedObj->TranslatableProperty,
'Fr',
'Translated object saves database field independently of original object'
);
$this->assertEquals(
$translatedObj->TranslatableDecoratedProperty,
'Fr',
'Translated object saves decorated database field independently of original object'
);
}
}
class TranslatableTest_DataObject extends DataObject implements TestOnly {

View File

@ -12,14 +12,22 @@ Page:
parent:
Title: Parent
URLSegment: parent
child:
Title: Child
URLSegment: child
child1:
Title: Child 1
URLSegment: child1
Parent: =>Page.parent
child2:
Title: Child 2
URLSegment: child2
Parent: =>Page.parent
child3:
Title: Child 3
URLSegment: child3
Parent: =>Page.parent
grandchild:
Title: Grantchild
Title: Grandchild
URLSegment: grandchild
Parent: =>Page.child
Parent: =>Page.child1
TranslatableTest_DataObject:
testobject_en:
TranslatableProperty: En