Example #1
0
 /**
  * If the record is not shown in the default language, this method
  * will try to autoselect a master language which is shown alongside
  * the normal formfields as a readonly representation.
  * This gives translators a powerful tool for their translation workflow
  * without leaving the translated page interface.
  * Translatable also adds a new tab "Translation" which shows existing
  * translations, as well as a formaction to create new translations based
  * on a dropdown with available languages.
  * 
  * @todo This is specific to SiteTree and CMSMain
  * @todo Implement a special "translation mode" which triggers display of the
  * readonly fields, so you can translation INTO the "default language" while
  * seeing readonly fields as well.
  */
 function updateCMSFields(FieldSet &$fields)
 {
     // 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)
     $excludedPageTypes = array('VirtualPage');
     foreach ($excludedPageTypes as $excludedPageType) {
         if (is_a($this->owner, $excludedPageType)) {
             return;
         }
     }
     $excludeFields = array('ViewerGroups', 'EditorGroups', 'CanViewType', 'CanEditType');
     // 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;
     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('<p class="message">%s</p>', _t('Translatable.NOTICENEWPAGE', 'Please save this page before creating a translation')))));
     }
     $fields->addFieldsToTab('Root', new Tab('Translations', _t('Translatable.TRANSLATIONS', 'Translations'), new HeaderField('CreateTransHeader', _t('Translatable.CREATE', 'Create new translation'), 2), $langDropdown = new LanguageDropdownField("NewTransLang", _t('Translatable.NEWLANGUAGE', 'New language'), $alreadyTranslatedLocales, 'SiteTree', 'Locale-English', $this->owner), $createButton = new InlineFormAction('createtranslation', _t('Translatable.CREATEBUTTON', 'Create'))));
     $createButton->includeDefaultJS(false);
     if ($alreadyTranslatedLocales) {
         $fields->addFieldToTab('Root.Translations', new HeaderField('ExistingTransHeader', _t('Translatable.EXISTING', 'Existing translations:'), 3));
         $existingTransHTML = '<ul>';
         foreach ($alreadyTranslatedLocales as $i => $langCode) {
             $existingTranslation = $this->owner->getTranslation($langCode);
             if ($existingTranslation) {
                 $existingTransHTML .= sprintf('<li><a href="%s">%s</a></li>', sprintf('admin/show/%d/?locale=%s', $existingTranslation->ID, $langCode), i18n::get_locale_name($langCode));
             }
         }
         $existingTransHTML .= '</ul>';
         $fields->addFieldToTab('Root.Translations', new LiteralField('existingtrans', $existingTransHTML));
     }
     $langDropdown->addExtraClass('languageDropdown');
     $createButton->addExtraClass('createTranslationButton');
 }
	function updateCMSFields(FieldSet &$fields) {
		if(!$this->stat('enabled', true)) return false;
		
		// add hidden fields for the used language and original record
		$fields->push(new HiddenField("Lang", "Lang", $this->getLang()) );
		$fields->push(new HiddenField("OriginalID", "OriginalID", $this->owner->OriginalID) );
		
		// if a language other than default language is used, we're in "translation mode",
		// hence have to modify the original fields
		$isTranslationMode = (Translatable::default_lang() != $this->getLang() && $this->getLang());
		if($isTranslationMode) {
			$originalLangID = Session::get($this->owner->ID . '_originalLangID');
			
			$translatableFieldNames = $this->getTranslatableFields();
			$allDataFields = $fields->dataFields();
			$transformation = new Translatable_Transformation(Translatable::get_original($this->owner->class, $this->owner->ID));
			
			// 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(in_array($dataField->Name(), $translatableFieldNames)) {
					//var_dump($dataField->Name());
					// 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());
				}
			}
		} else {
			// if we're not in "translation mode", show a dropdown to create a new translation.
			// this action should just be possible when showing the default language,
			// you can't create new translations from within a "translation mode" form.
			
			$alreadyTranslatedLangs = array();
			foreach ($alreadyTranslatedLangs as $i => $langCode) {
				$alreadyTranslatedLangs[$i] = i18n::get_language_name($langCode);
			}
			$fields->addFieldsToTab(
				'Root',
				new Tab(_t('Translatable.TRANSLATIONS', 'Translations'),
					new HeaderField('CreateTransHeader', _t('Translatable.CREATE', 'Create new translation'), 2),
					$langDropdown = new LanguageDropdownField("NewTransLang", _t('Translatable.NEWLANGUAGE', 'New language'), $alreadyTranslatedLangs),
					$createButton = new InlineFormAction('createtranslation',_t('Translatable.CREATEBUTTON', 'Create'))
				)
			);
			if (count($alreadyTranslatedLangs)) {
				$fields->addFieldsToTab(
					'Root.Translations',
					new FieldSet(
						new HeaderField('ExistingTransHeader', _t('Translatable.EXISTING', 'Existing translations:'), 3),
						new LiteralField('existingtrans',implode(', ',$alreadyTranslatedLangs))
					)
				);
			}
			$langDropdown->addExtraClass('languageDropdown');
			$createButton->addExtraClass('createTranslationButton');
			$createButton->includeDefaultJS(false);
		}
	}
 /**
  * This method can be called multiple times on the same FieldList
  * because it checks which fields have already been added or modified.
  */
 protected function addTranslatableFields(&$fields)
 {
     // used in LeftAndMain->init() to set language state when reading/writing record
     $fields->push(new HiddenField("Locale", "Locale", $this->owner->Locale));
     // Don't apply these modifications for normal DataObjects - they rely on CMSMain logic
     if (!class_exists('SiteTree')) {
         return;
     }
     if (!$this->owner instanceof SiteTree) {
         return;
     }
     // 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;
             }
         }
     }
     // Get excluded fields from translation
     $excludeFields = $this->owner->config()->translate_excluded_fields;
     // if a language other than default language is used, we're in "translation mode",
     // hence have to modify the original fields
     $baseClass = $this->owner->class;
     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();
     if ($originalRecord && $isTranslationMode) {
         // 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) {
             // Transformation is a visual helper for CMS authors, so ignore hidden fields
             if ($dataField instanceof HiddenField) {
                 continue;
             }
             // Some fields are explicitly excluded from transformation
             if (in_array($dataField->getName(), $excludeFields)) {
                 continue;
             }
             // Readonly field which has been added previously
             if (preg_match('/_original$/', $dataField->getName())) {
                 continue;
             }
             // Field already has been transformed
             if (isset($allDataFields[$dataField->getName() . '_original'])) {
                 continue;
             }
             // CheckboxField which is already transformed
             if (preg_match('/class=\\"originalvalue\\"/', $dataField->Title())) {
                 continue;
             }
             if (in_array($dataField->getName(), $translatableFieldNames)) {
                 // if the field is translatable, perform transformation
                 $fields->replaceField($dataField->getName(), $transformation->transformFormField($dataField));
             } elseif (!$dataField->isReadonly()) {
                 // else field shouldn't be editable in translation-mode, make readonly
                 $fields->replaceField($dataField->getName(), $dataField->performReadonlyTransformation());
             }
         }
     } elseif ($this->owner->isNew()) {
         $fields->addFieldsToTab('Root', new Tab(_t('Translatable.TRANSLATIONS', 'Translations'), new LiteralField('SaveBeforeCreatingTranslationNote', sprintf('<p class="message">%s</p>', _t('Translatable.NOTICENEWPAGE', 'Please save this page before creating a translation')))));
     }
 }
 protected function addTranslatableFields(&$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;
             }
         }
     }
     // TODO Remove hardcoding for SiteTree properties
     $excludeFields = array('ViewerGroups', 'EditorGroups', 'CanViewType', 'CanEditType');
     // 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();
     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->getName(), $excludeFields)) {
                 continue;
             }
             if (in_array($dataField->getName(), $translatableFieldNames)) {
                 // if the field is translatable, perform transformation
                 $fields->replaceField($dataField->getName(), $transformation->transformFormField($dataField));
             } else {
                 // else field shouldn't be editable in translation-mode, make readonly
                 $fields->replaceField($dataField->getName(), $dataField->performReadonlyTransformation());
             }
         }
     } elseif ($this->owner->isNew()) {
         $fields->addFieldsToTab('Root', new Tab(_t('Translatable.TRANSLATIONS', 'Translations'), new LiteralField('SaveBeforeCreatingTranslationNote', sprintf('<p class="message">%s</p>', _t('Translatable.NOTICENEWPAGE', 'Please save this page before creating a translation')))));
     }
 }