X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=lib%2Futil.php;h=3e52f5db16752943905f3d2522e26cceb68cc50c;hb=bd6571c2e17939b21e01afd3772acb5cebbbadfe;hp=6946f60feefc32c78bc5a92c3fe6ef792cddd7c7;hpb=71d5990ea3fd7864c3595ea738f35c613d52b62f;p=quix0rs-gnu-social.git diff --git a/lib/util.php b/lib/util.php index 6946f60fee..3e52f5db16 100644 --- a/lib/util.php +++ b/lib/util.php @@ -62,7 +62,7 @@ function common_init_language() // gettext will still select the right language. $language = common_language(); $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'); @@ -91,8 +91,16 @@ function common_language() if (_have_config() && common_logged_in()) { $user = common_current_user(); $user_language = $user->language; - if ($user_language) - return $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; + } + } + } } // Otherwise, find the best match for the languages requested by the @@ -111,6 +119,11 @@ function common_language() function common_munge_password($password, $id) { + if (is_object($id) || is_object($password)) { + $e = new Exception(); + common_log(LOG_ERR, __METHOD__ . ' object in param to common_munge_password ' . + str_replace("\n", " ", $e->getTraceAsString())); + } return md5($password . $id); } @@ -127,7 +140,7 @@ function common_check_user($nickname, $password) if (0 == strcmp(common_munge_password($password, $user->id), $user->password)) { //internal checking passed - $authenticatedUser =& $user; + $authenticatedUser = $user; } } } @@ -158,15 +171,27 @@ function common_ensure_session() if (common_config('sessions', 'handle')) { Session::setSaveHandler(); } + if (array_key_exists(session_name(), $_GET)) { + $id = $_GET[session_name()]; + common_log(LOG_INFO, 'Setting session from GET parameter: '.$id); + } else if (array_key_exists(session_name(), $_COOKIE)) { + $id = $_COOKIE[session_name()]; + common_log(LOG_INFO, 'Setting session from COOKIE: '.$id); + } + if (isset($id)) { + session_id($id); + setcookie(session_name(), $id); + } @session_start(); if (!isset($_SESSION['started'])) { $_SESSION['started'] = time(); - if (!empty($c)) { + if (!empty($id)) { common_log(LOG_WARNING, 'Session cookie "' . $_COOKIE[session_name()] . '" ' . ' is set but started value is null'); } } } + common_debug("Session ID = " . session_id()); } // Three kinds of arguments: @@ -523,19 +548,23 @@ function callback_helper($matches, $callback, $notice_id) { return substr($matches[0],0,$left) . $result . substr($matches[0],$right); } -function curry($fn) { - //TODO switch to a PHP 5.3 function closure based approach if PHP 5.3 is used - $args = func_get_args(); - array_shift($args); - $id = uniqid('_partial'); - $GLOBALS[$id] = array($fn, $args); - return create_function('', - '$args = func_get_args(); '. - 'return call_user_func_array('. - '$GLOBALS["'.$id.'"][0],'. - 'array_merge('. - '$args,'. - '$GLOBALS["'.$id.'"][1]));'); +if (version_compare(PHP_VERSION, '5.3.0', 'ge')) { + // lambda implementation in a separate file; PHP 5.2 won't parse it. + require_once INSTALLDIR . "/lib/curry.php"; +} else { + function curry($fn) { + $args = func_get_args(); + array_shift($args); + $id = uniqid('_partial'); + $GLOBALS[$id] = array($fn, $args); + return create_function('', + '$args = func_get_args(); '. + 'return call_user_func_array('. + '$GLOBALS["'.$id.'"][0],'. + 'array_merge('. + '$args,'. + '$GLOBALS["'.$id.'"][1]));'); + } } function common_linkify($url) { @@ -797,20 +826,50 @@ function common_path($relative, $ssl=false) } else if (common_config('site', 'server')) { $serverpart = common_config('site', 'server'); } else { - common_log(LOG_ERR, 'Site Sever not configured, unable to determine site name.'); + common_log(LOG_ERR, 'Site server not configured, unable to determine site name.'); } } else { $proto = 'http'; if (common_config('site', 'server')) { $serverpart = common_config('site', 'server'); } else { - common_log(LOG_ERR, 'Site Sever not configured, unable to determine site name.'); + common_log(LOG_ERR, 'Site server not configured, unable to determine site name.'); } } + $relative = common_inject_session($relative, $serverpart); + return $proto.'://'.$serverpart.'/'.$pathpart.$relative; } +function common_inject_session($url, $serverpart = null) +{ + if (common_have_session()) { + + if (empty($serverpart)) { + $serverpart = parse_url($url, PHP_URL_HOST); + } + + $currentServer = $_SERVER['HTTP_HOST']; + + // Are we pointing to another server (like an SSL server?) + + if (!empty($currentServer) && + 0 != strcasecmp($currentServer, $serverpart)) { + // Pass the session ID as a GET parameter + $sesspart = session_name() . '=' . session_id(); + $i = strpos($url, '?'); + if ($i === false) { // no GET params, just append + $url .= '?' . $sesspart; + } else { + $url = substr($url, 0, $i + 1).$sesspart.'&'.substr($url, $i + 1); + } + } + } + + return $url; +} + function common_date_string($dt) { // XXX: do some sexy date formatting @@ -896,6 +955,26 @@ function common_sql_date($datetime) return strftime('%Y-%m-%d %H:%M:%S', $datetime); } +/** + * Return an SQL fragment to calculate an age-based weight from a given + * timestamp or datetime column. + * + * @param string $column name of field we're comparing against current time + * @param integer $dropoff divisor for age in seconds before exponentiation + * @return string SQL fragment + */ +function common_sql_weight($column, $dropoff) +{ + if (common_config('db', 'type') == 'pgsql') { + // PostgreSQL doesn't support timestampdiff function. + // @fixme will this use the right time zone? + // @fixme does this handle cross-year subtraction correctly? + return "sum(exp(-extract(epoch from (now() - $column)) / $dropoff))"; + } else { + return "sum(exp(timestampdiff(second, utc_timestamp(), $column) / $dropoff))"; + } +} + function common_redirect($url, $code=307) { static $status = array(301 => "Moved Permanently", @@ -978,7 +1057,12 @@ function common_profile_url($nickname) function common_root_url($ssl=false) { - return common_path('', $ssl); + $url = common_path('', $ssl); + $i = strpos($url, '?'); + if ($i !== false) { + $url = substr($url, 0, $i); + } + return $url; } // returns $bytes bytes of random data as a hexadecimal string @@ -1050,19 +1134,41 @@ function common_log_line($priority, $msg) return date('Y-m-d H:i:s') . ' ' . $syslog_priorities[$priority] . ': ' . $msg . "\n"; } +function common_request_id() +{ + $pid = getmypid(); + if (php_sapi_name() == 'cli') { + return $pid; + } else { + static $req_id = null; + if (!isset($req_id)) { + $req_id = substr(md5(mt_rand()), 0, 8); + } + if (isset($_SERVER['REQUEST_URI'])) { + $url = $_SERVER['REQUEST_URI']; + } + $method = $_SERVER['REQUEST_METHOD']; + return "$pid.$req_id $method $url"; + } +} + function common_log($priority, $msg, $filename=null) { - $logfile = common_config('site', 'logfile'); - if ($logfile) { - $log = fopen($logfile, "a"); - if ($log) { - $output = common_log_line($priority, $msg); - fwrite($log, $output); - fclose($log); + if(Event::handle('StartLog', array(&$priority, &$msg, &$filename))){ + $msg = '[' . common_request_id() . '] ' . $msg; + $logfile = common_config('site', 'logfile'); + if ($logfile) { + $log = fopen($logfile, "a"); + if ($log) { + $output = common_log_line($priority, $msg); + fwrite($log, $output); + fclose($log); + } + } else { + common_ensure_syslog(); + syslog($priority, $msg); } - } else { - common_ensure_syslog(); - syslog($priority, $msg); + Event::handle('EndLog', array($priority, $msg, $filename)); } } @@ -1218,8 +1324,12 @@ function common_copy_args($from) return $to; } -// Neutralise the evil effects of magic_quotes_gpc in the current request. -// This is used before handing a request off to OAuthRequest::from_request. +/** + * Neutralise the evil effects of magic_quotes_gpc in the current request. + * This is used before handing a request off to OAuthRequest::from_request. + * @fixme Doesn't consider vars other than _POST and _GET? + * @fixme Can't be undone and could corrupt data if run twice. + */ function common_remove_magic_from_request() { if(get_magic_quotes_gpc()) { @@ -1346,41 +1456,17 @@ function common_session_token() function common_cache_key($extra) { - $base_key = common_config('memcached', 'base'); - - if (empty($base_key)) { - $base_key = common_keyize(common_config('site', 'name')); - } - - return 'statusnet:' . $base_key . ':' . $extra; + return Cache::key($extra); } function common_keyize($str) { - $str = strtolower($str); - $str = preg_replace('/\s/', '_', $str); - return $str; + return Cache::keyize($str); } function common_memcache() { - static $cache = null; - if (!common_config('memcached', 'enabled')) { - return null; - } else { - if (!$cache) { - $cache = new Memcache(); - $servers = common_config('memcached', 'server'); - if (is_array($servers)) { - foreach($servers as $server) { - $cache->addServer($server); - } - } else { - $cache->addServer($servers); - } - } - return $cache; - } + return Cache::instance(); } function common_license_terms($uri) @@ -1421,6 +1507,17 @@ function common_database_tablename($tablename) return $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 + * @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) { $user = common_current_user(); @@ -1441,6 +1538,16 @@ function common_shorten_url($long_url) } } +/** + * @return mixed array($proxy, $ip) for web requests; proxy may be null + * null if not a web request + * + * @fixme X-Forwarded-For can be chained by multiple proxies; + we should parse the list and provide a cleaner array + * @fixme X-Forwarded-For can be forged by clients; only use them if trusted + * @fixme X_Forwarded_For headers will override X-Forwarded-For read through $_SERVER; + * use function to get exact request headers from Apache if possible. + */ function common_client_ip() { if (!isset($_SERVER) || !array_key_exists('REQUEST_METHOD', $_SERVER)) {