X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=lib%2Futil.php;h=76639e2d40298bed935e2e9bc8658132d00576ef;hb=60e0f0426133544eaaea7ff84da5f02ca86bd8cc;hp=32061ec04ce037f55a6e4471e9092ecf96c411d8;hpb=dced92d6fde00d7a5609aba780fcfeac7c2b2fe0;p=quix0rs-gnu-social.git diff --git a/lib/util.php b/lib/util.php index 32061ec04c..76639e2d40 100644 --- a/lib/util.php +++ b/lib/util.php @@ -52,17 +52,43 @@ function common_init_language() { mb_internal_encoding('UTF-8'); - // gettext seems very picky... We first need to setlocale() - // to a locale which _does_ exist on the system, and _then_ - // we can set in another locale that may not be set up - // (say, ga_ES for Galego/Galician) it seems to take it. - common_init_locale("en_US"); - // Note that this setlocale() call may "fail" but this is harmless; // gettext will still select the right language. $language = common_language(); $locale_set = common_init_locale($language); + if (!$locale_set) { + // The requested locale doesn't exist on the system. + // + // gettext seems very picky... We first need to setlocale() + // to a locale which _does_ exist on the system, and _then_ + // we can set in another locale that may not be set up + // (say, ga_ES for Galego/Galician) it seems to take it. + // + // For some reason C and POSIX which are guaranteed to work + // don't do the job. en_US.UTF-8 should be there most of the + // time, but not guaranteed. + $ok = common_init_locale("en_US"); + if (!$ok) { + // Try to find a complete, working locale... + // @fixme shelling out feels awfully inefficient + // but I don't think there's a more standard way. + $all = `locale -a`; + foreach (explode("\n", $all) as $locale) { + if (preg_match('/\.utf[-_]?8$/i', $locale)) { + $ok = setlocale(LC_ALL, $locale); + if ($ok) { + break; + } + } + } + if (!$ok) { + common_log(LOG_ERR, "Unable to find a UTF-8 locale on this system; UI translations may not work."); + } + } + $locale_set = common_init_locale($language); + } + setlocale(LC_CTYPE, 'C'); // So we do not have to make people install the gettext locales $path = common_config('site','locale_path'); @@ -105,11 +131,13 @@ function common_language() // Otherwise, find the best match for the languages requested by the // user's browser... - $httplang = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : null; - if (!empty($httplang)) { - $language = client_prefered_language($httplang); - if ($language) - return $language; + if (common_config('site', 'langdetect')) { + $httplang = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : null; + if (!empty($httplang)) { + $language = client_prefered_language($httplang); + if ($language) + return $language; + } } // Finally, if none of the above worked, use the site's default... @@ -426,14 +454,14 @@ function common_render_content($text, $notice) { $r = common_render_text($text); $id = $notice->profile_id; - $r = common_linkify_mentions($id, $r); + $r = common_linkify_mentions($r, $notice); $r = preg_replace('/(^|[\s\.\,\:\;]+)!([A-Za-z0-9]{1,64})/e', "'\\1!'.common_group_link($id, '\\2')", $r); return $r; } -function common_linkify_mentions($profile_id, $text) +function common_linkify_mentions($text, $notice) { - $mentions = common_find_mentions($profile_id, $text); + $mentions = common_find_mentions($text, $notice); // We need to go through in reverse order by position, // so our positions stay valid despite our fudging with the @@ -487,11 +515,11 @@ function common_linkify_mention($mention) return $output; } -function common_find_mentions($profile_id, $text) +function common_find_mentions($text, $notice) { $mentions = array(); - $sender = Profile::staticGet('id', $profile_id); + $sender = Profile::staticGet('id', $notice->profile_id); if (empty($sender)) { return $mentions; @@ -499,6 +527,30 @@ function common_find_mentions($profile_id, $text) if (Event::handle('StartFindMentions', array($sender, $text, &$mentions))) { + // Get the context of the original notice, if any + + $originalAuthor = null; + $originalNotice = null; + $originalMentions = array(); + + // Is it a reply? + + if (!empty($notice) && !empty($notice->reply_to)) { + $originalNotice = Notice::staticGet('id', $notice->reply_to); + if (!empty($originalNotice)) { + $originalAuthor = Profile::staticGet('id', $originalNotice->profile_id); + + $ids = $originalNotice->getReplies(); + + foreach ($ids as $id) { + $repliedTo = Profile::staticGet('id', $id); + if (!empty($repliedTo)) { + $originalMentions[$repliedTo->nickname] = $repliedTo; + } + } + } + } + preg_match_all('/^T ([A-Z0-9]{1,64}) /', $text, $tmatches, @@ -514,7 +566,22 @@ function common_find_mentions($profile_id, $text) foreach ($matches as $match) { $nickname = common_canonical_nickname($match[0]); - $mentioned = common_relative_profile($sender, $nickname); + + // Try to get a profile for this nickname. + // Start with conversation context, then go to + // sender context. + + if (!empty($originalAuthor) && $originalAuthor->nickname == $nickname) { + + $mentioned = $originalAuthor; + + } else if (!empty($originalMentions) && + array_key_exists($nickname, $originalMentions)) { + + $mentioned = $originalMentions[$nickname]; + } else { + $mentioned = common_relative_profile($sender, $nickname); + } if (!empty($mentioned)) { @@ -731,20 +798,13 @@ function common_linkify($url) { } if (!empty($f)) { - if ($f->isEnclosure()) { + if ($f->getEnclosure()) { $is_attachment = true; $attachment_id = $f->id; - } else { - $foe = File_oembed::staticGet('file_id', $f->id); - if (!empty($foe)) { - // if it has OEmbed info, it's an attachment, too - $is_attachment = true; - $attachment_id = $f->id; - - $thumb = File_thumbnail::staticGet('file_id', $f->id); - if (!empty($thumb)) { - $has_thumb = true; - } + + $thumb = File_thumbnail::staticGet('file_id', $f->id); + if (!empty($thumb)) { + $has_thumb = true; } } } @@ -770,8 +830,28 @@ function common_shorten_links($text) function common_xml_safe_str($str) { - // Neutralize control codes and surrogates - return preg_replace('/[\p{Cc}\p{Cs}]/u', '*', $str); + // Replace common eol and extra whitespace input chars + $unWelcome = array( + "\t", // tab + "\n", // newline + "\r", // cr + "\0", // null byte eos + "\x0B" // vertical tab + ); + + $replacement = array( + ' ', // single space + ' ', + '', // nothing + '', + ' ' + ); + + $str = str_replace($unWelcome, $replacement, $str); + + // Neutralize any additional control codes and UTF-16 surrogates + // (Twitter uses '*') + return preg_replace('/[\p{Cc}\p{Cs}]/u', '*', $str); } function common_tag_link($tag) @@ -801,7 +881,7 @@ function common_valid_profile_tag($str) function common_group_link($sender_id, $nickname) { $sender = Profile::staticGet($sender_id); - $group = User_group::getForNickname($nickname); + $group = User_group::getForNickname($nickname, $sender); if ($sender && $group && $sender->isMember($group)) { $attrs = array('href' => $group->permalink(), 'class' => 'url');