public function setUp() { parent::setUp(); //Remap translation group for home pages Translatable::disable_locale_filter(); $default = $this->objFromFixture('Page', 'home'); $defaultFR = $this->objFromFixture('Page', 'home_fr'); $defaultFR->addTranslationGroup($default->ID, true); Translatable::enable_locale_filter(); $this->origLocaleRoutingEnabled = Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL'); Config::inst()->update('MultilingualRootURLController', 'UseLocaleURL', false); $this->origDashLocaleEnabled = Config::inst()->get('MultilingualRootURLController', 'UseDashLocale'); Config::inst()->update('MultilingualRootURLController', 'UseDashLocale', false); $this->origAcceptLanguage = $_SERVER['HTTP_ACCEPT_LANGUAGE']; $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'en-US,en;q=0.5'; $this->origCookieLocale = Cookie::get('language'); Cookie::force_expiry('language'); $this->origCurrentLocale = Translatable::get_current_locale(); Translatable::set_current_locale('en_US'); $this->origLocale = Translatable::default_locale(); Translatable::set_default_locale('en_US'); $this->origi18nLocale = i18n::get_locale(); i18n::set_locale('en_US'); $this->origAllowedLocales = Translatable::get_allowed_locales(); Translatable::set_allowed_locales(array('en_US', 'fr_FR')); MultilingualRootURLController::reset(); }
public function setUp() { parent::setUp(); Translatable::disable_locale_filter(); //Publish all english pages $pages = Page::get()->filter('Locale', 'en_US'); foreach ($pages as $page) { $page->publish('Stage', 'Live'); } //Rewrite the french translation groups and publish french pages $pagesFR = Page::get()->filter('Locale', 'fr_FR'); foreach ($pagesFR as $index => $page) { $page->addTranslationGroup($pages->offsetGet($index)->ID, true); $page->publish('Stage', 'Live'); } Translatable::enable_locale_filter(); $this->origLocaleRoutingEnabled = Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL'); Config::inst()->update('MultilingualRootURLController', 'UseLocaleURL', false); $this->origDashLocaleEnabled = Config::inst()->get('MultilingualRootURLController', 'UseDashLocale'); Config::inst()->update('MultilingualRootURLController', 'UseDashLocale', false); $this->origAcceptLanguage = $_SERVER['HTTP_ACCEPT_LANGUAGE']; $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'en-US,en;q=0.5'; $this->origCookieLocale = Cookie::get('language'); Cookie::force_expiry('language'); Cookie::set('language', 'en'); $this->origCurrentLocale = Translatable::get_current_locale(); Translatable::set_current_locale('en_US'); $this->origLocale = Translatable::default_locale(); Translatable::set_default_locale('en_US'); $this->origi18nLocale = i18n::get_locale(); i18n::set_locale('en_US'); $this->origAllowedLocales = Translatable::get_allowed_locales(); Translatable::set_allowed_locales(array('en_US', 'fr_FR')); MultilingualRootURLController::reset(); }
/** * Returns a DataList containing Pages. * The provided links point to their translated pages. * You can use it in templates like this: * * <% loop LanguageChooser %> * $Title, $Current, and any other vars in your page instance * <% end_loop %> * * @return DataList */ public function LanguageChooser() { if (!Controller::curr()) { return; } if ($langs = Translatable::get_allowed_locales()) { $data = ArrayList::create(); foreach ($langs as $key => $code) { if ($code == Translatable::get_current_locale()) { $this->owner->Current = 'current'; $data->push($this->owner); } else { $translation = $this->owner->getTranslation($code); if ($translation) { $data->push($translation); } else { $page = Translatable::get_one_by_locale("SiteTree", $code, "URLSegment LIKE 'home%'"); if ($page) { $data->push($page); } } } } return $data; } return false; }
function run(SS_List $pages) { $status = array('translated' => array(), 'error' => array()); foreach ($pages as $page) { $id = $page->ID; foreach (Translatable::get_allowed_locales() as $locale) { if ($page->Locale == $locale) { continue; } if (!$page->hasTranslation($locale)) { try { $translation = $page->createTranslation($locale); $successMessage = $this->duplicateRelations($page, $translation); $status['translated'][$translation->ID] = array('TreeTitle' => $translation->TreeTitle); $translation->destroy(); unset($translation); } catch (Exception $e) { // no permission - fail gracefully $status['error'][$page->ID] = true; } } } $page->destroy(); unset($page); } return $this->response(_t('CMSBatchActions.TRANSLATED_PAGES', 'Translated %d pages to draft site, %d failures'), $status); }
/** * Handles enabling translations for controllers that are not pages */ public function onBeforeInit() { //Bail for the root url controller and model as controller classes as they handle this internally, also disable for development admin and cms if ($this->owner instanceof MultilingualRootURLController || $this->owner instanceof MultilingualModelAsController || $this->owner instanceof LeftAndMain || $this->owner instanceof DevelopmentAdmin || $this->owner instanceof TestRunner) { return; } //Bail for pages since this would have been handled by MultilingualModelAsController, we're assuming that data has not been set to a page by other code if (method_exists($this->owner, 'data') && $this->owner->data() instanceof SiteTree) { return; } //Check if the locale is in the url $request = $this->owner->getRequest(); if ($request && $request->param('Language')) { $language = $request->param('Language'); if (Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL')) { $locale = $language; } else { if (strpos($request->param('Language'), '_') !== false) { //Invalid format so redirect to the default $url = $request->getURL(true); $default = Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL') ? Translatable::default_locale() : Translatable::default_lang(); $this->owner->redirect(preg_replace('/^' . preg_quote($language, '/') . '\\//', $default . '/', $url), 301); return; } else { $locale = i18n::get_locale_from_lang($language); } } if (in_array($locale, Translatable::get_allowed_locales())) { //Set the language cookie Cookie::set('language', $language); //Set the various locales Translatable::set_current_locale($locale); i18n::set_locale($locale); } else { //Unknown language so redirect to the default $url = $request->getURL(true); $default = Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL') ? Translatable::default_locale() : Translatable::default_lang(); $this->owner->redirect(preg_replace('/^' . preg_quote($language, '/') . '\\//', $default . '/', $url), 301); } return; } //Detect the locale if ($locale = MultilingualRootURLController::detect_browser_locale()) { if (Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL')) { $language = $locale; } else { $language = i18n::get_lang_from_locale($locale); } //Set the language cookie Cookie::set('language', $language); //Set the various locales Translatable::set_current_locale($locale); i18n::set_locale($locale); } }
public function updateEditForm(Form $form) { $locale = isset($_REQUEST['locale']) ? $_REQUEST['locale'] : $_REQUEST['Locale']; if (!empty($locale) && i18n::validate_locale($locale) && singleton('SiteConfig')->has_extension('Translatable') && (Translatable::get_allowed_locales() === null || in_array($locale, (array) Translatable::get_allowed_locales(), false)) && $locale != Translatable::get_current_locale()) { $orig = Translatable::get_current_locale(); Translatable::set_current_locale($locale); $formAction = $form->FormAction(); $form->setFormAction($formAction); Translatable::set_current_locale($orig); } }
/** * Create a new LanguageDropdownField * @param string $name * @param string $title * @param array $excludeLocales List of locales that won't be included * @param string $translatingClass Name of the class with translated instances where to look for used languages * @param string $list Indicates the source language list. Can be either Common-English, Common-Native, Locale-English, Locale-Native */ function __construct($name, $title, $excludeLocales = array(), $translatingClass = 'SiteTree', $list = 'Common-English', $instance = null) { $usedLocalesWithTitle = Translatable::get_existing_content_languages($translatingClass); $usedLocalesWithTitle = array_diff_key($usedLocalesWithTitle, $excludeLocales); if ('Common-English' == $list) { $allLocalesWithTitle = i18n::get_common_languages(); } else { if ('Common-Native' == $list) { $allLocalesWithTitle = i18n::get_common_languages(true); } else { if ('Locale-English' == $list) { $allLocalesWithTitle = i18n::get_common_locales(); } else { if ('Locale-Native' == $list) { $allLocalesWithTitle = i18n::get_common_locales(true); } else { $allLocalesWithTitle = i18n::get_locale_list(); } } } } if (isset($allLocales[Translatable::default_locale()])) { unset($allLocales[Translatable::default_locale()]); } // Limit to allowed locales if defined // Check for canTranslate() if an $instance is given $allowedLocales = Translatable::get_allowed_locales(); foreach ($allLocalesWithTitle as $locale => $localeTitle) { if ($allowedLocales && !in_array($locale, $allowedLocales) || $excludeLocales && in_array($locale, $excludeLocales) || $usedLocalesWithTitle && array_key_exists($locale, $usedLocalesWithTitle)) { unset($allLocalesWithTitle[$locale]); } } // instance specific permissions foreach ($allLocalesWithTitle as $locale => $localeTitle) { if ($instance && !$instance->canTranslate(null, $locale)) { unset($allLocalesWithTitle[$locale]); } } foreach ($usedLocalesWithTitle as $locale => $localeTitle) { if ($instance && !$instance->canTranslate(null, $locale)) { unset($usedLocalesWithTitle[$locale]); } } // Sort by title (array value) asort($allLocalesWithTitle); if (count($usedLocalesWithTitle)) { asort($usedLocalesWithTitle); $source = array(_t('Form.LANGAVAIL', "Available languages") => $usedLocalesWithTitle, _t('Form.LANGAOTHER', "Other languages") => $allLocalesWithTitle); } else { $source = $allLocalesWithTitle; } parent::__construct($name, $title, $source); }
public static function flushCountriesCache($locale = null) { $locales = $locale ? array($locale) : (class_exists('Translatable') ? \Translatable::get_allowed_locales() : \i18n::get_locale()); foreach ($locales as $localeItem) { $name = 'areas_array_' . $localeItem; $areas = array(); $source = \Zend_Locale::getTranslationList('territory', $localeItem, 2); foreach (explode(',', self::$allowed_countries) as $countryCode) { $content = isset($source[$countryCode]) ? $source[$countryCode] : null; if (!$content) { $content = isset(self::$newTerritory[$countryCode][$localeItem]) ? self::$newTerritory[$countryCode][$localeItem] : null; if (!$content) { $content = isset(self::$newTerritory[$countryCode]['en_US']) ? self::$newTerritory[$countryCode]['en_US'] : $countryCode; } } $areas[$countryCode]['tooltip'] = array('content' => $content); // $areas[$countryCode]['text'] = array('content' => $content); } static::set_cache($name, $areas); } }
/** * Presents a form to select a language to translate the pages selected with batch actions into. * * @param string $pageIDs | null * @return Form $form */ public function TranslatePagesForm($pageIDs = null) { Versioned::reading_stage('Stage'); // Needs this for changes to effect draft tree $languages = Translatable::get_allowed_locales(); $action = FormAction::create('doTranslatePages', 'Translate')->setUseButtonTag('true')->addExtraClass('ss-ui-button ss-ui-action-constructive batch-form-actions')->setUseButtonTag(true); $actions = FieldList::create($action); $allFields = new CompositeField(); $allFields->addExtraClass('batch-form-body'); if ($pageIDs == null) { $pageIDs = $this->getRequest()->getVar('PageIDs'); } else { $allFields->push(new LiteralField("ErrorParent", '<p class="message bad">Invalid parent selected, please choose another</p>')); } $allFields->push(new HiddenField("PageIDs", "PageIDs", $pageIDs)); $allFields->push(LanguageDropdownField::create("NewTransLang", _t('Translatable.NEWLANGUAGE', 'New language'), $languages)); $headings = new CompositeField(new LiteralField('Heading', sprintf('<h3 class="">%s</h3>', _t('HtmlEditorField.MOVE', 'Choose Language...')))); $headings->addExtraClass('cms-content-header batch-pages'); $fields = new FieldList($headings, $allFields); $form = Form::create($this, 'TranslatePagesForm', $fields, $actions); return $form; }
public function setUp() { parent::setUp(); $this->origLocaleRoutingEnabled = Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL'); Config::inst()->update('MultilingualRootURLController', 'UseLocaleURL', false); $this->origAcceptLanguage = $_SERVER['HTTP_ACCEPT_LANGUAGE']; $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'en-US,en;q=0.5'; $this->origCookieLocale = Cookie::get('language'); Cookie::force_expiry('language'); Cookie::set('language', 'en'); $this->origCurrentLocale = Translatable::get_current_locale(); Translatable::set_current_locale('en_US'); $this->origLocale = Translatable::default_locale(); Translatable::set_default_locale('en_US'); $this->origi18nLocale = i18n::get_locale(); i18n::set_locale('en_US'); $this->origAllowedLocales = Translatable::get_allowed_locales(); Translatable::set_allowed_locales(array('en_US', 'fr_FR')); MultilingualTestController::add_extension('MultilingualControllerExtension'); Config::inst()->update('Director', 'rules', array('$Language/multilingual-test-controller//$Action/$ID/$OtherID' => 'MultilingualTestController')); MultilingualRootURLController::reset(); }
/** * @uses ModelAsController::getNestedController() * @return SS_HTTPResponse */ public function handleRequest(SS_HTTPRequest $request, DataModel $model) { $this->request = $request; $this->setDataModel($model); $this->pushCurrent(); //Get the local from the language param if (Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL')) { if (Config::inst()->get('MultilingualRootURLController', 'UseDashLocale')) { //Language is missing a dash 404 if (strpos($request->param('Language'), '-') === false) { //Locale not found 404 if ($response = ErrorPage::response_for(404)) { return $response; } else { $this->httpError(404, 'The requested page could not be found.'); } return $this->response; } $locale = explode('-', $request->param('Language')); $locale[1] = strtoupper($locale[1]); //Make sure that the language is all lowercase if ($request->param('Language') == implode('-', $locale)) { //Locale not found 404 if ($response = ErrorPage::response_for(404)) { return $response; } else { $this->httpError(404, 'The requested page could not be found.'); } return $this->response; } $locale = implode('_', $locale); } else { $locale = $request->param('Language'); } } else { if (strpos($request->param('Language'), '_') !== false) { //Locale not found 404 if ($response = ErrorPage::response_for(404)) { return $response; } else { $this->httpError(404, 'The requested page could not be found.'); } return $this->response; } else { $locale = i18n::get_locale_from_lang($request->param('Language')); } } if (in_array($locale, Translatable::get_allowed_locales())) { //Set the current locale and remember it Cookie::set('language', $request->param('Language')); Translatable::set_current_locale($locale); i18n::set_locale($locale); } else { //Locale not found 404 if ($response = ErrorPage::response_for(404)) { return $response; } else { $this->httpError(404, 'The requested page could not be found.'); } return $this->response; } //Handle the home page for the language $urlSegment = $request->param('URLSegment'); if (empty($urlSegment)) { $controller = new MultilingualRootURLController(); $response = $controller->handleRequest($request, $model); $this->popCurrent(); return $response; } //Normal page request so handle that $response = parent::handleRequest($request, $model); $this->popCurrent(); return $response; }
public function translate(SS_HTTPRequest $request) { $locales = ""; if (SiteTree::has_extension("Translatable")) { $locales = Translatable::get_allowed_locales(); } else { $locales = array("it_IT"); } $locales_list = new ArrayList(); foreach ($locales as $key => $value) { $obj = new ViewableData(); $obj->__set("Locale", $value); $obj->__set("LocaleName", i18n::get_locale_name($value)); $obj->__set("Lang", i18n::get_lang_from_locale($value)); $locales_list->push($obj); } if ($request->isAjax()) { if (isset($_POST["collect"])) { foreach ($locales as $value) { $c = new TextCollector($value); $c->run(LanguageAdmin::$modules, true); } die(_t("SUCCESSFULL_COLLECT", "The text was collected.")); } if (isset($_POST["save"])) { $lang_array[$_POST["locale"]] = $_POST[$_POST["locale"]]; $file = $_POST["file"]; $yml_file = sfYaml::dump($lang_array); if ($fh = fopen($file, "w")) { fwrite($fh, $yml_file); fclose($fh); file_get_contents("http://{$_SERVER['HTTP_HOST']}?flush"); } else { throw new LogicException("Cannot write language file! Please check permissions of {$langFile}"); } die; } $files = $this->getFiles(); if (isset($_POST["loadfiles"])) { // die($this->getYaml($_POST["loadfiles"])); $this->customise(array("Translations" => $this->getYaml($_POST["loadfiles"]), "Modules" => $files, "Locales" => $locales_list)); $content = $this->renderWith('LanguageAdmin_Content'); return $content; } else { $this->customise(array("Modules" => $files, "Translations" => $this->getYaml($files->filter(array('Locale' => $locales_list->first()->Locale))->first()->Path), "Locales" => $locales_list, "CurrentLocale" => $locales_list->first()->LocaleName)); $content = $this->renderWith('LanguageAdmin_Content'); return $content; } } else { $files = $this->getFiles(); $this->customise(array("Modules" => $files, "Translations" => $this->getYaml($files->filter(array('Locale' => $locales_list->first()->Locale))->first()->Path), "Locales" => $locales_list, "CurrentLocale" => $locales_list->first()->LocaleName)); $content = $this->renderWith($this->getViewer('translate')); return $content; } }
/** * Is the prefix a valid locale? (@see alternateGetByLink) * * @param string $prefix * @return boolean */ public static function valid_prefix($prefix) { // is this part of the prefix map if there is one? if (!empty(self::$locale_prefix_map)) { return in_array($prefix, self::$locale_prefix_map); } // is this part of the allowed languages, if there are any $alowed_locales = Translatable::get_allowed_locales(); if (!empty($alowed_locales)) { return in_array($prefix, $alowed_locales); } // is this a valid locale anyway? return i18n::validate_locale($prefix); }
/** * Get the locales that should be translated * @return array containing the locales to use */ protected static function get_target_locales() { // if locales are explicitly set, use these if (is_array(self::config()->locales)) { return (array) self::config()->locales; // otherwise check the allowed locales. If these have been set, use these } else { if (is_array(Translatable::get_allowed_locales())) { return (array) Translatable::get_allowed_locales(); } } // last resort is to take the existing content languages return array_keys(Translatable::get_existing_content_languages()); }
function testCanTranslate() { $origAllowedLocales = Translatable::get_allowed_locales(); $cmseditor = $this->objFromFixture('Member', 'cmseditor'); $testPage = $this->objFromFixture('Page', 'testpage_en'); $this->assertTrue($testPage->canTranslate($cmseditor, 'de_DE'), "Users with canEdit() permission can create a new translation if locales are not limited"); Translatable::set_allowed_locales(array('ja_JP')); $this->assertTrue($testPage->canTranslate($cmseditor, 'ja_JP'), "Users with canEdit() permission can create a new translation if locale is in Translatable::get_allowed_locales()"); $this->assertFalse($testPage->canTranslate($cmseditor, 'de_DE'), "Users with canEdit() permission can't create a new translation if locale is not in Translatable::get_allowed_locales()"); $this->assertType('Page', $testPage->createTranslation('ja_JP')); try { $testPage->createTranslation('de_DE'); $this->setExpectedException("Exception"); } catch (Exception $e) { } Translatable::set_allowed_locales($origAllowedLocales); }
/** * Determines the locale best matching the given list of browser locales * @return {string} The matching locale, or null if none could be determined */ public static function detect_browser_locale() { if ($language = Cookie::get('language')) { if (Config::inst()->get('MultilingualRootURLController', 'UseLocaleURL')) { $locale = $language; } else { $locale = i18n::get_locale_from_lang($language); } if (in_array($locale, Translatable::get_allowed_locales())) { return $locale; } else { Cookie::force_expiry('language'); } } // Given multiple canditates, narrow down the final result using the client's preferred languages $inputLocales = array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : null; if (empty($inputLocales)) { return null; } // Generate mapping of priority => list of languages at this priority // break up string into pieces (languages and q factors) preg_match_all('/(?<code>[a-z]{1,8}(-[a-z]{1,8})?)\\s*(;\\s*q\\s*=\\s*(?<priority>1|0\\.[0-9]+))?/i', $inputLocales, $parsedLocales); $prioritisedLocales = array(); if (count($parsedLocales['code'])) { // create a list like "en" => 0.8 $parsedLocales = array_combine($parsedLocales['code'], $parsedLocales['priority']); // Generate nested list of priorities => [languages] foreach ($parsedLocales as $language => $priority) { $priority = empty($priority) ? 1.0 : floatval($priority); if (empty($prioritisedLocales[$priority])) { $prioritisedLocales[$priority] = array(); } $prioritisedLocales[$priority][] = $language; } // sort list based on value krsort($prioritisedLocales, SORT_NUMERIC); } // Check each requested language against loaded languages foreach ($prioritisedLocales as $priority => $parsedLocales) { foreach ($parsedLocales as $browserLocale) { foreach (Translatable::get_allowed_locales() as $language) { if (stripos(preg_replace('/_/', '-', $language), $browserLocale) === 0) { return $language; } } } } return null; }
function testLocalesForMember() { $origAllowedLocales = Translatable::get_allowed_locales(); Translatable::set_allowed_locales(array('de_DE', 'ja_JP')); $cmseditor = $this->objFromFixture('Member', 'cmseditor'); $translator = $this->objFromFixture('Member', 'germantranslator'); $this->assertEquals(array('de_DE', 'ja_JP'), singleton('SiteTree')->getAllowedLocalesForMember($cmseditor), 'Members with TRANSLATE_ALL permission can edit all locales'); $this->assertEquals(array('de_DE'), singleton('SiteTree')->getAllowedLocalesForMember($translator), 'Members with TRANSLATE_<locale> permission cant edit all locales'); Translatable::set_allowed_locales($origAllowedLocales); }