From 9de0583196ec8f5afa56afc192861d0d735860b4 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 22 Dec 2008 14:30:29 -0500 Subject: [PATCH] reformat lib/language.php for PEAR Coding Standards darcs-hash:20081222193029-84dde-8d0f64d0fad2a2854d1a3a294a30e74d73fd1bd1.gz --- _darcs/inventory | 4 +- ...d0f64d0fad2a2854d1a3a294a30e74d73fd1bd1.gz | Bin 0 -> 2233 bytes _darcs/pristine/lib/language.php | 201 +++-- _darcs/tentative_pristine | 808 ++++-------------- lib/language.php | 201 +++-- 5 files changed, 439 insertions(+), 775 deletions(-) create mode 100644 _darcs/patches/20081222193029-84dde-8d0f64d0fad2a2854d1a3a294a30e74d73fd1bd1.gz diff --git a/_darcs/inventory b/_darcs/inventory index b3846949ed..b3f0045032 100644 --- a/_darcs/inventory +++ b/_darcs/inventory @@ -31,4 +31,6 @@ Evan Prodromou **20081221004607] [reformat for phpcs Evan Prodromou **20081221005837] [reformat lib/jabber.php for phpcs, including doc comments -Evan Prodromou **20081222173249] \ No newline at end of file +Evan Prodromou **20081222173249] +[reformat lib/language.php for PEAR Coding Standards +Evan Prodromou **20081222193029] \ No newline at end of file diff --git a/_darcs/patches/20081222193029-84dde-8d0f64d0fad2a2854d1a3a294a30e74d73fd1bd1.gz b/_darcs/patches/20081222193029-84dde-8d0f64d0fad2a2854d1a3a294a30e74d73fd1bd1.gz new file mode 100644 index 0000000000000000000000000000000000000000..14fdbabbf774f112e4b741d81d4daf694814b45b GIT binary patch literal 2233 zcmV;q2uAlGiwFP!000001FczWSK~Gi{k-`V(=Mk;2zfzYurJsw%hG09&H_EBWjQ{I zBRgsw+sHC0+w$K#vYm$t7DacL_Yg@EmF zeth&9dclzSE?fxW4+$SemE$|&!#NLzJeUMAyrlSi7|xzsKAF(h+uOUH&ad6w-QDi~ zUT1gz2L7##Vt)*+_6pK&rP@jwQd6?5?5{nVq2KYz>hJ6YroVqT&oTQH}S3VxP6T-Zf9ZX*5M)ers z=a}9oR&?pVIH%oAEDnPA;N=pdpe!AoXBYf z+-;}tkO$cvjoQQwz2;u4(;A712PbD&aO60Y2XI1t%83W(@c=tRKQlYa77m%=VR+@0 z;dx28(4Tf`5ApGu zb*?lX$^m~`RE?}D>I?8O;eruK%!HS-0bmD18ZD?15=lNuFD#!eIZ4?QK3ra&!;x*% zP&E6qp(9F$lrP3|Dq`->1}g{&=72_G(To(bM{;0!>y<_prLC;9Y>nU*5YEYc4Wm|y^h>3=2@d4YL?k_yTxw%%70Sh5&)$ePy+Lwzj7xm_w^!H7@_Tu(c z?Yh(4Z{0NN`1~c>uI=ET|F-JiS9dVUBJhGK>@0XC-yl zd5{})c?tRFr11^Z94{cE4*555Ac2-=KD!=Pn~J8kmrf0S_yMw4CGMpiH9;V_SzvxK zz4K6XTAeN=N!u(Odyff6GeJ8*(EWXbpyVE(M*$bWeDobx;^atktM(vVc2Q$AtDA48 zcWNeg6>}bzNnd)_*j1g!nxMoUf$Bbx2)2^-_SI|Hx-Cqv+#y&LQJlH5I9w+K*Ki_T zor_0ZCo4$xX7fB{YySJA{>3p4enABOA)T`sES>i`R25qL2|VT?)%s80qS z>Oy2(A{Da|NweBYWL9D<8U?X8gimMvKk;meHRZ`s(-FlpEEPiXG!6?)NW&>pq-(9j z){%b?0e0np%19QsT#j7DTl6$`6HhZ>=0^gL&-7hOk|U0u}Wn<3*g!A@U$f>-N1GX(#u z0m9i|B?xDK=@Hz40m8}K5`?#$3B1w5R3#;KFlYp?Rhae0hosPWr=^-766@XX>MY(7 zUu)g>3|#j;>#U!%9pg@-iArGPICfi!OBAB2_C>HBz~N1YuVxqb6$QZI*89(@_wPCN zb?y(TL1c#1dUveaKB0U<{Pnh(FtE*pb$Y4VJ{81cI^$!rxQ|!k{=3{DG}irr31J4- z*(cTYvw%;ji_SxB5R50p)6`U09HLHZS3$yV`B|Lf*&udf8c`iWb5KB^ZqB~-HbGR>E`<8Y~ZZr#CLRb(xFNWz5G~ zmogTsESWA&naS7!^GNRULE|nkXfYWK2dGuQz z>}OwW(*qoy<{@H}(96D`HeZ9Z2NM#8@?g6B4L4f(1e-W0`zEL4JHkA9B3?Qx5AIX5 zcu1Xpkd^jZ=?B@y(s$P~owfMbS}3v_-|z*qk(W8;3TrM}o<>=znnaN-57Mn!lD=Js z%yX9f*XOCEh&1@kQbZcjOOaB}CHzc5mj1<{P>uOcP|UQPq?wZ}1(~HgE5J>ZP2m^4 z#kH~SQOs?mfF9w=T79(QiLp|8geQ6(m3K$)%X&vPky$FX6kNL1I#XMQ4(NoKiZ3OZ z=6IdzF;n#QQY{zwKtFk@*i1vOS8^);W}42Ni8{rXqX5;VAQOIuVbEzp6Pc9Tg(CH7=!l6b%{ySOPt6Nq1NE9) z8T4CbWE>5x_*AilHV&BvHH6p7Qx#qcRU?&Z2yY-@b5zi737HZ!CgUa>;zT?BOfDLt znRaGzVUAA}Lg-rr. + * + * @category I18n + * @package Laconica + * @author Matthew Gregg + * @author Ciaran Gultnieks + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ */ -if (!defined('LACONICA')) { exit(1); } - - - -function client_prefered_language($httplang) { - $client_langs = array(); - $all_languages = common_config('site','languages'); - - preg_match_all('"(((\S\S)-?(\S\S)?)(;q=([0-9.]+))?)\s*(,\s*|$)"',strtolower($httplang),$httplang); - for ($i = 0; $i < count($httplang); $i++) { - if(!empty($httplang[2][$i])) { - #if no q default to 1.0 - $client_langs[$httplang[2][$i]] = ($httplang[6][$i]? (float) $httplang[6][$i] : 1.0); - } - if(!empty($httplang[3][$i]) && empty($client_langs[$httplang[3][$i]])) { - #if a catchall default 0.01 lower - $client_langs[$httplang[3][$i]] = ($httplang[6][$i]? (float) $httplang[6][$i]-0.01 : 0.99); - } - } - #sort in decending q - arsort($client_langs); - - foreach ($client_langs as $lang => $q) { - if (isset($all_languages[$lang])) { - return($all_languages[$lang]['lang']); - } - } - return FALSE; +if (!defined('LACONICA')) { + exit(1); } -function get_nice_language_list() { - $nice_lang = array(); - $all_languages = common_config('site','languages'); - foreach ($all_languages as $lang) { - $nice_lang = $nice_lang + array($lang['lang'] => $lang['name']); +/** + * Content negotiation for language codes + * + * @param string $httplang HTTP Accept-Language header + * + * @return string language code for best language match + */ + +function client_prefered_language($httplang) +{ + $client_langs = array(); + + $all_languages = common_config('site', 'languages'); + + preg_match_all('"(((\S\S)-?(\S\S)?)(;q=([0-9.]+))?)\s*(,\s*|$)"', + strtolower($httplang), $httplang); + + for ($i = 0; $i < count($httplang); $i++) { + if (!empty($httplang[2][$i])) { + // if no q default to 1.0 + $client_langs[$httplang[2][$i]] = + ($httplang[6][$i]? (float) $httplang[6][$i] : 1.0); } - return $nice_lang; + if (!empty($httplang[3][$i]) && empty($client_langs[$httplang[3][$i]])) { + // if a catchall default 0.01 lower + $client_langs[$httplang[3][$i]] = + ($httplang[6][$i]? (float) $httplang[6][$i]-0.01 : 0.99); + } + } + // sort in decending q + arsort($client_langs); + + foreach ($client_langs as $lang => $q) { + if (isset($all_languages[$lang])) { + return($all_languages[$lang]['lang']); + } + } + return false; } -// Get a list of all languages that are enabled in the default config. This -// should ONLY be called when setting up the default config in common.php. -// Any other attempt to get a list of lanugages should instead call -// common_config('site','languages') -function get_all_languages() { - return array( - 'en-us' => array('q' => 1, 'lang' => 'en_US', 'name' => 'English (US)', 'direction' => 'ltr'), - 'en-nz' => array('q' => 1, 'lang' => 'en_NZ', 'name' => 'English (NZ)', 'direction' => 'ltr'), - 'en-gb' => array('q' => 1, 'lang' => 'en_GB', 'name' => 'English (British)', 'direction' => 'ltr'), - 'en' => array('q' => 1, 'lang' => 'en', 'name' => 'English', 'direction' => 'ltr'), - 'da' => array('q' => 0.1, 'lang' => 'da_DK', 'name' => 'Danish', 'direction' => 'ltr'), - 'nl' => array('q' => 1, 'lang' => 'nl_NL', 'name' => 'Dutch', 'direction' => 'ltr'), - 'eo' => array('q' => 0.1, 'lang' => 'eo', 'name' => 'Esperanto', 'direction' => 'ltr'), - 'fr-fr' => array('q' => 0.9, 'lang' => 'fr_FR', 'name' => 'French', 'direction' => 'ltr'), - 'de' => array('q' => 1, 'lang' => 'de_DE', 'name' => 'German', 'direction' => 'ltr'), - 'it' => array('q' => 1, 'lang' => 'it_IT', 'name' => 'Italian', 'direction' => 'ltr'), - 'ko' => array('q' => 0.1, 'lang' => 'ko', 'name' => 'Korean', 'direction' => 'ltr'), - 'nb' => array('q' => 1, 'lang' => 'nb_NO', 'name' => 'Norwegian (bokmal)', 'direction' => 'ltr'), - 'pt' => array('q' => 0.2, 'lang' => 'pt', 'name' => 'Portuguese', 'direction' => 'ltr'), - 'pt-br' => array('q' => 1, 'lang' => 'pt_BR', 'name' => 'Portuguese Brazil', 'direction' => 'ltr'), -# 'ru' => array('q' => 0.1, 'lang' => 'ru_RU', 'name' => 'Russian', 'direction' => 'ltr'), - 'es' => array('q' => 1, 'lang' => 'es', 'name' => 'Spanish', 'direction' => 'ltr'), - 'tr' => array('q' => 1, 'lang' => 'tr_TR', 'name' => 'Turkish', 'direction' => 'ltr'), - 'uk' => array('q' => 1, 'lang' => 'uk_UA', 'name' => 'Ukrainian', 'direction' => 'ltr'), -# 'lt' => array('q' => 0.1, 'lang' => 'lt_LT', 'name' => 'Lithuanian', 'direction' => 'ltr'), -# 'sv' => array('q' => 1, 'lang' => 'sv_SE', 'name' => 'Swedish', 'direction' => 'ltr'), - 'pl' => array('q' => 1, 'lang' => 'pl_PL', 'name' => 'Polish', 'direction' => 'ltr'), - 'mk' => array('q' => 1, 'lang' => 'mk_MK', 'name' => 'Macedonian', 'direction' => 'ltr'), - 'jp' => array('q' => 0.1, 'lang' => 'ja_JP', 'name' => 'Japanese', 'direction' => 'ltr'), - 'cs' => array('q' => 1, 'lang' => 'cs_CZ', 'name' => 'Czech', 'direction' => 'ltr'), - 'ca' => array('q' => 1, 'lang' => 'ca_ES', 'name' => 'Catalan', 'direction' => 'ltr'), -# 'hr' => array('q' => 0.1, 'lang' => 'he_IL', 'name' => 'Hebrew', 'direction' => 'ltr') - ); +/** + * returns a simple code -> name mapping for languages + * + * @return array map of available languages by code to language name. + */ + +function get_nice_language_list() +{ + $nice_lang = array(); + + $all_languages = common_config('site', 'languages'); + + foreach ($all_languages as $lang) { + $nice_lang = $nice_lang + array($lang['lang'] => $lang['name']); + } + return $nice_lang; +} + +/** + * Get a list of all languages that are enabled in the default config + * + * This should ONLY be called when setting up the default config in common.php. + * Any other attempt to get a list of lanugages should instead call + * common_config('site','languages') + * + * @return array mapping of language codes to language info + */ + +function get_all_languages() +{ + return + array('en-us' => array('q' => 1, 'lang' => 'en_US', + 'name' => 'English (US)', 'direction' => 'ltr'), + 'en-nz' => array('q' => 1, 'lang' => 'en_NZ', + 'name' => 'English (NZ)', 'direction' => 'ltr'), + 'en-gb' => array('q' => 1, 'lang' => 'en_GB', + 'name' => 'English (British)', 'direction' => 'ltr'), + 'en' => array('q' => 1, 'lang' => 'en', + 'name' => 'English', 'direction' => 'ltr'), + 'da' => array('q' => 0.1, 'lang' => 'da_DK', + 'name' => 'Danish', 'direction' => 'ltr'), + 'nl' => array('q' => 1, 'lang' => 'nl_NL', + 'name' => 'Dutch', 'direction' => 'ltr'), + 'eo' => array('q' => 0.1, 'lang' => 'eo', + 'name' => 'Esperanto', 'direction' => 'ltr'), + 'fr-fr' => array('q' => 0.9, 'lang' => 'fr_FR', + 'name' => 'French', 'direction' => 'ltr'), + 'de' => array('q' => 1, 'lang' => 'de_DE', + 'name' => 'German', 'direction' => 'ltr'), + 'it' => array('q' => 1, 'lang' => 'it_IT', + 'name' => 'Italian', 'direction' => 'ltr'), + 'ko' => array('q' => 0.1, 'lang' => 'ko', + 'name' => 'Korean', 'direction' => 'ltr'), + 'nb' => array('q' => 1, 'lang' => 'nb_NO', + 'name' => 'Norwegian (bokmal)', 'direction' => 'ltr'), + 'pt' => array('q' => 0.2, 'lang' => 'pt', + 'name' => 'Portuguese', 'direction' => 'ltr'), + 'pt-br' => array('q' => 1, 'lang' => 'pt_BR', + 'name' => 'Portuguese Brazil', 'direction' => 'ltr'), + 'es' => array('q' => 1, 'lang' => 'es', + 'name' => 'Spanish', 'direction' => 'ltr'), + 'tr' => array('q' => 1, 'lang' => 'tr_TR', + 'name' => 'Turkish', 'direction' => 'ltr'), + 'uk' => array('q' => 1, 'lang' => 'uk_UA', + 'name' => 'Ukrainian', 'direction' => 'ltr'), + 'pl' => array('q' => 1, 'lang' => 'pl_PL', + 'name' => 'Polish', 'direction' => 'ltr'), + 'mk' => array('q' => 1, 'lang' => 'mk_MK', + 'name' => 'Macedonian', 'direction' => 'ltr'), + 'jp' => array('q' => 0.1, 'lang' => 'ja_JP', + 'name' => 'Japanese', 'direction' => 'ltr'), + 'cs' => array('q' => 1, 'lang' => 'cs_CZ', + 'name' => 'Czech', 'direction' => 'ltr'), + 'ca' => array('q' => 1, 'lang' => 'ca_ES', + 'name' => 'Catalan', 'direction' => 'ltr'), + ); } diff --git a/_darcs/tentative_pristine b/_darcs/tentative_pristine index 402ea252ba..9b17c08d16 100644 --- a/_darcs/tentative_pristine +++ b/_darcs/tentative_pristine @@ -1,661 +1,205 @@ -hunk ./lib/jabber.php 2 +hunk ./lib/language.php 2 -/* - * Laconica - a distributed open-source microblogging tool - * Copyright (C) 2008, Controlez-Vous, Inc. +/** + * Laconica, the distributed open-source microblogging tool -hunk ./lib/jabber.php 5 +hunk ./lib/language.php 5 - * This program is free software: you can redistribute it and/or modify -+ * utility functions for Jabber/GTalk/XMPP messages ++ * utility functions for i18n + * + * PHP version 5 + * + * LICENCE: This program is free software: you can redistribute it and/or modify -hunk ./lib/jabber.php 21 +hunk ./lib/language.php 21 + * -+ * @category Network -+ * @package Laconica -+ * @author Evan Prodromou -+ * @copyright 2008 Control Yourself, Inc. -+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 -+ * @link http://laconi.ca/ -hunk ./lib/jabber.php 30 ++ * @category I18n ++ * @package Laconica ++ * @author Matthew Gregg ++ * @author Ciaran Gultnieks ++ * @author Evan Prodromou ++ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 ++ * @link http://laconi.ca/ +hunk ./lib/language.php 31 -if (!defined('LACONICA')) { exit(1); } +if (!defined('LACONICA')) { + exit(1); +} -hunk ./lib/jabber.php 34 --require_once('XMPPHP/XMPP.php'); -+require_once 'XMPPHP/XMPP.php'; -hunk ./lib/jabber.php 36 --function jabber_valid_base_jid($jid) { -- # Cheap but effective -- return Validate::email($jid); +hunk ./lib/language.php 35 +/** -+ * checks whether a string is a syntactically valid Jabber ID (JID) ++ * Content negotiation for language codes + * -+ * @param string $jid string to check ++ * @param string $httplang HTTP Accept-Language header + * -+ * @return boolean whether the string is a valid JID ++ * @return string language code for best language match + */ -+ -+function jabber_valid_base_jid($jid) +hunk ./lib/language.php 43 ++function client_prefered_language($httplang) +{ -+ // Cheap but effective -+ return Validate::email($jid); -hunk ./lib/jabber.php 50 --function jabber_normalize_jid($jid) { -- if (preg_match("/(?:([^\@]+)\@)?([^\/]+)(?:\/(.*))?$/", $jid, $matches)) { -- $node = $matches[1]; -- $server = $matches[2]; -- return strtolower($node.'@'.$server); -- } else { -- return NULL; -- } -+/** -+ * normalizes a Jabber ID for comparison -+ * -+ * @param string $jid JID to check -+ * -+ * @return string an equivalent JID in normalized (lowercase) form -+ */ -+ -+function jabber_normalize_jid($jid) -+{ -+ if (preg_match("/(?:([^\@]+)\@)?([^\/]+)(?:\/(.*))?$/", $jid, $matches)) { -+ $node = $matches[1]; -+ $server = $matches[2]; -+ return strtolower($node.'@'.$server); -+ } else { -+ return null; -+ } -hunk ./lib/jabber.php 69 --function jabber_daemon_address() { -- return common_config('xmpp', 'user') . '@' . common_config('xmpp', 'server'); -+/** -+ * the JID of the Jabber daemon for this Laconica instance -+ * -+ * @return string JID of the Jabber daemon -+ */ -+ -+function jabber_daemon_address() -+{ -+ return common_config('xmpp', 'user') . '@' . common_config('xmpp', 'server'); -hunk ./lib/jabber.php 80 --function jabber_connect($resource=NULL) { -- static $conn = NULL; -- if (!$conn) { -- $conn = new XMPPHP_XMPP(common_config('xmpp', 'host') ? -- common_config('xmpp', 'host') : -- common_config('xmpp', 'server'), -- common_config('xmpp', 'port'), -- common_config('xmpp', 'user'), -- common_config('xmpp', 'password'), -- ($resource) ? $resource : -- common_config('xmpp', 'resource'), -- common_config('xmpp', 'server'), -- common_config('xmpp', 'debug') ? -- true : false, -- common_config('xmpp', 'debug') ? -- XMPPHP_Log::LEVEL_VERBOSE : NULL -- ); -+/** -+ * connect the configured Jabber account to the configured server -+ * -+ * @param string $resource Resource to connect (defaults to configured resource) -+ * -+ * @return XMPPHP connection to the configured server -+ */ -+ -+function jabber_connect($resource=null) -+{ -+ static $conn = null; -+ if (!$conn) { -+ $conn = new XMPPHP_XMPP(common_config('xmpp', 'host') ? -+ common_config('xmpp', 'host') : -+ common_config('xmpp', 'server'), -+ common_config('xmpp', 'port'), -+ common_config('xmpp', 'user'), -+ common_config('xmpp', 'password'), -+ ($resource) ? $resource : -+ common_config('xmpp', 'resource'), -+ common_config('xmpp', 'server'), -+ common_config('xmpp', 'debug') ? -+ true : false, -+ common_config('xmpp', 'debug') ? -+ XMPPHP_Log::LEVEL_VERBOSE : null -+ ); -hunk ./lib/jabber.php 107 -- if (!$conn) { -- return false; -- } -+ if (!$conn) { -+ return false; ++ $client_langs = array(); +hunk ./lib/language.php 47 +-function client_prefered_language($httplang) { +- $client_langs = array(); +- $all_languages = common_config('site','languages'); ++ $all_languages = common_config('site', 'languages'); +hunk ./lib/language.php 49 +- preg_match_all('"(((\S\S)-?(\S\S)?)(;q=([0-9.]+))?)\s*(,\s*|$)"',strtolower($httplang),$httplang); +- for ($i = 0; $i < count($httplang); $i++) { +- if(!empty($httplang[2][$i])) { +- #if no q default to 1.0 +- $client_langs[$httplang[2][$i]] = ($httplang[6][$i]? (float) $httplang[6][$i] : 1.0); +- } +- if(!empty($httplang[3][$i]) && empty($client_langs[$httplang[3][$i]])) { +- #if a catchall default 0.01 lower +- $client_langs[$httplang[3][$i]] = ($httplang[6][$i]? (float) $httplang[6][$i]-0.01 : 0.99); +- } +- } +- #sort in decending q +- arsort($client_langs); ++ preg_match_all('"(((\S\S)-?(\S\S)?)(;q=([0-9.]+))?)\s*(,\s*|$)"', ++ strtolower($httplang), $httplang); +hunk ./lib/language.php 52 +- foreach ($client_langs as $lang => $q) { +- if (isset($all_languages[$lang])) { +- return($all_languages[$lang]['lang']); +- } +- } +- return FALSE; +-} ++ for ($i = 0; $i < count($httplang); $i++) { ++ if (!empty($httplang[2][$i])) { ++ // if no q default to 1.0 ++ $client_langs[$httplang[2][$i]] = ++ ($httplang[6][$i]? (float) $httplang[6][$i] : 1.0); + } -hunk ./lib/jabber.php 111 -- $conn->autoSubscribe(); -- $conn->useEncryption(common_config('xmpp', 'encryption')); -+ $conn->autoSubscribe(); -+ $conn->useEncryption(common_config('xmpp', 'encryption')); -hunk ./lib/jabber.php 114 -- try { -- $conn->connect(true); # true = persistent connection -- } catch (XMPPHP_Exception $e) { -- common_log(LOG_ERROR, $e->getMessage()); -- return false; -- } -+ try { -+ $conn->connect(true); // true = persistent connection -+ } catch (XMPPHP_Exception $e) { -+ common_log(LOG_ERROR, $e->getMessage()); -+ return false; -+ } -hunk ./lib/jabber.php 121 -- $conn->processUntil('session_start'); -- } -- return $conn; -+ $conn->processUntil('session_start'); -+ } -+ return $conn; -hunk ./lib/jabber.php 126 --function jabber_send_notice($to, $notice) { -- $conn = jabber_connect(); -- if (!$conn) { -- return false; -- } -- $profile = Profile::staticGet($notice->profile_id); -- if (!$profile) { -- common_log(LOG_WARNING, 'Refusing to send notice with ' . -- 'unknown profile ' . common_log_objstring($notice), -- __FILE__); -- return false; -- } -- $msg = jabber_format_notice($profile, $notice); -- $entry = jabber_format_entry($profile, $notice); -- $conn->message($to, $msg, 'chat', NULL, $entry); -- $profile->free(); -- return true; -+/** -+ * send a single notice to a given Jabber address -+ * -+ * @param string $to JID to send the notice to -+ * @param Notice $notice notice to send -+ * -+ * @return boolean success value -+ */ -+ -+function jabber_send_notice($to, $notice) -+{ -+ $conn = jabber_connect(); -+ if (!$conn) { -+ return false; -+ } -+ $profile = Profile::staticGet($notice->profile_id); -+ if (!$profile) { -+ common_log(LOG_WARNING, 'Refusing to send notice with ' . -+ 'unknown profile ' . common_log_objstring($notice), -+ __FILE__); -+ return false; -+ } -+ $msg = jabber_format_notice($profile, $notice); -+ $entry = jabber_format_entry($profile, $notice); -+ $conn->message($to, $msg, 'chat', null, $entry); -+ $profile->free(); -+ return true; -hunk ./lib/jabber.php 155 --# Extra stuff defined by Twitter, needed by twitter clients -+/** -+ * extra information for XMPP messages, as defined by Twitter -+ * -+ * @param Profile $profile Profile of the sending user -+ * @param Notice $notice Notice being sent -+ * -+ * @return string Extra information (Atom, HTML, addresses) in string format -+ */ -hunk ./lib/jabber.php 164 --function jabber_format_entry($profile, $notice) { -+function jabber_format_entry($profile, $notice) -+{ -+ // FIXME: notice url might be remote -hunk ./lib/jabber.php 168 -- # FIXME: notice url might be remote -+ $noticeurl = common_local_url('shownotice', -+ array('notice' => $notice->id)); -hunk ./lib/jabber.php 171 -- $noticeurl = common_local_url('shownotice', -- array('notice' => $notice->id)); -- $msg = jabber_format_notice($profile, $notice); -- $entry = "\n\n"; -- $entry .= "\n"; -- $entry .= "" . $profile->nickname . " - " . common_config('site', 'name') . "\n"; -- $entry .= "\n"; -- $entry .= " $profile->nickname)) . "'/>\n"; -- $entry .= "" . $profile->nickname . "\n"; -- $entry .= "" . common_profile_avatar_url($profile, AVATAR_PROFILE_SIZE) . "\n"; -- $entry .= "\n"; -- $entry .= "" . htmlspecialchars($msg) . "\n"; -- $entry .= "" . htmlspecialchars($msg) . "\n"; -- $entry .= "\n"; -- $entry .= "". $notice->uri . "\n"; -- $entry .= "".common_date_w3dtf($notice->created)."\n"; -- $entry .= "".common_date_w3dtf($notice->modified)."\n"; -- $entry .= "\n"; -+ $msg = jabber_format_notice($profile, $notice); -hunk ./lib/jabber.php 173 -- $html = "\n\n"; -- $html .= "\n"; -- $html .= "".$profile->nickname.": "; -- $html .= ($notice->rendered) ? $notice->rendered : common_render_content($notice->content, $notice); -- $html .= "\n\n"; -- $html .= "\n\n"; -+ $self_url = common_local_url('userrss', array('nickname' => $profile->nickname)); -hunk ./lib/jabber.php 175 -- $address = "\n"; -- $address .= "
\n"; -- $address .= "\n"; -+ $entry = "\n\n"; -+ $entry .= "\n"; -+ $entry .= "" . $profile->nickname . " - " . common_config('site', 'name') . "\n"; -+ $entry .= "\n"; -+ $entry .= "\n"; -+ $entry .= "" . $profile->nickname . "\n"; -+ $entry .= "" . common_profile_avatar_url($profile, AVATAR_PROFILE_SIZE) . "\n"; -+ $entry .= "\n"; -+ $entry .= "" . htmlspecialchars($msg) . "\n"; -+ $entry .= "" . htmlspecialchars($msg) . "\n"; -+ $entry .= "\n"; -+ $entry .= "". $notice->uri . "\n"; -+ $entry .= "".common_date_w3dtf($notice->created)."\n"; -+ $entry .= "".common_date_w3dtf($notice->modified)."\n"; -+ $entry .= "\n"; -hunk ./lib/jabber.php 191 -- # FIXME: include a pubsub event, too. -+ $html = "\n\n"; -+ $html .= "\n"; -+ $html .= "".$profile->nickname.": "; -+ $html .= ($notice->rendered) ? $notice->rendered : common_render_content($notice->content, $notice); -+ $html .= "\n\n"; -+ $html .= "\n\n"; -hunk ./lib/jabber.php 198 -- return $html . $entry . $address; -+ $address = "\n"; -+ $address .= "
\n"; -+ $address .= "\n"; -+ -+ // FIXME: include a pubsub event, too. -+ -+ return $html . $entry . $address; -hunk ./lib/jabber.php 207 --function jabber_send_message($to, $body, $type='chat', $subject=NULL) { -- $conn = jabber_connect(); -- if (!$conn) { -- return false; -- } -- $conn->message($to, $body, $type, $subject); -- return true; -+/** -+ * sends a single text message to a given JID -+ * -+ * @param string $to JID to send the message to -+ * @param string $body body of the message -+ * @param string $type type of the message -+ * @param string $subject subject of the message -+ * -+ * @return boolean success flag -+ */ -+ -+function jabber_send_message($to, $body, $type='chat', $subject=null) -+{ -+ $conn = jabber_connect(); -+ if (!$conn) { -+ return false; -+ } -+ $conn->message($to, $body, $type, $subject); -+ return true; -hunk ./lib/jabber.php 228 --function jabber_send_presence($status, $show='available', $to=NULL, -- $type = 'available', $priority=NULL) -+/** -+ * sends a presence stanza on the Jabber network -+ * -+ * @param string $status current status, free-form string -+ * @param string $show structured status value -+ * @param string $to recipient of presence, null for general -+ * @param string $type type of status message, related to $show -+ * @param int $priority priority of the presence -+ * -+ * @return boolean success value -+ */ -+ -+function jabber_send_presence($status, $show='available', $to=null, -+ $type = 'available', $priority=null) -hunk ./lib/jabber.php 243 -- $conn = jabber_connect(); -- if (!$conn) { -- return false; -- } -- $conn->presence($status, $show, $to, $type, $priority); -- return true; -+ $conn = jabber_connect(); -+ if (!$conn) { -+ return false; -+ } -+ $conn->presence($status, $show, $to, $type, $priority); -+ return true; -hunk ./lib/jabber.php 251 --function jabber_confirm_address($code, $nickname, $address) { -- $body = 'User "' . $nickname . '" on ' . common_config('site', 'name') . ' ' . -- 'has said that your Jabber ID belongs to them. ' . -- 'If that\'s true, you can confirm by clicking on this URL: ' . -- common_local_url('confirmaddress', array('code' => $code)) . -- ' . (If you cannot click it, copy-and-paste it into the ' . -- 'address bar of your browser). If that user isn\'t you, ' . -- 'or if you didn\'t request this confirmation, just ignore this message.'; -+/** -+ * sends a confirmation request to a JID -+ * -+ * @param string $code confirmation code for confirmation URL -+ * @param string $nickname nickname of confirming user -+ * @param string $address JID to send confirmation to -+ * -+ * @return boolean success flag -+ */ -+ -+function jabber_confirm_address($code, $nickname, $address) -+{ -+ $body = 'User "' . $nickname . '" on ' . common_config('site', 'name') . ' ' . -+ 'has said that your Jabber ID belongs to them. ' . -+ 'If that\'s true, you can confirm by clicking on this URL: ' . -+ common_local_url('confirmaddress', array('code' => $code)) . -+ ' . (If you cannot click it, copy-and-paste it into the ' . -+ 'address bar of your browser). If that user isn\'t you, ' . -+ 'or if you didn\'t request this confirmation, just ignore this message.'; -hunk ./lib/jabber.php 271 -- return jabber_send_message($address, $body); -+ return jabber_send_message($address, $body); -hunk ./lib/jabber.php 274 --function jabber_special_presence($type, $to=NULL, $show=NULL, $status=NULL) { -- $conn = jabber_connect(); -+/** -+ * sends a "special" presence stanza on the Jabber network -+ * -+ * @param string $type Type of presence -+ * @param string $to JID to send presence to -+ * @param string $show show value for presence -+ * @param string $status status value for presence -+ * -+ * @return boolean success flag -+ * -+ * @see jabber_send_presence() -+ */ -+ -+function jabber_special_presence($type, $to=null, $show=null, $status=null) -+{ -+ // FIXME: why use this instead of jabber_send_presence()? -+ $conn = jabber_connect(); -hunk ./lib/jabber.php 292 -- $to = htmlspecialchars($to); -- $status = htmlspecialchars($status); -- $out = "send($out); -+ $to = htmlspecialchars($to); -+ $status = htmlspecialchars($status); -+ -+ $out = "send($out); -hunk ./lib/jabber.php 317 --function jabber_broadcast_notice($notice) { -+/** -+ * broadcast a notice to all subscribers and reply recipients -+ * -+ * This function will send a notice to all subscribers on the local server -+ * who have Jabber addresses, and have Jabber notification enabled, and -+ * have this subscription enabled for Jabber. It also sends the notice to -+ * all recipients of @-replies who have Jabber addresses and Jabber notification -+ * enabled. This is really the heart of Jabber distribution in Laconica. -+ * -+ * @param Notice $notice The notice to broadcast -+ * -+ * @return boolean success flag -+ */ -hunk ./lib/jabber.php 331 -- if (!common_config('xmpp', 'enabled')) { -- return true; -- } -- $profile = Profile::staticGet($notice->profile_id); -+function jabber_broadcast_notice($notice) -+{ -+ if (!common_config('xmpp', 'enabled')) { -+ return true; -+ } -+ $profile = Profile::staticGet($notice->profile_id); -+ -+ if (!$profile) { -+ common_log(LOG_WARNING, 'Refusing to broadcast notice with ' . -+ 'unknown profile ' . common_log_objstring($notice), -+ __FILE__); -+ return false; -+ } -hunk ./lib/jabber.php 345 -- if (!$profile) { -- common_log(LOG_WARNING, 'Refusing to broadcast notice with ' . -- 'unknown profile ' . common_log_objstring($notice), -- __FILE__); -- return false; -- } -+ $msg = jabber_format_notice($profile, $notice); -+ $entry = jabber_format_entry($profile, $notice); -hunk ./lib/jabber.php 348 -- $msg = jabber_format_notice($profile, $notice); -- $entry = jabber_format_entry($profile, $notice); -+ $profile->free(); -+ unset($profile); -hunk ./lib/jabber.php 351 -- $profile->free(); -- unset($profile); -+ $sent_to = array(); -hunk ./lib/jabber.php 353 -- $sent_to = array(); -- $conn = jabber_connect(); -+ $conn = jabber_connect(); -hunk ./lib/jabber.php 355 -- # First, get users to whom this is a direct reply -- $user = new User(); -- $user->query('SELECT user.id, user.jabber ' . -- 'FROM user JOIN reply ON user.id = reply.profile_id ' . -- 'WHERE reply.notice_id = ' . $notice->id . ' ' . -- 'AND user.jabber is not null ' . -- 'AND user.jabbernotify = 1 ' . -- 'AND user.jabberreplies = 1 '); -+ // First, get users to whom this is a direct reply -+ $user = new User(); -+ $user->query('SELECT user.id, user.jabber ' . -+ 'FROM user JOIN reply ON user.id = reply.profile_id ' . -+ 'WHERE reply.notice_id = ' . $notice->id . ' ' . -+ 'AND user.jabber is not null ' . -+ 'AND user.jabbernotify = 1 ' . -+ 'AND user.jabberreplies = 1 '); -hunk ./lib/jabber.php 364 -- while ($user->fetch()) { -- common_log(LOG_INFO, -- 'Sending reply notice ' . $notice->id . ' to ' . $user->jabber, -- __FILE__); -- $conn->message($user->jabber, $msg, 'chat', NULL, $entry); -- $conn->processTime(0); -- $sent_to[$user->id] = 1; -- } -+ while ($user->fetch()) { -+ common_log(LOG_INFO, -+ 'Sending reply notice ' . $notice->id . ' to ' . $user->jabber, -+ __FILE__); -+ $conn->message($user->jabber, $msg, 'chat', null, $entry); -+ $conn->processTime(0); -+ $sent_to[$user->id] = 1; -+ } -hunk ./lib/jabber.php 373 -- $user->free(); -+ $user->free(); -hunk ./lib/jabber.php 375 -- # Now, get users subscribed to this profile -+ // Now, get users subscribed to this profile -hunk ./lib/jabber.php 377 -- $user = new User(); -- $user->query('SELECT user.id, user.jabber ' . -- 'FROM user JOIN subscription ON user.id = subscription.subscriber ' . -- 'WHERE subscription.subscribed = ' . $notice->profile_id . ' ' . -- 'AND user.jabber is not null ' . -- 'AND user.jabbernotify = 1 ' . -+ $user = new User(); -+ $user->query('SELECT user.id, user.jabber ' . -+ 'FROM user JOIN subscription ' . -+ 'ON user.id = subscription.subscriber ' . -+ 'WHERE subscription.subscribed = ' . $notice->profile_id . ' ' . -+ 'AND user.jabber is not null ' . -+ 'AND user.jabbernotify = 1 ' . -hunk ./lib/jabber.php 386 -- while ($user->fetch()) { -- if (!array_key_exists($user->id, $sent_to)) { -- common_log(LOG_INFO, -- 'Sending notice ' . $notice->id . ' to ' . $user->jabber, -- __FILE__); -- $conn->message($user->jabber, $msg, 'chat', NULL, $entry); -- # To keep the incoming queue from filling up, we service it after each send. -- $conn->processTime(0); -- } -- } -+ while ($user->fetch()) { -+ if (!array_key_exists($user->id, $sent_to)) { -+ common_log(LOG_INFO, -+ 'Sending notice ' . $notice->id . ' to ' . $user->jabber, -+ __FILE__); -+ $conn->message($user->jabber, $msg, 'chat', null, $entry); -+ // To keep the incoming queue from filling up, -+ // we service it after each send. -+ $conn->processTime(0); ++ if (!empty($httplang[3][$i]) && empty($client_langs[$httplang[3][$i]])) { ++ // if a catchall default 0.01 lower ++ $client_langs[$httplang[3][$i]] = ++ ($httplang[6][$i]? (float) $httplang[6][$i]-0.01 : 0.99); + } + } -hunk ./lib/jabber.php 398 -- $user->free(); -+ $user->free(); -hunk ./lib/jabber.php 400 -- return true; -+ return true; -hunk ./lib/jabber.php 403 --function jabber_public_notice($notice) { -+/** -+ * send a notice to all public listeners -+ * -+ * For notices that are generated on the local system (by users), we can optionally -+ * forward them to remote listeners by XMPP. -+ * -+ * @param Notice $notice notice to broadcast -+ * -+ * @return boolean success flag -+ */ -hunk ./lib/jabber.php 414 -- # Now, users who want everything -+function jabber_public_notice($notice) -+{ -+ // Now, users who want everything -hunk ./lib/jabber.php 418 -- $public = common_config('xmpp', 'public'); -+ $public = common_config('xmpp', 'public'); -hunk ./lib/jabber.php 420 -- # FIXME PRIV don't send out private messages here -- # XXX: should we send out non-local messages if public,localonly -- # = false? I think not -+ // FIXME PRIV don't send out private messages here -+ // XXX: should we send out non-local messages if public,localonly -+ // = false? I think not -hunk ./lib/jabber.php 424 -- if ($public && $notice->is_local) { -- $profile = Profile::staticGet($notice->profile_id); -+ if ($public && $notice->is_local) { -+ $profile = Profile::staticGet($notice->profile_id); -hunk ./lib/jabber.php 427 -- if (!$profile) { -- common_log(LOG_WARNING, 'Refusing to broadcast notice with ' . -- 'unknown profile ' . common_log_objstring($notice), -- __FILE__); -- return false; -- } -+ if (!$profile) { -+ common_log(LOG_WARNING, 'Refusing to broadcast notice with ' . -+ 'unknown profile ' . common_log_objstring($notice), -+ __FILE__); -+ return false; -+ } -hunk ./lib/jabber.php 434 -- $msg = jabber_format_notice($profile, $notice); -- $entry = jabber_format_entry($profile, $notice); -+ $msg = jabber_format_notice($profile, $notice); -+ $entry = jabber_format_entry($profile, $notice); -hunk ./lib/jabber.php 437 -- $conn = jabber_connect(); -+ $conn = jabber_connect(); -hunk ./lib/jabber.php 439 -- foreach ($public as $address) { -- common_log(LOG_INFO, -- 'Sending notice ' . $notice->id . ' to public listener ' . $address, -- __FILE__); -- $conn->message($address, $msg, 'chat', NULL, $entry); -- $conn->processTime(0); -- } -- $profile->free(); -- } -+ foreach ($public as $address) { -+ common_log(LOG_INFO, -+ 'Sending notice ' . $notice->id . -+ ' to public listener ' . $address, -+ __FILE__); -+ $conn->message($address, $msg, 'chat', null, $entry); -+ $conn->processTime(0); -+ } -+ $profile->free(); ++ // sort in decending q ++ arsort($client_langs); +hunk ./lib/language.php 67 +-function get_nice_language_list() { +- $nice_lang = array(); +- $all_languages = common_config('site','languages'); +- foreach ($all_languages as $lang) { +- $nice_lang = $nice_lang + array($lang['lang'] => $lang['name']); ++ foreach ($client_langs as $lang => $q) { ++ if (isset($all_languages[$lang])) { ++ return($all_languages[$lang]['lang']); +hunk ./lib/language.php 71 +- return $nice_lang; + } -hunk ./lib/jabber.php 450 -- return true; -+ return true; -hunk ./lib/jabber.php 453 --function jabber_format_notice(&$profile, &$notice) { -- return $profile->nickname . ': ' . $notice->content; ++ return false; +hunk ./lib/language.php 75 +-// Get a list of all languages that are enabled in the default config. This +-// should ONLY be called when setting up the default config in common.php. +-// Any other attempt to get a list of lanugages should instead call +-// common_config('site','languages') +-function get_all_languages() { +- return array( +- 'en-us' => array('q' => 1, 'lang' => 'en_US', 'name' => 'English (US)', 'direction' => 'ltr'), +- 'en-nz' => array('q' => 1, 'lang' => 'en_NZ', 'name' => 'English (NZ)', 'direction' => 'ltr'), +- 'en-gb' => array('q' => 1, 'lang' => 'en_GB', 'name' => 'English (British)', 'direction' => 'ltr'), +- 'en' => array('q' => 1, 'lang' => 'en', 'name' => 'English', 'direction' => 'ltr'), +- 'da' => array('q' => 0.1, 'lang' => 'da_DK', 'name' => 'Danish', 'direction' => 'ltr'), +- 'nl' => array('q' => 1, 'lang' => 'nl_NL', 'name' => 'Dutch', 'direction' => 'ltr'), +- 'eo' => array('q' => 0.1, 'lang' => 'eo', 'name' => 'Esperanto', 'direction' => 'ltr'), +- 'fr-fr' => array('q' => 0.9, 'lang' => 'fr_FR', 'name' => 'French', 'direction' => 'ltr'), +- 'de' => array('q' => 1, 'lang' => 'de_DE', 'name' => 'German', 'direction' => 'ltr'), +- 'it' => array('q' => 1, 'lang' => 'it_IT', 'name' => 'Italian', 'direction' => 'ltr'), +- 'ko' => array('q' => 0.1, 'lang' => 'ko', 'name' => 'Korean', 'direction' => 'ltr'), +- 'nb' => array('q' => 1, 'lang' => 'nb_NO', 'name' => 'Norwegian (bokmal)', 'direction' => 'ltr'), +- 'pt' => array('q' => 0.2, 'lang' => 'pt', 'name' => 'Portuguese', 'direction' => 'ltr'), +- 'pt-br' => array('q' => 1, 'lang' => 'pt_BR', 'name' => 'Portuguese Brazil', 'direction' => 'ltr'), +-# 'ru' => array('q' => 0.1, 'lang' => 'ru_RU', 'name' => 'Russian', 'direction' => 'ltr'), +- 'es' => array('q' => 1, 'lang' => 'es', 'name' => 'Spanish', 'direction' => 'ltr'), +- 'tr' => array('q' => 1, 'lang' => 'tr_TR', 'name' => 'Turkish', 'direction' => 'ltr'), +- 'uk' => array('q' => 1, 'lang' => 'uk_UA', 'name' => 'Ukrainian', 'direction' => 'ltr'), +-# 'lt' => array('q' => 0.1, 'lang' => 'lt_LT', 'name' => 'Lithuanian', 'direction' => 'ltr'), +-# 'sv' => array('q' => 1, 'lang' => 'sv_SE', 'name' => 'Swedish', 'direction' => 'ltr'), +- 'pl' => array('q' => 1, 'lang' => 'pl_PL', 'name' => 'Polish', 'direction' => 'ltr'), +- 'mk' => array('q' => 1, 'lang' => 'mk_MK', 'name' => 'Macedonian', 'direction' => 'ltr'), +- 'jp' => array('q' => 0.1, 'lang' => 'ja_JP', 'name' => 'Japanese', 'direction' => 'ltr'), +- 'cs' => array('q' => 1, 'lang' => 'cs_CZ', 'name' => 'Czech', 'direction' => 'ltr'), +- 'ca' => array('q' => 1, 'lang' => 'ca_ES', 'name' => 'Catalan', 'direction' => 'ltr'), +-# 'hr' => array('q' => 0.1, 'lang' => 'he_IL', 'name' => 'Hebrew', 'direction' => 'ltr') +- ); +/** -+ * makes a plain-text formatted version of a notice, suitable for Jabber distribution ++ * returns a simple code -> name mapping for languages + * -+ * @param Profile &$profile profile of the sending user -+ * @param Notice &$notice notice being sent -+ * -+ * @return string plain-text version of the notice, with user nickname prefixed ++ * @return array map of available languages by code to language name. + */ + -+function jabber_format_notice(&$profile, &$notice) ++function get_nice_language_list() +{ -+ return $profile->nickname . ': ' . $notice->content; ++ $nice_lang = array(); ++ ++ $all_languages = common_config('site', 'languages'); ++ ++ foreach ($all_languages as $lang) { ++ $nice_lang = $nice_lang + array($lang['lang'] => $lang['name']); ++ } ++ return $nice_lang; ++} ++ ++/** ++ * Get a list of all languages that are enabled in the default config ++ * ++ * This should ONLY be called when setting up the default config in common.php. ++ * Any other attempt to get a list of lanugages should instead call ++ * common_config('site','languages') ++ * ++ * @return array mapping of language codes to language info ++ */ ++ ++function get_all_languages() ++{ ++ return ++ array('en-us' => array('q' => 1, 'lang' => 'en_US', ++ 'name' => 'English (US)', 'direction' => 'ltr'), ++ 'en-nz' => array('q' => 1, 'lang' => 'en_NZ', ++ 'name' => 'English (NZ)', 'direction' => 'ltr'), ++ 'en-gb' => array('q' => 1, 'lang' => 'en_GB', ++ 'name' => 'English (British)', 'direction' => 'ltr'), ++ 'en' => array('q' => 1, 'lang' => 'en', ++ 'name' => 'English', 'direction' => 'ltr'), ++ 'da' => array('q' => 0.1, 'lang' => 'da_DK', ++ 'name' => 'Danish', 'direction' => 'ltr'), ++ 'nl' => array('q' => 1, 'lang' => 'nl_NL', ++ 'name' => 'Dutch', 'direction' => 'ltr'), ++ 'eo' => array('q' => 0.1, 'lang' => 'eo', ++ 'name' => 'Esperanto', 'direction' => 'ltr'), ++ 'fr-fr' => array('q' => 0.9, 'lang' => 'fr_FR', ++ 'name' => 'French', 'direction' => 'ltr'), ++ 'de' => array('q' => 1, 'lang' => 'de_DE', ++ 'name' => 'German', 'direction' => 'ltr'), ++ 'it' => array('q' => 1, 'lang' => 'it_IT', ++ 'name' => 'Italian', 'direction' => 'ltr'), ++ 'ko' => array('q' => 0.1, 'lang' => 'ko', ++ 'name' => 'Korean', 'direction' => 'ltr'), ++ 'nb' => array('q' => 1, 'lang' => 'nb_NO', ++ 'name' => 'Norwegian (bokmal)', 'direction' => 'ltr'), ++ 'pt' => array('q' => 0.2, 'lang' => 'pt', ++ 'name' => 'Portuguese', 'direction' => 'ltr'), ++ 'pt-br' => array('q' => 1, 'lang' => 'pt_BR', ++ 'name' => 'Portuguese Brazil', 'direction' => 'ltr'), ++ 'es' => array('q' => 1, 'lang' => 'es', ++ 'name' => 'Spanish', 'direction' => 'ltr'), ++ 'tr' => array('q' => 1, 'lang' => 'tr_TR', ++ 'name' => 'Turkish', 'direction' => 'ltr'), ++ 'uk' => array('q' => 1, 'lang' => 'uk_UA', ++ 'name' => 'Ukrainian', 'direction' => 'ltr'), ++ 'pl' => array('q' => 1, 'lang' => 'pl_PL', ++ 'name' => 'Polish', 'direction' => 'ltr'), ++ 'mk' => array('q' => 1, 'lang' => 'mk_MK', ++ 'name' => 'Macedonian', 'direction' => 'ltr'), ++ 'jp' => array('q' => 0.1, 'lang' => 'ja_JP', ++ 'name' => 'Japanese', 'direction' => 'ltr'), ++ 'cs' => array('q' => 1, 'lang' => 'cs_CZ', ++ 'name' => 'Czech', 'direction' => 'ltr'), ++ 'ca' => array('q' => 1, 'lang' => 'ca_ES', ++ 'name' => 'Catalan', 'direction' => 'ltr'), ++ ); diff --git a/lib/language.php b/lib/language.php index 796e28870d..1d00cc31e1 100644 --- a/lib/language.php +++ b/lib/language.php @@ -1,9 +1,12 @@ . + * + * @category I18n + * @package Laconica + * @author Matthew Gregg + * @author Ciaran Gultnieks + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ */ -if (!defined('LACONICA')) { exit(1); } - - - -function client_prefered_language($httplang) { - $client_langs = array(); - $all_languages = common_config('site','languages'); - - preg_match_all('"(((\S\S)-?(\S\S)?)(;q=([0-9.]+))?)\s*(,\s*|$)"',strtolower($httplang),$httplang); - for ($i = 0; $i < count($httplang); $i++) { - if(!empty($httplang[2][$i])) { - #if no q default to 1.0 - $client_langs[$httplang[2][$i]] = ($httplang[6][$i]? (float) $httplang[6][$i] : 1.0); - } - if(!empty($httplang[3][$i]) && empty($client_langs[$httplang[3][$i]])) { - #if a catchall default 0.01 lower - $client_langs[$httplang[3][$i]] = ($httplang[6][$i]? (float) $httplang[6][$i]-0.01 : 0.99); - } - } - #sort in decending q - arsort($client_langs); - - foreach ($client_langs as $lang => $q) { - if (isset($all_languages[$lang])) { - return($all_languages[$lang]['lang']); - } - } - return FALSE; +if (!defined('LACONICA')) { + exit(1); } -function get_nice_language_list() { - $nice_lang = array(); - $all_languages = common_config('site','languages'); - foreach ($all_languages as $lang) { - $nice_lang = $nice_lang + array($lang['lang'] => $lang['name']); +/** + * Content negotiation for language codes + * + * @param string $httplang HTTP Accept-Language header + * + * @return string language code for best language match + */ + +function client_prefered_language($httplang) +{ + $client_langs = array(); + + $all_languages = common_config('site', 'languages'); + + preg_match_all('"(((\S\S)-?(\S\S)?)(;q=([0-9.]+))?)\s*(,\s*|$)"', + strtolower($httplang), $httplang); + + for ($i = 0; $i < count($httplang); $i++) { + if (!empty($httplang[2][$i])) { + // if no q default to 1.0 + $client_langs[$httplang[2][$i]] = + ($httplang[6][$i]? (float) $httplang[6][$i] : 1.0); } - return $nice_lang; + if (!empty($httplang[3][$i]) && empty($client_langs[$httplang[3][$i]])) { + // if a catchall default 0.01 lower + $client_langs[$httplang[3][$i]] = + ($httplang[6][$i]? (float) $httplang[6][$i]-0.01 : 0.99); + } + } + // sort in decending q + arsort($client_langs); + + foreach ($client_langs as $lang => $q) { + if (isset($all_languages[$lang])) { + return($all_languages[$lang]['lang']); + } + } + return false; } -// Get a list of all languages that are enabled in the default config. This -// should ONLY be called when setting up the default config in common.php. -// Any other attempt to get a list of lanugages should instead call -// common_config('site','languages') -function get_all_languages() { - return array( - 'en-us' => array('q' => 1, 'lang' => 'en_US', 'name' => 'English (US)', 'direction' => 'ltr'), - 'en-nz' => array('q' => 1, 'lang' => 'en_NZ', 'name' => 'English (NZ)', 'direction' => 'ltr'), - 'en-gb' => array('q' => 1, 'lang' => 'en_GB', 'name' => 'English (British)', 'direction' => 'ltr'), - 'en' => array('q' => 1, 'lang' => 'en', 'name' => 'English', 'direction' => 'ltr'), - 'da' => array('q' => 0.1, 'lang' => 'da_DK', 'name' => 'Danish', 'direction' => 'ltr'), - 'nl' => array('q' => 1, 'lang' => 'nl_NL', 'name' => 'Dutch', 'direction' => 'ltr'), - 'eo' => array('q' => 0.1, 'lang' => 'eo', 'name' => 'Esperanto', 'direction' => 'ltr'), - 'fr-fr' => array('q' => 0.9, 'lang' => 'fr_FR', 'name' => 'French', 'direction' => 'ltr'), - 'de' => array('q' => 1, 'lang' => 'de_DE', 'name' => 'German', 'direction' => 'ltr'), - 'it' => array('q' => 1, 'lang' => 'it_IT', 'name' => 'Italian', 'direction' => 'ltr'), - 'ko' => array('q' => 0.1, 'lang' => 'ko', 'name' => 'Korean', 'direction' => 'ltr'), - 'nb' => array('q' => 1, 'lang' => 'nb_NO', 'name' => 'Norwegian (bokmal)', 'direction' => 'ltr'), - 'pt' => array('q' => 0.2, 'lang' => 'pt', 'name' => 'Portuguese', 'direction' => 'ltr'), - 'pt-br' => array('q' => 1, 'lang' => 'pt_BR', 'name' => 'Portuguese Brazil', 'direction' => 'ltr'), -# 'ru' => array('q' => 0.1, 'lang' => 'ru_RU', 'name' => 'Russian', 'direction' => 'ltr'), - 'es' => array('q' => 1, 'lang' => 'es', 'name' => 'Spanish', 'direction' => 'ltr'), - 'tr' => array('q' => 1, 'lang' => 'tr_TR', 'name' => 'Turkish', 'direction' => 'ltr'), - 'uk' => array('q' => 1, 'lang' => 'uk_UA', 'name' => 'Ukrainian', 'direction' => 'ltr'), -# 'lt' => array('q' => 0.1, 'lang' => 'lt_LT', 'name' => 'Lithuanian', 'direction' => 'ltr'), -# 'sv' => array('q' => 1, 'lang' => 'sv_SE', 'name' => 'Swedish', 'direction' => 'ltr'), - 'pl' => array('q' => 1, 'lang' => 'pl_PL', 'name' => 'Polish', 'direction' => 'ltr'), - 'mk' => array('q' => 1, 'lang' => 'mk_MK', 'name' => 'Macedonian', 'direction' => 'ltr'), - 'jp' => array('q' => 0.1, 'lang' => 'ja_JP', 'name' => 'Japanese', 'direction' => 'ltr'), - 'cs' => array('q' => 1, 'lang' => 'cs_CZ', 'name' => 'Czech', 'direction' => 'ltr'), - 'ca' => array('q' => 1, 'lang' => 'ca_ES', 'name' => 'Catalan', 'direction' => 'ltr'), -# 'hr' => array('q' => 0.1, 'lang' => 'he_IL', 'name' => 'Hebrew', 'direction' => 'ltr') - ); +/** + * returns a simple code -> name mapping for languages + * + * @return array map of available languages by code to language name. + */ + +function get_nice_language_list() +{ + $nice_lang = array(); + + $all_languages = common_config('site', 'languages'); + + foreach ($all_languages as $lang) { + $nice_lang = $nice_lang + array($lang['lang'] => $lang['name']); + } + return $nice_lang; +} + +/** + * Get a list of all languages that are enabled in the default config + * + * This should ONLY be called when setting up the default config in common.php. + * Any other attempt to get a list of lanugages should instead call + * common_config('site','languages') + * + * @return array mapping of language codes to language info + */ + +function get_all_languages() +{ + return + array('en-us' => array('q' => 1, 'lang' => 'en_US', + 'name' => 'English (US)', 'direction' => 'ltr'), + 'en-nz' => array('q' => 1, 'lang' => 'en_NZ', + 'name' => 'English (NZ)', 'direction' => 'ltr'), + 'en-gb' => array('q' => 1, 'lang' => 'en_GB', + 'name' => 'English (British)', 'direction' => 'ltr'), + 'en' => array('q' => 1, 'lang' => 'en', + 'name' => 'English', 'direction' => 'ltr'), + 'da' => array('q' => 0.1, 'lang' => 'da_DK', + 'name' => 'Danish', 'direction' => 'ltr'), + 'nl' => array('q' => 1, 'lang' => 'nl_NL', + 'name' => 'Dutch', 'direction' => 'ltr'), + 'eo' => array('q' => 0.1, 'lang' => 'eo', + 'name' => 'Esperanto', 'direction' => 'ltr'), + 'fr-fr' => array('q' => 0.9, 'lang' => 'fr_FR', + 'name' => 'French', 'direction' => 'ltr'), + 'de' => array('q' => 1, 'lang' => 'de_DE', + 'name' => 'German', 'direction' => 'ltr'), + 'it' => array('q' => 1, 'lang' => 'it_IT', + 'name' => 'Italian', 'direction' => 'ltr'), + 'ko' => array('q' => 0.1, 'lang' => 'ko', + 'name' => 'Korean', 'direction' => 'ltr'), + 'nb' => array('q' => 1, 'lang' => 'nb_NO', + 'name' => 'Norwegian (bokmal)', 'direction' => 'ltr'), + 'pt' => array('q' => 0.2, 'lang' => 'pt', + 'name' => 'Portuguese', 'direction' => 'ltr'), + 'pt-br' => array('q' => 1, 'lang' => 'pt_BR', + 'name' => 'Portuguese Brazil', 'direction' => 'ltr'), + 'es' => array('q' => 1, 'lang' => 'es', + 'name' => 'Spanish', 'direction' => 'ltr'), + 'tr' => array('q' => 1, 'lang' => 'tr_TR', + 'name' => 'Turkish', 'direction' => 'ltr'), + 'uk' => array('q' => 1, 'lang' => 'uk_UA', + 'name' => 'Ukrainian', 'direction' => 'ltr'), + 'pl' => array('q' => 1, 'lang' => 'pl_PL', + 'name' => 'Polish', 'direction' => 'ltr'), + 'mk' => array('q' => 1, 'lang' => 'mk_MK', + 'name' => 'Macedonian', 'direction' => 'ltr'), + 'jp' => array('q' => 0.1, 'lang' => 'ja_JP', + 'name' => 'Japanese', 'direction' => 'ltr'), + 'cs' => array('q' => 1, 'lang' => 'cs_CZ', + 'name' => 'Czech', 'direction' => 'ltr'), + 'ca' => array('q' => 1, 'lang' => 'ca_ES', + 'name' => 'Catalan', 'direction' => 'ltr'), + ); }