From 610874755cecfaa5a93d45be8258159785666d9d Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Tue, 15 May 2012 17:50:04 +0200 Subject: [PATCH] BUGFIX 3.0 compatibility: Query manipulation, CMS links, separation of settings fields, new place for language selector on tree --- .../TranslatableCMSMainExtension.php | 34 ++- code/model/Translatable.php | 196 +++++++++--------- css/CMSMain.Translatable.css | 14 ++ javascript/CMSMain.Translatable.js | 38 ++-- tests/unit/TranslatableSearchFormTest.php | 9 +- tests/unit/TranslatableSiteConfigTest.php | 2 +- tests/unit/TranslatableTest.php | 12 +- 7 files changed, 166 insertions(+), 139 deletions(-) diff --git a/code/controller/TranslatableCMSMainExtension.php b/code/controller/TranslatableCMSMainExtension.php index df5c0ac..a07d4cd 100644 --- a/code/controller/TranslatableCMSMainExtension.php +++ b/code/controller/TranslatableCMSMainExtension.php @@ -14,10 +14,14 @@ class TranslatableCMSMainExtension extends Extension { // $Lang serves as a "context" which can be inspected by Translatable - hence it // has the same name as the database property on Translatable. $req = $this->owner->getRequest(); + $id = $req->param('ID'); if($req->requestVar("Locale")) { $this->owner->Locale = $req->requestVar("Locale"); } elseif($req->requestVar("locale")) { $this->owner->Locale = $req->requestVar("locale"); + } else if($id && is_numeric($id)) { + $record = DataObject::get_by_id($this->owner->stat('tree_class'), $id); + if($record && $record->Locale) $this->owner->Locale = $record->Locale; } else { $this->owner->Locale = Translatable::default_locale(); } @@ -46,14 +50,15 @@ class TranslatableCMSMainExtension extends Extension { /** * Create a new translation from an existing item, switch to this language and reload the tree. */ - function createtranslation($request) { + function createtranslation($data, $form) { + $request = $this->owner->getRequest(); + // Protect against CSRF on destructive action if(!SecurityToken::inst()->checkRequest($request)) return $this->owner->httpError(400); - $langCode = Convert::raw2sql($request->getVar('newlang')); - $originalLangID = (int)$request->getVar('ID'); - - $record = $this->owner->getRecord($originalLangID); + $langCode = Convert::raw2sql($request->postVar('NewTransLang')); + $record = $this->owner->getRecord($request->postVar('ID')); + if(!$record) return $this->httpError(404); $this->owner->Locale = $langCode; Translatable::set_current_locale($langCode); @@ -67,13 +72,25 @@ class TranslatableCMSMainExtension extends Extension { $url = sprintf( "%s/%d/?locale=%s", - $this->owner->Link('show'), + singleton('CMSPageEditController')->Link('show'), $translatedRecord->ID, $langCode ); return Director::redirect($url); } + + function updateLink(&$link) { + if($this->owner->Locale) $link = Controller::join_links($link, '?locale=' . $this->owner->Locale); + } + + function updateLinkWithSearch(&$link) { + if($this->owner->Locale) $link = Controller::join_links($link, '?locale=' . $this->owner->Locale); + } + + function updateExtraTreeTools(&$html) { + $html = $this->LangForm()->forTemplate() . $html; + } /** * Returns a form with all languages with languages already used appearing first. @@ -104,14 +121,15 @@ class TranslatableCMSMainExtension extends Extension { $form = new Form( $this->owner, 'LangForm', - new FieldSet( + new FieldList( $field ), - new FieldSet( + new FieldList( new FormAction('selectlang', _t('CMSMain_left.ss.GO','Go')) ) ); $form->unsetValidator(); + $form->addExtraClass('nostyle'); return $form; } diff --git a/code/model/Translatable.php b/code/model/Translatable.php index b1b6f4d..f23d125 100755 --- a/code/model/Translatable.php +++ b/code/model/Translatable.php @@ -516,7 +516,7 @@ class Translatable extends DataExtension implements PermissionProvider { } } - function extraStatics() { + function extraStatics($class = null, $extension = null) { return array( "db" => array( "Locale" => "DBLocale", @@ -542,7 +542,6 @@ class Translatable extends DataExtension implements PermissionProvider { // with other extensions like Versioned $locale = ($this->owner->ID && $this->owner->Locale) ? $this->owner->Locale : Translatable::get_current_locale(); $baseTable = ClassInfo::baseDataClass($this->owner->class); - $where = $query->where; if( $locale // unless the filter has been temporarily disabled @@ -551,13 +550,13 @@ class Translatable extends DataExtension implements PermissionProvider { && !$query->filtersOnID() // the query contains this table // @todo Isn't this always the case?! - && array_search($baseTable, array_keys($query->from)) !== false + && array_search($baseTable, array_keys($query->getFrom())) !== false // or we're already filtering by Lang (either from an earlier augmentSQL() call or through custom SQL filters) - && !preg_match('/("|\'|`)Locale("|\'|`)/', $query->getFilter()) + && !preg_match('/("|\'|`)Locale("|\'|`)/', implode(' ', $query->getWhere())) //&& !$query->filtersOnFK() ) { $qry = sprintf('"%s"."Locale" = \'%s\'', $baseTable, Convert::raw2sql($locale)); - $query->where[] = $qry; + $query->addWhere($qry); } } @@ -900,92 +899,15 @@ class Translatable extends DataExtension implements PermissionProvider { * readonly fields, so you can translation INTO the "default language" while * seeing readonly fields as well. */ - function updateCMSFields(FieldSet &$fields) { - if(!class_exists('SiteTree')) return; - // Don't apply these modifications for normal DataObjects - they rely on CMSMain logic - if(!($this->owner instanceof SiteTree)) return; - - // used in CMSMain->init() to set language state when reading/writing record - $fields->push(new HiddenField("Locale", "Locale", $this->owner->Locale) ); - - // Don't allow translation of virtual pages because of data inconsistencies (see #5000) - if(class_exists('VirtualPage')){ - $excludedPageTypes = array('VirtualPage'); - foreach($excludedPageTypes as $excludedPageType) { - if(is_a($this->owner, $excludedPageType)) return; - } - } - - $excludeFields = array( - 'ViewerGroups', - 'EditorGroups', - 'CanViewType', - 'CanEditType' - ); + function updateCMSFields(FieldList $fields) { + $this->addTranslatableFields($fields); - // if a language other than default language is used, we're in "translation mode", - // hence have to modify the original fields - $creating = false; - $baseClass = $this->owner->class; - $allFields = $fields->toArray(); - while( ($p = get_parent_class($baseClass)) != "DataObject") $baseClass = $p; - - // try to get the record in "default language" - $originalRecord = $this->owner->getTranslation(Translatable::default_locale()); - // if no translation in "default language", fall back to first translation - if(!$originalRecord) { - $translations = $this->owner->getTranslations(); - $originalRecord = ($translations) ? $translations->First() : null; - } - - $isTranslationMode = $this->owner->Locale != Translatable::default_locale(); - // Show a dropdown to create a new translation. // This action is possible both when showing the "default language" // and a translation. Include the current locale (record might not be saved yet). $alreadyTranslatedLocales = $this->getTranslatedLocales(); $alreadyTranslatedLocales[$this->owner->Locale] = $this->owner->Locale; $alreadyTranslatedLocales = array_combine($alreadyTranslatedLocales, $alreadyTranslatedLocales); - - if($originalRecord && $isTranslationMode) { - $originalLangID = Session::get($this->owner->ID . '_originalLangID'); - - // Remove parent page dropdown - $fields->removeByName("ParentType"); - $fields->removeByName("ParentID"); - - $translatableFieldNames = $this->getTranslatableFields(); - $allDataFields = $fields->dataFields(); - - $transformation = new Translatable_Transformation($originalRecord); - - // iterate through sequential list of all datafields in fieldset - // (fields are object references, so we can replace them with the translatable CompositeField) - foreach($allDataFields as $dataField) { - if($dataField instanceof HiddenField) continue; - if(in_array($dataField->Name(), $excludeFields)) continue; - - if(in_array($dataField->Name(), $translatableFieldNames)) { - // if the field is translatable, perform transformation - $fields->replaceField($dataField->Name(), $transformation->transformFormField($dataField)); - } else { - // else field shouldn't be editable in translation-mode, make readonly - $fields->replaceField($dataField->Name(), $dataField->performReadonlyTransformation()); - } - } - - } elseif($this->owner->isNew()) { - $fields->addFieldsToTab( - 'Root', - new Tab(_t('Translatable.TRANSLATIONS', 'Translations'), - new LiteralField('SaveBeforeCreatingTranslationNote', - sprintf('

%s

', - _t('Translatable.NOTICENEWPAGE', 'Please save this page before creating a translation') - ) - ) - ) - ); - } $fields->addFieldsToTab( 'Root', @@ -1012,9 +934,9 @@ class Translatable extends DataExtension implements PermissionProvider { $existingTransHTML = '