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());
 }
Example #15
0
 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);
 }