diff --git a/cfg/conf.ini b/cfg/conf.ini index dff69c1..b6e6683 100644 --- a/cfg/conf.ini +++ b/cfg/conf.ini @@ -43,6 +43,11 @@ template = "bootstrap" ; use "1.7" if you are upgrading from a ZeroBin Alpha 0.19 installation base64version = "2.1.9" +; by default ZeroBin will guess the visitors language based on the browsers +; settings. Optionally you can enable the language selection menu, which uses +; a session cookie to store the choice until the browser is closed. +languageselection = false + [expire] ; expire value that is selected per default ; make sure the value exists in [expire_options] diff --git a/css/zerobin.css b/css/zerobin.css index fe036eb..c252d26 100644 --- a/css/zerobin.css +++ b/css/zerobin.css @@ -126,7 +126,7 @@ h3.title { #copyhint { color: #666; font-size: 0.85em; } -button, .button, #expiration, #formatter { +button, .button { color: #fff; background-color: #323b47; background-repeat: no-repeat; @@ -134,7 +134,7 @@ button, .button, #expiration, #formatter { padding: 4px 8px; font-size: 1em; margin-right: 5px; - display: inline; + display: inline-block; background-image: linear-gradient(bottom, #323b47 0, #51606e 100%); background-image: -o-linear-gradient(bottom, #323b47 0, #51606e 100%); background-image: -moz-linear-gradient(bottom, #323b47 0, #51606e 100%); @@ -185,7 +185,7 @@ button img { top: 2px; } -#expiration, #formatter, #rawtextbutton, #burnafterreadingoption, #opendisc { +.button { background-color: #414d5a; padding: 6px 8px; margin: 0 5px 0 0; @@ -193,14 +193,14 @@ button img { bottom: 1px; /* WTF ? Why is this shifted by 1 pixel ? */ } -#expiration select, #formatter select { +.button select { color: #eee; background: transparent; border: none; } -#expiration select option, #formatter select option { +.button select option { color:#eee; background: #414d5a; } diff --git a/i18n/de.json b/i18n/de.json index 66d6859..4cdebec 100644 --- a/i18n/de.json +++ b/i18n/de.json @@ -130,7 +130,7 @@ "Markdown": "Markdown", "Download attachment": "Anhang herunterladen", "Cloned file attached.": "Kopierte Datei angehängt.", - "Attach a file:": "Datei anhängen:", + "Attach a file": "Datei anhängen", "Remove attachment": "Anhang entfernen", "Your browser does not support uploading encrypted files. Please use a newer browser.": "Dein Browser unterstützt das hochladen von verschlüsselten Dateien nicht. Bitte verwende einen neueren Browser.", diff --git a/i18n/fr.json b/i18n/fr.json index 9eb9bdc..87b7ca9 100644 --- a/i18n/fr.json +++ b/i18n/fr.json @@ -139,7 +139,7 @@ "Markdown": "Markdown", "Download attachment": "Télécharger la pièce jointe", "Cloned file attached.": "Cloner le fichier attaché.", - "Attach a file:": "Attacher un fichier :", + "Attach a file": "Attacher un fichier ", "Remove attachment": "Enlever l'attachement", "Your browser does not support uploading encrypted files. Please use a newer browser.": "Votre navigateur ne supporte pas l'envoi de fichiers chiffrés. Merci d'utiliser un navigateur plus récent.", diff --git a/i18n/languages.json b/i18n/languages.json new file mode 100644 index 0000000..8cde844 --- /dev/null +++ b/i18n/languages.json @@ -0,0 +1,181 @@ +{ + "ab": ["аҧсуа бызшәа", "Abkhaz"], + "aa": ["Afaraf", "Afar"], + "af": ["Afrikaans", "Afrikaans"], + "ak": ["Akan", "Akan"], + "sq": ["Shqip", "Albanian"], + "am": ["አማርኛ", "Amharic"], + "ar": ["العربية", "Arabic"], + "an": ["aragonés", "Aragonese"], + "hy": ["Հայերեն", "Armenian"], + "as": ["অসমীয়া", "Assamese"], + "ac": ["Ástralic", "Australian"], + "av": ["авар мацӀ", "Avaric"], + "ae": ["avesta", "Avestan"], + "ay": ["aymar aru", "Aymara"], + "az": ["azərbaycan dili", "Azerbaijani"], + "bm": ["bamanankan", "Bambara"], + "ba": ["башҡорт теле", "Bashkir"], + "eu": ["euskara", "Basque"], + "be": ["беларуская мова", "Belarusian"], + "bn": ["বাংলা", "Bengali"], + "bh": ["भोजपुरी", "Bihari"], + "bi": ["Bislama", "Bislama"], + "bs": ["bosanski jezik", "Bosnian"], + "br": ["brezhoneg", "Breton"], + "bg": ["български език", "Bulgarian"], + "my": ["ဗမာစာ", "Burmese"], + "ca": ["català", "Catalan"], + "ch": ["Chamoru", "Chamorro"], + "ce": ["нохчийн мотт", "Chechen"], + "ny": ["chiCheŵa", "Chichewa"], + "zh": ["中文", "Chinese"], + "cv": ["чӑваш чӗлхи", "Chuvash"], + "kw": ["Kernewek", "Cornish"], + "co": ["corsu", "Corsican"], + "cr": ["ᓀᐦᐃᔭᐍᐏᐣ", "Cree"], + "hr": ["hrvatski jezik", "Croatian"], + "cs": ["čeština", "Czech"], + "da": ["dansk", "Danish"], + "dv": ["ދިވެހި", "Divehi"], + "nl": ["Nederlands", "Dutch"], + "dz": ["རྫོང་ཁ", "Dzongkha"], + "en": ["English", "English"], + "eo": ["Esperanto", "Esperanto"], + "et": ["eesti", "Estonian"], + "ee": ["Eʋegbe", "Ewe"], + "fo": ["føroyskt", "Faroese"], + "fj": ["vosa Vakaviti", "Fijian"], + "fi": ["suomi", "Finnish"], + "fr": ["français", "French"], + "ff": ["Fulfulde", "Fula"], + "gl": ["galego", "Galician"], + "ka": ["ქართული", "Georgian"], + "de": ["Deutsch", "German"], + "el": ["ελληνικά", "Greek"], + "gn": ["Avañe'ẽ", "Guaraní"], + "gu": ["ગુજરાતી", "Gujarati"], + "ht": ["Kreyòl ayisyen", "Haitian"], + "ha": ["هَوُسَ", "Hausa"], + "he": ["עברית", "Hebrew"], + "hz": ["Otjiherero", "Herero"], + "hi": ["हिन्दी", "Hindi"], + "ho": ["Hiri Motu", "Hiri Motu"], + "hu": ["magyar", "Hungarian"], + "ia": ["Interlingua", "Interlingua"], + "ie": ["Interlingue", "Interlingue"], + "ga": ["Gaeilge", "Irish"], + "ig": ["Asụsụ Igbo", "Igbo"], + "ik": ["Iñupiaq", "Inupiaq"], + "io": ["Ido", "Ido"], + "is": ["Íslenska", "Icelandic"], + "it": ["italiano", "Italian"], + "iu": ["ᐃᓄᒃᑎᑐᑦ", "Inuktitut"], + "ja": ["日本語", "Japanese"], + "jv": ["basa Jawa", "Javanese"], + "kl": ["kalaallisut", "Greenlandic"], + "kn": ["ಕನ್ನಡ", "Kannada"], + "kr": ["Kanuri", "Kanuri"], + "ks": ["कश्मीरी", "Kashmiri"], + "kk": ["қазақ тілі", "Kazakh"], + "km": ["ខ្មែរ", "Khmer"], + "ki": ["Gĩkũyũ", "Kikuyu"], + "rw": ["Ikinyarwanda", "Kinyarwanda"], + "ky": ["Кыргызча", "Kyrgyz"], + "kv": ["коми кыв", "Komi"], + "kg": ["Kikongo", "Kongo"], + "ko": ["한국어", "Korean"], + "ku": ["Kurdî", "Kurdish"], + "kj": ["Kuanyama", "Kwanyama"], + "la": ["lingua latina", "Latin"], + "lb": ["Lëtzebuergesch", "Luxembourgish"], + "lg": ["Luganda", "Ganda"], + "li": ["Limburgs", "Limburgish"], + "ln": ["Lingála", "Lingala"], + "lo": ["ພາສາລາວ", "Lao"], + "lt": ["lietuvių kalba", "Lithuanian"], + "lu": ["Tshiluba", "Luba-Katanga"], + "lv": ["latviešu valoda", "Latvian"], + "gv": ["Gaelg", "Manx"], + "mk": ["македонски јазик", "Macedonian"], + "mg": ["fiteny malagasy", "Malagasy"], + "ms": ["بهاس ملايو‎", "Malay"], + "ml": ["മലയാളം", "Malayalam"], + "mt": ["Malti", "Maltese"], + "mi": ["te reo Māori", "Māori"], + "mr": ["मराठी", "Marathi"], + "mh": ["Kajin M̧ajeļ", "Marshallese"], + "mn": ["Монгол хэл", "Mongolian"], + "na": ["Ekakairũ Naoero", "Nauru"], + "nv": ["Diné bizaad", "Navajo"], + "nd": ["isiNdebele", "Northern Ndebele"], + "ne": ["नेपाली", "Nepali"], + "ng": ["Owambo", "Ndonga"], + "no": ["Norsk", "Norwegian"], + "ii": ["ꆈꌠ꒿", "Nuosu"], + "nr": ["isiNdebele", "Southern Ndebele"], + "oc": ["occitan", "Occitan"], + "oj": ["ᐊᓂᔑᓈᐯᒧᐎᓐ", "Ojibwe"], + "om": ["Afaan Oromoo", "Oromo"], + "or": ["ଓଡ଼ିଆ", "Oriya"], + "os": ["ирон æвзаг", "Ossetian"], + "pa": ["ਪੰਜਾਬੀ", "Punjabi"], + "pi": ["पाऴि", "Pāli"], + "fa": ["فارسی", "Persian"], + "pl": ["polszczyzna", "Polish"], + "ps": ["پښتو", "Pashto"], + "pt": ["português", "Portuguese"], + "qu": ["Runa Simi", "Quechua"], + "rm": ["rumantsch grischun", "Romansh"], + "rn": ["Ikirundi", "Kirundi"], + "ro": ["limba română", "Romanian"], + "ru": ["Русский", "Russian"], + "sc": ["sardu", "Sardinian"], + "sd": ["सिन्धी", "Sindhi"], + "se": ["Davvisámegiella", "Northern Sami"], + "sm": ["gagana fa'a Samoa", "Samoan"], + "sg": ["yângâ tî sängö", "Sango"], + "sr": ["српски језик", "Serbian"], + "gd": ["Gàidhlig", "Gaelic"], + "sn": ["chiShona", "Shona"], + "si": ["සිංහල", "Sinhalese"], + "sk": ["slovenčina", "Slovak"], + "sl": ["slovenščina", "Slovene"], + "so": ["Soomaaliga", "Somali"], + "st": ["Sesotho", "Southern Sotho"], + "es": ["español", "Spanish"], + "su": ["Basa Sunda", "Sundanese"], + "sw": ["Kiswahili", "Swahili"], + "ss": ["SiSwati", "Swati"], + "sv": ["svenska", "Swedish"], + "ta": ["தமிழ்", "Tamil"], + "te": ["తెలుగు", "Telugu"], + "tg": ["тоҷикӣ", "Tajik"], + "th": ["ไทย", "Thai"], + "ti": ["ትግርኛ", "Tigrinya"], + "bo": ["བོད་ཡིག", "Tibetan"], + "tk": ["Түркмен", "Turkmen"], + "tl": ["ᜏᜒᜃᜅ᜔ ᜆᜄᜎᜓᜄ᜔", "Tagalog"], + "tn": ["Setswana", "Tswana"], + "to": ["faka Tonga", "Tonga"], + "tr": ["Türkçe", "Turkish"], + "ts": ["Xitsonga", "Tsonga"], + "tt": ["татар теле", "Tatar"], + "ty": ["Reo Tahiti", "Tahitian"], + "ug": ["ئۇيغۇرچە‎", "Uyghur"], + "uk": ["українська мова", "Ukrainian"], + "ur": ["اردو", "Urdu"], + "uz": ["Oʻzbek‎", "Uzbek"], + "ve": ["Tshivenḓa", "Venda"], + "vi": ["Việt Nam", "Vietnamese"], + "vo": ["Volapük", "Volapük"], + "wa": ["walon", "Walloon"], + "cy": ["Cymraeg", "Welsh"], + "wo": ["Wollof", "Wolof"], + "fy": ["Frysk", "Western Frisian"], + "xh": ["isiXhosa", "Xhosa"], + "yi": ["ייִדיש", "Yiddish"], + "yo": ["Yorùbá", "Yoruba"], + "za": ["Saɯ cueŋƅ", "Zhuang"], + "zu": ["isiZulu", "Zulu"] +} diff --git a/i18n/pl.json b/i18n/pl.json index 1497e18..b5ba538 100644 --- a/i18n/pl.json +++ b/i18n/pl.json @@ -130,7 +130,7 @@ "Markdown": "Markdown", "Download attachment": "Download attachment", "Cloned file attached.": "Cloned file attached.", - "Attach a file:": "Attach a file:", + "Attach a file": "Attach a file", "Remove attachment": "Remove attachment", "Your browser does not support uploading encrypted files. Please use a newer browser.": "Your browser does not support uploading encrypted files. Please use a newer browser.", diff --git a/js/zerobin.js b/js/zerobin.js index fcdfe69..c5f1d0d 100644 --- a/js/zerobin.js +++ b/js/zerobin.js @@ -266,7 +266,25 @@ $(function() { } return val; }); - } + }, + + /** + * get value of cookie, if it was set, empty string otherwise + * From: http://www.w3schools.com/js/js_cookies.asp + * + * @param string cname + * @return string + */ + getCookie: function(cname) { + var name = cname + '='; + var ca = document.cookie.split(';'); + for(var i = 0; i < ca.length; ++i) { + var c = ca[i]; + while (c.charAt(0) == ' ') c = c.substring(1); + if (c.indexOf(name) == 0) return c.substring(name.length, c.length); + } + return ''; + } }; /** @@ -361,7 +379,8 @@ $(function() { */ loadTranslations: function(callback) { - var language = (navigator.language || navigator.userLanguage).substring(0, 2); + var selectedLang = helper.getCookie('lang'); + var language = selectedLang.length > 0 ? selectedLang : (navigator.language || navigator.userLanguage).substring(0, 2); // note that 'en' is built in, so no translation is necessary if (this.supportedLanguages.indexOf(language) == -1) { diff --git a/lib/i18n.php b/lib/i18n.php index 632f215..9861db7 100644 --- a/lib/i18n.php +++ b/lib/i18n.php @@ -26,6 +26,33 @@ class i18n */ protected static $_language = 'en'; + /** + * language labels + * + * @access protected + * @static + * @var array + */ + protected static $_languageLabels = array(); + + /** + * available languages + * + * @access protected + * @static + * @var array + */ + protected static $_availableLanguages = array(); + + /** + * path to language files + * + * @access protected + * @static + * @var string + */ + protected static $_path = ''; + /** * translation cache * @@ -94,36 +121,57 @@ class i18n * * From: http://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447 * - * @access protected + * @access public * @static * @return void */ public static function loadTranslations() { - // find a matching translation file - $availableLanguages = array(); - $path = PUBLIC_PATH . DIRECTORY_SEPARATOR . 'i18n'; - $i18n = dir($path); - while (false !== ($file = $i18n->read())) + $availableLanguages = self::getAvailableLanguages(); + + // check if the lang cookie was set and that language exists + if (array_key_exists('lang', $_COOKIE) && in_array($_COOKIE['lang'], $availableLanguages)) { - if (preg_match('/^([a-z]{2}).json$/', $file, $match) === 1) - { - $availableLanguages[] = $match[1]; - } + $match = $_COOKIE['lang']; + } + // find a translation file matching the browsers language preferences + else + { + $match = self::_getMatchingLanguage( + self::getBrowserLanguages(), $availableLanguages + ); } - $match = self::_getMatchingLanguage( - self::getBrowserLanguages(), $availableLanguages - ); // load translations - if ($match != 'en') + self::$_language = $match; + self::$_translations = ($match == 'en') ? array() : json_decode( + file_get_contents(self::_getPath($match . '.json')), + true + ); + } + + /** + * get list of available translations based on files found + * + * @access public + * @static + * @return array + */ + public static function getAvailableLanguages() + { + if (count(self::$_availableLanguages) == 0) { - self::$_language = $match; - self::$_translations = json_decode( - file_get_contents($path . DIRECTORY_SEPARATOR . $match . '.json'), - true - ); + $i18n = dir(self::_getPath()); + while (false !== ($file = $i18n->read())) + { + if (preg_match('/^([a-z]{2}).json$/', $file, $match) === 1) + { + self::$_availableLanguages[] = $match[1]; + } + } + self::$_availableLanguages[] = 'en'; } + return self::$_availableLanguages; } /** @@ -131,6 +179,8 @@ class i18n * * From: http://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447 * + * @access public + * @static * @return array */ public static function getBrowserLanguages() @@ -165,12 +215,64 @@ class i18n return $languages; } + /** + * get currently loaded language + * + * @access public + * @static + * @return string + */ + public static function getLanguage() + { + return self::$_language; + } + + /** + * get list of language labels + * + * Only for given language codes, otherwise all labels. + * + * @access public + * @static + * @param array $languages + * @return array + */ + public static function getLanguageLabels($languages = array()) + { + $file = self::_getPath('languages.json'); + if (count(self::$_languageLabels) == 0 && is_readable($file)) + { + self::$_languageLabels = json_decode(file_get_contents($file), true); + } + if (count($languages) == 0) return self::$_languageLabels; + return array_intersect_key(self::$_languageLabels, array_flip($languages)); + } + + /** + * get language file path + * + * @access protected + * @static + * @param string $file + * @return string + */ + protected static function _getPath($file = '') + { + if (strlen(self::$_path) == 0) + { + self::$_path = PUBLIC_PATH . DIRECTORY_SEPARATOR . 'i18n'; + } + return self::$_path . (strlen($file) ? DIRECTORY_SEPARATOR . $file : ''); + } + /** * determines the plural form to use based on current language and given number * * From: http://localization-guide.readthedocs.org/en/latest/l10n/pluralforms.html * - * @param int $n + * @access protected + * @static + * @param int $n * @return int */ protected static function _getPluralForm($n) @@ -191,8 +293,10 @@ class i18n * * From: http://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447 * - * @param array $acceptedLanguages - * @param array $availableLanguages + * @access protected + * @static + * @param array $acceptedLanguages + * @param array $availableLanguages * @return string */ protected static function _getMatchingLanguage($acceptedLanguages, $availableLanguages) { @@ -247,8 +351,10 @@ class i18n * * From: http://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447 * - * @param string $a - * @param string $b + * @access protected + * @static + * @param string $a + * @param string $b * @return float */ protected static function _matchLanguage($a, $b) { diff --git a/lib/zerobin.php b/lib/zerobin.php index 5de2710..e87f6cb 100644 --- a/lib/zerobin.php +++ b/lib/zerobin.php @@ -659,6 +659,14 @@ class zerobin // translate all the formatter options $formatters = array_map(array('i18n', 'translate'), $this->_conf['formatter_options']); + // set language cookie if that functionality was enabled + $languageselection = ''; + if ($this->_getMainConfig('languageselection', false)) + { + $languageselection = i18n::getLanguage(); + setcookie('lang', $languageselection); + } + $page = new RainTPL; $page::$path_replace = false; // we escape it here because ENT_NOQUOTES can't be used in RainTPL templates @@ -678,6 +686,8 @@ class zerobin $page->assign('PASSWORD', $this->_getMainConfig('password', true)); $page->assign('FILEUPLOAD', $this->_getMainConfig('fileupload', false)); $page->assign('BASE64JSVERSION', $this->_getMainConfig('base64version', '2.1.9')); + $page->assign('LANGUAGESELECTION', $languageselection); + $page->assign('LANGUAGES', i18n::getLanguageLabels(i18n::getAvailableLanguages())); $page->assign('EXPIRE', $expire); $page->assign('EXPIREDEFAULT', $this->_conf['expire']['default']); $page->draw($this->_getMainConfig('template', 'page')); diff --git a/tpl/bootstrap-compact.html b/tpl/bootstrap-compact.html index 248d344..0dbcd18 100644 --- a/tpl/bootstrap-compact.html +++ b/tpl/bootstrap-compact.html @@ -118,7 +118,18 @@ {/if} - -