X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=lib%2Futil.php;h=df339d4b1e39e6058c84ea3d31becf2e1bb05210;hb=99194e03fa50b61f99164674afc949b4bbefd44a;hp=89d2bf8c2ff72f69e7a55696e2b841147308fc2b;hpb=2d4c0f9a47f6534c578a37abe79670cec699caae;p=quix0rs-gnu-social.git diff --git a/lib/util.php b/lib/util.php index 89d2bf8c2f..df339d4b1e 100644 --- a/lib/util.php +++ b/lib/util.php @@ -145,7 +145,6 @@ function common_switch_locale($language=null) textdomain("statusnet"); } - function common_timezone() { if (common_logged_in()) { @@ -158,22 +157,38 @@ function common_timezone() return common_config('site', 'timezone'); } +function common_valid_language($lang) +{ + if ($lang) { + // Validate -- we don't want to end up with a bogus code + // left over from some old junk. + foreach (common_config('site', 'languages') as $code => $info) { + if ($info['lang'] == $lang) { + return true; + } + } + } + return false; +} + function common_language() { + // Allow ?uselang=xx override, very useful for debugging + // and helping translators check usage and context. + if (isset($_GET['uselang'])) { + $uselang = strval($_GET['uselang']); + if (common_valid_language($uselang)) { + return $uselang; + } + } + // If there is a user logged in and they've set a language preference // then return that one... if (_have_config() && common_logged_in()) { $user = common_current_user(); - $user_language = $user->language; - - if ($user->language) { - // Validate -- we don't want to end up with a bogus code - // left over from some old junk. - foreach (common_config('site', 'languages') as $code => $info) { - if ($info['lang'] == $user_language) { - return $user_language; - } - } + + if (common_valid_language($user->language)) { + return $user->language; } } @@ -494,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) { @@ -878,11 +916,45 @@ function common_linkify($url) { function common_shorten_links($text, $always = false) { - $maxLength = Notice::maxContent(); - if (!$always && ($maxLength == 0 || mb_strlen($text) <= $maxLength)) return $text; - return common_replace_urls_callback($text, array('File_redirection', 'makeShort')); + common_debug("common_shorten_links() called"); + + $user = common_current_user(); + + $maxLength = User_urlshortener_prefs::maxNoticeLength($user); + + common_debug("maxLength = $maxLength"); + + if ($always || mb_strlen($text) > $maxLength) { + common_debug("Forcing shortening"); + return common_replace_urls_callback($text, array('File_redirection', 'forceShort')); + } else { + common_debug("Not forcing shortening"); + return common_replace_urls_callback($text, array('File_redirection', 'makeShort')); + } +} + +/** + * 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. + return preg_replace('//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 @@ -1105,30 +1177,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'); @@ -1226,14 +1298,8 @@ function common_redirect($url, $code=307) exit; } -function common_broadcast_notice($notice, $remote=false) -{ - // DO NOTHING! -} +// Stick the notice on the queue -/** - * Stick the notice on the queue. - */ function common_enqueue_notice($notice) { static $localTransports = array('omb', @@ -1247,18 +1313,9 @@ function common_enqueue_notice($notice) $transports[] = 'plugin'; } - $xmpp = common_config('xmpp', 'enabled'); - - if ($xmpp) { - $transports[] = 'jabber'; - } - // We can skip these for gatewayed notices. if ($notice->isLocal()) { $transports = array_merge($transports, $localTransports); - if ($xmpp) { - $transports[] = 'public'; - } } if (Event::handle('StartEnqueueNotice', array($notice, &$transports))) { @@ -1457,7 +1514,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) @@ -1635,19 +1697,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; @@ -1785,21 +1853,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_memcache() -{ - return Cache::instance(); -} - function common_license_terms($uri) { if(preg_match('/creativecommons.org\/licenses\/([^\/]+)/', $uri, $matches)) { @@ -1840,30 +1893,42 @@ function common_database_tablename($tablename) /** * Shorten a URL with the current user's configured shortening service, * or ur1.ca if configured, or not at all if no shortening is set up. - * Length is not considered. * - * @param string $long_url + * @param string $long_url original URL + * @param boolean $force Force shortening (used when notice is too long) + * * @return string may return the original URL if shortening failed * * @fixme provide a way to specify a particular shortener * @fixme provide a way to specify to use a given user's shortening preferences */ -function common_shorten_url($long_url) + +function common_shorten_url($long_url, $force = false) { + common_debug("Shortening URL '$long_url' (force = $force)"); + $long_url = trim($long_url); + $user = common_current_user(); - if (empty($user)) { - // common current user does not find a user when called from the XMPP daemon - // therefore we'll set one here fix, so that XMPP given URLs may be shortened - $shortenerName = 'ur1.ca'; - } else { - $shortenerName = $user->urlshorteningservice; + + $maxUrlLength = User_urlshortener_prefs::maxUrlLength($user); + common_debug("maxUrlLength = $maxUrlLength"); + + // $force forces shortening even if it's not strictly needed + + if (mb_strlen($long_url) < $maxUrlLength && !$force) { + common_debug("Skipped shortening URL."); + return $long_url; } - if(Event::handle('StartShortenUrl', array($long_url,$shortenerName,&$shortenedUrl))){ + $shortenerName = User_urlshortener_prefs::urlShorteningService($user); + + common_debug("Shortener name = '$shortenerName'"); + + if (Event::handle('StartShortenUrl', array($long_url, $shortenerName, &$shortenedUrl))) { //URL wasn't shortened, so return the long url return $long_url; - }else{ + } else { //URL was shortened, so return the result return trim($shortenedUrl); }