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() // 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 // 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. // on Hierarchy class, and routes through to Hierarchy->doAllChildrenIncludingDeleted() instead.
// Caution: There's an additional method for augmentAllChildrenIncludingDeleted()
$this->createMethod("AllChildrenIncludingDeleted", $this->createMethod("AllChildrenIncludingDeleted",
" "
\$context = (isset(\$args[0])) ? \$args[0] : null; \$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, // if the language matches the context (e.g. CMSMain), and object is translated,
// then call method on original language instead // then call method on original language instead
return \$obj->getOwner()->getOriginalPage()->doAllChildrenIncludingDeleted(\$context); 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; if(!Translatable::is_enabled()) return false;
$find = array(); $find = array();
$replace = array(); $replace = array();
// @todo check usage of $context // @todo check usage of $context
if($context && $context->Lang /*&& $this->owner->Lang != $context->Lang */&& $context->Lang != Translatable::default_lang()) { $lang = ($context) ? $context->Lang : Translatable::current_lang();
if($children) { if($lang != Translatable::default_lang()) {
foreach($children as $child) { if($untranslatedChildren) {
if($child->hasTranslation($context->Lang)) { foreach($untranslatedChildren as $untranslatedChild) {
$trans = $child->getTranslation($context->Lang); // replace original language with translation (if one is present for this language)
$find[] = $child; if($untranslatedChild->hasTranslation($lang)) {
$replace[] = $trans; $translatedChild = $untranslatedChild->getTranslation($lang);
$find[] = $untranslatedChild;
$replace[] = $translatedChild;
} }
} }
foreach($find as $i => $found) { 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(); 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() { function testCreateTranslationOnSiteTree() {
$origPage = $this->objFromFixture('Page', 'testpage_en'); $origPage = $this->objFromFixture('Page', 'testpage_en');
$translatedPage = $origPage->createTranslation('de'); $translatedPage = $origPage->createTranslation('de');
@ -302,11 +273,169 @@ class TranslatableTest extends FunctionalTest {
$this->assertNotNull(DataObject::get_by_id('Page', $origPage->ID)); $this->assertNotNull(DataObject::get_by_id('Page', $origPage->ID));
} }
/* function testHierarchyAllChildrenIncludingDeleted() {
function testSiteTreeHierarchyTranslation() { $parentPage = $this->objFromFixture('Page', 'parent');
//$parentPage = $this->objFromFixture(); $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 { class TranslatableTest_DataObject extends DataObject implements TestOnly {

View File

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