]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - lib/util.php
Make StatusNet::initDefaults() public so we can call it from the installer.
[quix0rs-gnu-social.git] / lib / util.php
index a5e29a7818cf2e8215795205c8a42cce750b64bc..85d7c72f453fb59b58ecd671bb975409b17b081d 100644 (file)
 
 /* XXX: break up into separate modules (HTTP, user, files) */
 
-// Show a server error
-
+/**
+ * Show a server error.
+ */
 function common_server_error($msg, $code=500)
 {
     $err = new ServerErrorAction($msg, $code);
     $err->showPage();
 }
 
-// Show a user error
+/**
+ * Show a user error.
+ */
 function common_user_error($msg, $code=400)
 {
     $err = new ClientErrorAction($msg, $code);
@@ -203,8 +206,10 @@ function common_language()
     // Finally, if none of the above worked, use the site's default...
     return common_config('site', 'language');
 }
-// salted, hashed passwords are stored in the DB
 
+/**
+ * Salted, hashed passwords are stored in the DB.
+ */
 function common_munge_password($password, $id)
 {
     if (is_object($id) || is_object($password)) {
@@ -215,8 +220,9 @@ function common_munge_password($password, $id)
     return md5($password . $id);
 }
 
-// check if a username exists and has matching password
-
+/**
+ * Check if a username exists and has matching password.
+ */
 function common_check_user($nickname, $password)
 {
     // empty nickname always unacceptable
@@ -243,7 +249,9 @@ function common_check_user($nickname, $password)
     return $authenticatedUser;
 }
 
-// is the current user logged in?
+/**
+ * Is the current user logged in?
+ */
 function common_logged_in()
 {
     return (!is_null(common_current_user()));
@@ -289,12 +297,10 @@ function common_ensure_session()
 // 3) null to clear
 
 // Initialize to false; set to null if none found
-
 $_cur = false;
 
 function common_set_user($user)
 {
-
     global $_cur;
 
     if (is_null($user) && common_have_session()) {
@@ -380,7 +386,6 @@ function common_rememberme($user=null)
 
 function common_remembered_user()
 {
-
     $user = null;
 
     $packed = isset($_COOKIE[REMEMBERME]) ? $_COOKIE[REMEMBERME] : null;
@@ -442,14 +447,17 @@ function common_remembered_user()
     return $user;
 }
 
-// must be called with a valid user!
-
+/**
+ * must be called with a valid user!
+ */
 function common_forgetme()
 {
     common_set_cookie(REMEMBERME, '', 0);
 }
 
-// who is the current user?
+/**
+ * Who is the current user?
+ */
 function common_current_user()
 {
     global $_cur;
@@ -485,10 +493,11 @@ function common_current_user()
     return $_cur;
 }
 
-// Logins that are 'remembered' aren't 'real' -- they're subject to
-// cookie-stealing. So, we don't let them do certain things. New reg,
-// OpenID, and password logins _are_ real.
-
+/**
+ * Logins that are 'remembered' aren't 'real' -- they're subject to
+ * cookie-stealing. So, we don't let them do certain things. New reg,
+ * OpenID, and password logins _are_ real.
+ */
 function common_real_login($real=true)
 {
     common_ensure_session();
@@ -500,6 +509,29 @@ function common_is_real_login()
     return common_logged_in() && $_SESSION['real_login'];
 }
 
+/**
+ * Get a hash portion for HTTP caching Etags and such including
+ * info on the current user's session. If login/logout state changes,
+ * or we've changed accounts, or we've renamed the current user,
+ * we'll get a new hash value.
+ *
+ * This should not be considered secure information.
+ *
+ * @param User $user (optional; uses common_current_user() if left out)
+ * @return string
+ */
+function common_user_cache_hash($user=false)
+{
+    if ($user === false) {
+        $user = common_current_user();
+    }
+    if ($user) {
+        return crc32($user->id . ':' . $user->nickname);
+    } else {
+        return '0';
+    }
+}
+
 // get canonical version of nickname for comparison
 function common_canonical_nickname($nickname)
 {
@@ -591,9 +623,7 @@ function common_find_mentions($text, $notice)
     }
 
     if (Event::handle('StartFindMentions', array($sender, $text, &$mentions))) {
-
         // Get the context of the original notice, if any
-
         $originalAuthor   = null;
         $originalNotice   = null;
         $originalMentions = array();
@@ -629,7 +659,6 @@ function common_find_mentions($text, $notice)
         $matches = array_merge($tmatches[1], $atmatches[1]);
 
         foreach ($matches as $match) {
-
             $nickname = common_canonical_nickname($match[0]);
 
             // Try to get a profile for this nickname.
@@ -637,19 +666,15 @@ function common_find_mentions($text, $notice)
             // 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)) {
-
                 $user = User::staticGet('id', $mentioned->id);
 
                 if ($user) {
@@ -908,6 +933,33 @@ function common_shorten_links($text, $always = false)
     }
 }
 
+/**
+ * Very basic stripping of invalid UTF-8 input text.
+ *
+ * @param string $str
+ * @return mixed string or null if invalid input
+ *
+ * @todo ideally we should drop bad chars, and maybe do some of the checks
+ *       from common_xml_safe_str. But we can't strip newlines, etc.
+ * @todo Unicode normalization might also be useful, but not needed now.
+ */
+function common_validate_utf8($str)
+{
+    // preg_replace will return NULL on invalid UTF-8 input.
+    //
+    // Note: empty regex //u also caused NULL return on some
+    // production machines, but none of our test machines.
+    //
+    // This should be replaced with a more reliable check.
+    return preg_replace('/\x00/u', '', $str);
+}
+
+/**
+ * Make sure an arbitrary string is safe for output in XML as a single line.
+ *
+ * @param string $str
+ * @return string
+ */
 function common_xml_safe_str($str)
 {
     // Replace common eol and extra whitespace input chars
@@ -1130,30 +1182,30 @@ function common_date_string($dt)
         // TRANS: Used in notices to indicate when the notice was made compared to now.
         return _('about a minute ago');
     } else if ($diff < 3300) {
-        // XXX: should support plural.
+        $minutes = round($diff/60);
         // TRANS: Used in notices to indicate when the notice was made compared to now.
-        return sprintf(_('about %d minutes ago'), round($diff/60));
+        return sprintf( ngettext('about one minute ago', 'about %d minutes ago', $minutes), $minutes);
     } else if ($diff < 5400) {
         // TRANS: Used in notices to indicate when the notice was made compared to now.
         return _('about an hour ago');
     } else if ($diff < 22 * 3600) {
-        // XXX: should support plural.
+        $hours = round($diff/3600);
         // TRANS: Used in notices to indicate when the notice was made compared to now.
-        return sprintf(_('about %d hours ago'), round($diff/3600));
+        return sprintf( ngettext('about one hour ago', 'about %d hours ago', $hours), $hours);
     } else if ($diff < 37 * 3600) {
         // TRANS: Used in notices to indicate when the notice was made compared to now.
         return _('about a day ago');
     } else if ($diff < 24 * 24 * 3600) {
-        // XXX: should support plural.
+        $days = round($diff/(24*3600));
         // TRANS: Used in notices to indicate when the notice was made compared to now.
-        return sprintf(_('about %d days ago'), round($diff/(24*3600)));
+        return sprintf( ngettext('about one day ago', 'about %d days ago', $days), $days);
     } else if ($diff < 46 * 24 * 3600) {
         // TRANS: Used in notices to indicate when the notice was made compared to now.
         return _('about a month ago');
     } else if ($diff < 330 * 24 * 3600) {
-        // XXX: should support plural.
+        $months = round($diff/(30*24*3600));
         // TRANS: Used in notices to indicate when the notice was made compared to now.
-        return sprintf(_('about %d months ago'), round($diff/(30*24*3600)));
+        return sprintf( ngettext('about one month ago', 'about %d months ago',$months), $months);
     } else if ($diff < 480 * 24 * 3600) {
         // TRANS: Used in notices to indicate when the notice was made compared to now.
         return _('about a year ago');
@@ -1305,8 +1357,9 @@ function common_profile_url($nickname)
                             null, null, false);
 }
 
-// Should make up a reasonable root URL
-
+/**
+ * Should make up a reasonable root URL
+ */
 function common_root_url($ssl=false)
 {
     $url = common_path('', $ssl, false);
@@ -1317,9 +1370,10 @@ function common_root_url($ssl=false)
     return $url;
 }
 
-// returns $bytes bytes of random data as a hexadecimal string
-// "good" here is a goal and not a guarantee
-
+/**
+ * returns $bytes bytes of random data as a hexadecimal string
+ * "good" here is a goal and not a guarantee
+ */
 function common_good_rand($bytes)
 {
     // XXX: use random.org...?
@@ -1465,7 +1519,12 @@ function common_log_db_error(&$object, $verb, $filename=null)
 {
     $objstr = common_log_objstring($object);
     $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
-    common_log(LOG_ERR, $last_error->message . '(' . $verb . ' on ' . $objstr . ')', $filename);
+    if (is_object($last_error)) {
+        $msg = $last_error->message;
+    } else {
+        $msg = 'Unknown error (' . var_export($last_error, true) . ')';
+    }
+    common_log(LOG_ERR, $msg . '(' . $verb . ' on ' . $objstr . ')', $filename);
 }
 
 function common_log_objstring(&$object)
@@ -1643,19 +1702,25 @@ function common_config($main, $sub)
             array_key_exists($sub, $config[$main])) ? $config[$main][$sub] : false;
 }
 
+/**
+ * Pull arguments from a GET/POST/REQUEST array with first-level input checks:
+ * strips "magic quotes" slashes if necessary, and kills invalid UTF-8 strings.
+ *
+ * @param array $from
+ * @return array
+ */
 function common_copy_args($from)
 {
     $to = array();
     $strip = get_magic_quotes_gpc();
     foreach ($from as $k => $v) {
-        if($strip) {
-            if(is_array($v)) {
-                $to[$k] = common_copy_args($v);
-            } else {
-                $to[$k] = stripslashes($v);
-            }
+        if(is_array($v)) {
+            $to[$k] = common_copy_args($v);
         } else {
-            $to[$k] = $v;
+            if ($strip) {
+                $v = stripslashes($v);
+            }
+            $to[$k] = strval(common_validate_utf8($v));
         }
     }
     return $to;
@@ -1793,16 +1858,6 @@ function common_session_token()
     return $_SESSION['token'];
 }
 
-function common_cache_key($extra)
-{
-    return Cache::key($extra);
-}
-
-function common_keyize($str)
-{
-    return Cache::keyize($str);
-}
-
 function common_license_terms($uri)
 {
     if(preg_match('/creativecommons.org\/licenses\/([^\/]+)/', $uri, $matches)) {
@@ -1833,7 +1888,6 @@ function common_compatible_license($from, $to)
  */
 function common_database_tablename($tablename)
 {
-
   if(common_config('db','quote_identifiers')) {
       $tablename = '"'. $tablename .'"';
   }