diff --git a/_config/extensions.yml b/_config/extensions.yml index 97156f5..cc60d89 100644 --- a/_config/extensions.yml +++ b/_config/extensions.yml @@ -12,4 +12,7 @@ LeftAndMain: ['TranslatableCMSMainExtension'] HtmlEditorField_Toolbar: extensions: - ['TranslatableEditorToolbarExtension'] \ No newline at end of file + ['TranslatableEditorToolbarExtension'] +DataQuery: + extensions: + ['Translatable'] diff --git a/code/model/Translatable.php b/code/model/Translatable.php index d9bfc9a..e53580a 100755 --- a/code/model/Translatable.php +++ b/code/model/Translatable.php @@ -163,6 +163,8 @@ */ class Translatable extends DataExtension implements PermissionProvider { + const QUERY_LOCALE_FILTER_ENABLED = 'Translatable.LocaleFilterEnabled'; + /** * The 'default' language. * @var string @@ -560,7 +562,7 @@ class Translatable extends DataExtension implements PermissionProvider { * * Use {@link disable_locale_filter()} to temporarily disable this "auto-filtering". */ - function augmentSQL(SQLQuery &$query) { + function augmentSQL(SQLQuery &$query, DataQuery &$dataQuery = null) { // If the record is saved (and not a singleton), and has a locale, // limit the current call to its locale. This fixes a lot of problems // with other extensions like Versioned @@ -575,6 +577,8 @@ class Translatable extends DataExtension implements PermissionProvider { $locale // unless the filter has been temporarily disabled && self::locale_filter_enabled() + // or it was disabled when the DataQuery was created + && $dataQuery->getQueryParam(self::QUERY_LOCALE_FILTER_ENABLED) // DataObject::get_by_id() should work independently of language && !$query->filtersOnID() // the query contains this table @@ -589,6 +593,11 @@ class Translatable extends DataExtension implements PermissionProvider { $query->addWhere($qry); } } + + function augmentDataQueryCreation(SQLQuery &$sqlQuery, DataQuery &$dataQuery) { + $enabled = self::locale_filter_enabled(); + $dataQuery->setQueryParam(self::QUERY_LOCALE_FILTER_ENABLED, $enabled); + } /** * Create _translation database table to enable @@ -1813,4 +1822,4 @@ class Translatable_Transformation extends FormTransformation { return $nonEditableField_holder; } -} \ No newline at end of file +} diff --git a/tests/unit/TranslatableTest.php b/tests/unit/TranslatableTest.php index eed5404..b16b950 100755 --- a/tests/unit/TranslatableTest.php +++ b/tests/unit/TranslatableTest.php @@ -40,6 +40,44 @@ class TranslatableTest extends FunctionalTest { parent::tearDown(); } + + function testLocaleFilteringEnabledAndDisabled() { + $this->assertTrue(Translatable::locale_filter_enabled()); + + // get our base page to use for testing + $origPage = $this->objFromFixture('Page', 'testpage_en'); + $origPage->MenuTitle = 'unique-key-used-in-my-query'; + $origPage->write(); + $origPage->publish('Stage', 'Live'); + + // create a translation of it so that we can see if translations are filtered + $translatedPage = $origPage->createTranslation('de_DE'); + $translatedPage->MenuTitle = $origPage->MenuTitle; + $translatedPage->write(); + $translatedPage->publish('Stage', 'Live'); + + $where = sprintf("MenuTitle = '%s'", Convert::raw2sql($origPage->MenuTitle)); + + // make sure that our query was filtered + $this->assertEquals(1, Page::get()->where($where)->count()); + + // test no filtering with disabled locale filter + Translatable::disable_locale_filter(); + $this->assertEquals(2, Page::get()->where($where)->count()); + Translatable::enable_locale_filter(); + + // make sure that our query was filtered after re-enabling the filter + $this->assertEquals(1, Page::get()->where($where)->count()); + + // test effectiveness of disabling locale filter with 3.x delayed querying + // see https://github.com/silverstripe/silverstripe-translatable/issues/113 + Translatable::disable_locale_filter(); + // create the DataList while the locale filter is disabled + $dataList = Page::get()->where($where); + Translatable::enable_locale_filter(); + // but don't use it until later - after the filter is re-enabled + $this->assertEquals(2, $dataList->count()); + } function testLocaleGetParamRedirectsToTranslation() { $origPage = $this->objFromFixture('Page', 'testpage_en');