]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - lib/util.php
Merge branch '0.9.x' into 1.0.x
[quix0rs-gnu-social.git] / lib / util.php
index 9c50d9931fa258471f9b72c7940fdef2ee044ca4..a7f43b5d4f23f5a978b756bc2519023d52979260 100644 (file)
@@ -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...
@@ -131,10 +159,15 @@ function common_munge_password($password, $id)
 
 function common_check_user($nickname, $password)
 {
+    // empty nickname always unacceptable
+    if (empty($nickname)) {
+        return false;
+    }
+
     $authenticatedUser = false;
 
     if (Event::handle('StartCheckPassword', array($nickname, $password, &$authenticatedUser))) {
-        $user = User::staticGet('nickname', $nickname);
+        $user = User::staticGet('nickname', common_canonical_nickname($nickname));
         if (!empty($user)) {
             if (!empty($password)) { // never allow login with blank password
                 if (0 == strcmp(common_munge_password($password, $user->id),
@@ -426,14 +459,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 +520,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 +532,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 +571,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 +803,13 @@ function common_linkify($url) {
     }
 
     if (!empty($f)) {
-        if ($f->isEnclosure()) {
+        if ($f->getEnclosure() || File_oembed::staticGet('file_id',$f->id)) {
             $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 +835,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 +886,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');
@@ -856,7 +941,7 @@ function common_relative_profile($sender, $nickname, $dt=null)
     return null;
 }
 
-function common_local_url($action, $args=null, $params=null, $fragment=null)
+function common_local_url($action, $args=null, $params=null, $fragment=null, $addSession=true)
 {
     $r = Router::get();
     $path = $r->build($action, $args, $params, $fragment);
@@ -864,12 +949,12 @@ function common_local_url($action, $args=null, $params=null, $fragment=null)
     $ssl = common_is_sensitive($action);
 
     if (common_config('site','fancy')) {
-        $url = common_path(mb_substr($path, 1), $ssl);
+        $url = common_path(mb_substr($path, 1), $ssl, $addSession);
     } else {
         if (mb_strpos($path, '/index.php') === 0) {
-            $url = common_path(mb_substr($path, 1), $ssl);
+            $url = common_path(mb_substr($path, 1), $ssl, $addSession);
         } else {
-            $url = common_path('index.php'.$path, $ssl);
+            $url = common_path('index.php'.$path, $ssl, $addSession);
         }
     }
     return $url;
@@ -888,7 +973,7 @@ function common_is_sensitive($action)
     return $ssl;
 }
 
-function common_path($relative, $ssl=false)
+function common_path($relative, $ssl=false, $addSession=true)
 {
     $pathpart = (common_config('site', 'path')) ? common_config('site', 'path')."/" : '';
 
@@ -912,7 +997,9 @@ function common_path($relative, $ssl=false)
         }
     }
 
-    $relative = common_inject_session($relative, $serverpart);
+    if ($addSession) {
+        $relative = common_inject_session($relative, $serverpart);
+    }
 
     return $proto.'://'.$serverpart.'/'.$pathpart.$relative;
 }
@@ -1089,19 +1176,10 @@ function common_enqueue_notice($notice)
         $transports[] = 'plugin';
     }
 
-    $xmpp = common_config('xmpp', 'enabled');
-
-    if ($xmpp) {
-        $transports[] = 'jabber';
-    }
-
     // @fixme move these checks into QueueManager and/or individual handlers
     if ($notice->is_local == Notice::LOCAL_PUBLIC ||
         $notice->is_local == Notice::LOCAL_NONPUBLIC) {
         $transports = array_merge($transports, $localTransports);
-        if ($xmpp) {
-            $transports[] = 'public';
-        }
     }
 
     if (Event::handle('StartEnqueueNotice', array($notice, &$transports))) {
@@ -1134,14 +1212,15 @@ function common_broadcast_profile(Profile $profile)
 
 function common_profile_url($nickname)
 {
-    return common_local_url('showstream', array('nickname' => $nickname));
+    return common_local_url('showstream', array('nickname' => $nickname),
+                            null, null, false);
 }
 
 // Should make up a reasonable root URL
 
 function common_root_url($ssl=false)
 {
-    $url = common_path('', $ssl);
+    $url = common_path('', $ssl, false);
     $i = strpos($url, '?');
     if ($i !== false) {
         $url = substr($url, 0, $i);
@@ -1405,7 +1484,15 @@ function common_copy_args($from)
     $to = array();
     $strip = get_magic_quotes_gpc();
     foreach ($from as $k => $v) {
-        $to[$k] = ($strip) ? stripslashes($v) : $v;
+        if($strip) {
+            if(is_array($v)) {
+                $to[$k] = common_copy_args($v);
+            } else {
+                $to[$k] = stripslashes($v);
+            }
+        } else {
+            $to[$k] = $v;
+        }
     }
     return $to;
 }
@@ -1426,13 +1513,15 @@ function common_remove_magic_from_request()
 
 function common_user_uri(&$user)
 {
-    return common_local_url('userbyid', array('id' => $user->id));
+    return common_local_url('userbyid', array('id' => $user->id),
+                            null, null, false);
 }
 
 function common_notice_uri(&$notice)
 {
     return common_local_url('shownotice',
-                            array('notice' => $notice->id));
+                            array('notice' => $notice->id),
+                            null, null, false);
 }
 
 // 36 alphanums - lookalikes (0, O, 1, I) = 32 chars = 5 bits
@@ -1698,7 +1787,8 @@ function common_url_to_nickname($url)
             # Strip starting, ending slashes
             $path = preg_replace('@/$@', '', $parts['path']);
             $path = preg_replace('@^/@', '', $path);
-            if (strpos($path, '/') === false) {
+            $path = basename($path);
+            if ($path) {
                 return common_nicknamize($path);
             }
         }