<?php
/*======================================================================*\
|| #################################################################### ||
|| # vBulletin 4.0.5
|| # ---------------------------------------------------------------- # ||
|| # Copyright ©2000-2010 vBulletin Solutions Inc. All Rights Reserved. ||
|| # This file may not be redistributed in whole or significant part. # ||
|| # ---------------- VBULLETIN IS NOT FREE SOFTWARE ---------------- # ||
|| # http://www.vbulletin.com | http://www.vbulletin.com/license.html # ||
|| #################################################################### ||
\*======================================================================*/
// ###################### Start microtime_diff #######################
// get microtime difference between $starttime and NOW
function fetch_microtime_difference($starttime, $addtime = 0)
{
$finishtime = microtime();
$starttime = explode(' ', $starttime);
$finishtime = explode(' ', $finishtime);
return $finishtime[0] - $starttime[0] + $finishtime[1] - $starttime[1] + $addtime;
}
// ###################### Start mktimefix #######################
// mktime() workaround for < 1970
function mktimefix($format, $year)
{
$two_digit_year = substr($year, 2);
// note: the ISO (%G) replaces here are not always correct, but it's the best we can do
$replace = array(
'%Y' => $year,
'%y' => $two_digit_year,
'%G' => $year,
'%g' => $two_digit_year,
'Y' => $year,
'y' => $two_digit_year,
'o' => $year
);
return str_replace(array_keys($replace), $replace, $format);
}
// ###################### Start getlanguagesarray #######################
function fetch_language_titles_array($titleprefix = '', $getall = true)
{
global $vbulletin;
$out = array();
$languages = $vbulletin->db->query_read_slave("
SELECT languageid, title
FROM " . TABLE_PREFIX . "language
" . iif($getall != true, ' WHERE userselect = 1')
);
while ($language = $vbulletin->db->fetch_array($languages))
{
$out["$language[languageid]"] = $titleprefix . $language['title'];
}
asort($out);
return $out;
}
// ###################### Start makefolderjump #######################
function construct_folder_jump($foldertype = 0, $selectedid = false, $exclusions = false, $sentfolders = '', $data_only = false)
{
global $vbphrase, $folderid, $folderselect, $foldernames, $messagecounters, $subscribecounters, $folder;
global $vbulletin;
// 0 indicates PMs
// 1 indicates subscriptions
// get all folder names (for dropdown)
// reference with $foldernames[#] .
$folderjump = '';
if (!is_array($foldernames))
{
$foldernames = array();
}
switch($foldertype)
{
case 0:
// get PM folders total
$pmcounts = $vbulletin->db->query_read_slave("
SELECT COUNT(*) AS total, folderid
FROM " . TABLE_PREFIX . "pm AS pm
WHERE userid = " . $vbulletin->userinfo['userid'] . "
GROUP BY folderid
");
$messagecounters = array();
while ($pmcount = $vbulletin->db->fetch_array($pmcounts))
{
$messagecounters["$pmcount[folderid]"] = $pmcount['total'];
}
$folderfield = 'pmfolders';
$folders = array('0' => $vbphrase['inbox'], '-1' => $vbphrase['sent_items']);
if (!empty($vbulletin->userinfo["$folderfield"]))
{
$userfolder = unserialize($vbulletin->userinfo["$folderfield"]);
if (is_array($userfolder))
{
$folders = $folders + $userfolder;
}
}
$counters =& $messagecounters;
break;
case 1:
// get Subscription folder totals
$foldertotals = $vbulletin->db->query_read_slave("
SELECT COUNT(*) AS total, folderid
FROM " . TABLE_PREFIX . "subscribethread AS subscribethread
LEFT JOIN " . TABLE_PREFIX . "thread AS thread ON(thread.threadid = subscribethread.threadid)
WHERE subscribethread.userid = " . $vbulletin->userinfo['userid'] . "
AND thread.visible = 1
AND canview = 1
GROUP BY folderid
");
$subscribecounters = array();
while ($foldertotal = $vbulletin->db->fetch_array($foldertotals))
{
$subscribecounters["$foldertotal[folderid]"] = intval($foldertotal['total']);
}
$folderfield = 'subfolders';
$folders = iif($sentfolders, $sentfolders, unserialize($vbulletin->userinfo["$folderfield"]));
if (!$folders[0])
{
$folders[0] = $vbphrase['subscriptions'];
asort($folders, SORT_STRING);
}
$counters =& $subscribecounters;
break;
default:
return;
}
if (is_array($folders))
{
foreach($folders AS $_folderid => &$_foldername)
{
if (is_array($exclusions) AND in_array($_folderid, $exclusions))
{
continue;
}
else
{
if ($_folderid == $selectedid AND $selectedid !== false)
{
$folder = $_foldername;
}
if ($data_only)
{
$_foldername = array(
'name' => $_foldername,
'id' => $_folderid,
'selected' => ($_folderid == $selectedid),
'count' => (is_array($counters) ? intval($counters[$_folderid]) : 0),
'type' => (($foldertype == 1) ? $vbphrase['threads'] : $vbphrase['messages'])
);
}
$foldernames["$_folderid"] = $_foldername;
$folderjump .= "<option value=\"$_folderid\" " . iif($_folderid == $selectedid, 'selected="selected"') . ">$_foldername" . iif(is_array($counters), ' (' . intval($counters["$_folderid"]) . iif($foldertype == 1, " $vbphrase[threads])", " $vbphrase[messages])")) . "</option>\n";
}
}
}
if ($data_only)
{
return sizeof($folders) ? $folders : false;
}
return $folderjump;
}
// ###################### Start vbmktime #######################
function vbmktime($hours = 0, $minutes = 0, $seconds = 0, $month = 0, $day = 0, $year = 0)
{
global $vbulletin;
return mktime(intval($hours), intval($minutes), intval($seconds), intval($month), intval($day), intval($year)) + $vbulletin->options['hourdiff'];
}
// ###################### Start gmvbdate #####################
function vbgmdate($format, $timestamp, $doyestoday = false, $locale = true)
{
return vbdate($format, $timestamp, $doyestoday, $locale, false, true);
}
// ###################### Start fetch period group #####################
function fetch_period_group($itemtime)
{
global $vbphrase, $vbulletin;
static $periods;
// create the periods array if it does not exist
if (empty($periods))
{
$daynum = -1;
$i = 0;
// make $vbulletin->userinfo's startofweek setting agree with the date() function
$weekstart = $vbulletin->userinfo['startofweek'] - 1;
// get the timestamp for the beginning of today, according to vbulletin->userinfo's timezone
$timestamp = vbmktime(0, 0, 0, vbdate('m', TIMENOW, false, false), vbdate('d', TIMENOW, false, false), vbdate('Y', TIMENOW, false, false));
// initialize $periods array with stamp for today
$periods = array('today' => $timestamp);
// create periods for today, yesterday and all days until we hit the start of the week
while ($daynum != $weekstart AND $i++ < 7)
{
// take away 24 hours
$timestamp -= 86400;
// get the number of the current day
$daynum = vbdate('w', $timestamp, false, false);
if ($i == 1)
{
$periods['yesterday'] = $timestamp;
}
else
{
$periods[strtolower(vbdate('l', $timestamp, false, false))] = $timestamp;
}
}
// create periods for Last Week, 2 Weeks Ago, 3 Weeks Ago and Last Month
$periods['last_week'] = $timestamp -= (7 * 86400);
$periods['2_weeks_ago'] = $timestamp -= (7 * 86400);
$periods['3_weeks_ago'] = $timestamp -= (7 * 86400);
$periods['last_month'] = $timestamp -= (7 * 86400);
}
foreach ($periods AS $periodname => $periodtime)
{
if ($itemtime >= $periodtime)
{
return $periodname;
}
}
return 'older';
}
/**
* Fetches a character group id for a string
*
* @param string $str
* @return string
*/
function fetch_char_group($str)
{
$str = trim($str);
$chr = strtolower(fetch_try_to_ascii($str[0]));
if (is_numeric($chr))
{
return '0_to_9';
}
else if($chr >= 'a' AND $chr <= 'h')
{
return 'a_to_h';
}
else if($chr >= 'i' AND $chr <= 'p')
{
return 'i_to_p';
}
else if($chr >= 'q' AND $chr <= 'z')
{
return 'q_to_z';
}
else
{
return 'other';
}
}
/**
* Tries to convert a character to it's closest non extended ascii equivelant
*
* @param string $chr - The character to convert
* @returns string - The result
*/
function fetch_try_to_ascii($chr)
{
$conv = array(
'А' => 'a', 'Б' => 'a', 'В' => 'a', 'Г' => 'a', 'Д' => 'a', 'Е' => 'a', 'Ж' => 'e', 'З' => 'c',
'И' => 'e', 'Й' => 'e', 'К' => 'e', 'Л' => 'e', 'М' => 'i', 'Н' => 'i', 'О' => 'i', 'П' => 'i',
'Р' => 'd', 'С' => 'n', 'Т' => 'o', 'У' => 'o', 'Ф' => 'o', 'Х' => 'o', 'Ц' => 'o', 'Ш' => 'o',
'Щ' => 'u', 'Ъ' => 'u', 'Ы' => 'u', 'Ь' => 'u', 'Э' => 'y', 'а' => 'a', 'б' => 'a', 'в' => 'a',
'г' => 'a', 'д' => 'a', 'е' => 'a', 'з' => 'c', 'и' => 'e', 'й' => 'e', 'к' => 'e', 'л' => 'e',
'м' => 'i', 'н' => 'i', 'о' => 'i', 'п' => 'i', 'с' => 'n', 'т' => 'o', 'у' => 'o', 'ф' => 'o',
'х' => 'o', 'ц' => 'o', 'щ' => 'u', 'ъ' => 'u', 'ы' => 'u', 'ь' => 'u', 'э' => 'y', 'я' => 'y'
);
return (isset($conv[$chr]) ? $conv[$chr] : $chr);
}
/**
* Converts a timestamp into an array of dmY
*
* @param integer $timestamp
* @returns array | boolean false
*/
function fetch_datearray_from_timestamp($timestamp = TIMENOW)
{
global $vbulletin;
if ($timestamp = $vbulletin->input->clean($timestamp, TYPE_UNIXTIME))
{
$datearray = array(
'day' => date('d', $timestamp),
'month' => date('n', $timestamp),
'year' => date('Y', $timestamp)
);
return $datearray;
}
return false;
}
// ###################### Start array2bits #######################
// takes an array and returns the bitwise value
function convert_array_to_bits(&$arry, $_FIELDNAMES, $unset = 0)
{
$bits = 0;
foreach($_FIELDNAMES AS $fieldname => $bitvalue)
{
if ($arry["$fieldname"] == 1)
{
$bits += $bitvalue;
}
if ($unset)
{
unset($arry["$fieldname"]);
}
}
return $bits;
}
// ###################### Start bitwise #######################
// Returns 1 if the bitwise is successful, 0 other wise
// usage bitwise($perms, UG_CANMOVE);
function bitwise($value, $bitfield)
{
// Do not change this to return true/false!
return iif(intval($value) & $bitfield, 1, 0);
}
// ###################### Start echoarray #######################
// recursively prints out an array
function print_array($array, $title = NULL, $htmlisekey = false, $indent = '')
{
global $vbphrase;
if ($title === NULL)
{
$title = 'My Array';
}
if (is_array($array))
{
echo iif(empty($indent), "<div class=\"echoarray\">\n") . "$indent<li><b" . iif(empty($indent), ' style="font-size: larger"', '').">" . iif($htmlisekey, htmlspecialchars_uni($title), $title) . "</b><ul>\n";
foreach ($array AS $key => $val)
{
if (is_array($val))
{
print_array($val, $key, $htmlisekey, $indent."\t");
}
else
{
echo "$indent\t<li>" . iif($htmlisekey, htmlspecialchars_uni($key), $key) . " = '<i>" . htmlspecialchars_uni($val) . "</i>'</li>\n";
}
}
echo iif(empty($indent), "</div>\n") . "$indent</ul></li>\n";
}
}
// ###################### Start getChildForums #######################
function fetch_child_forums($parentid, $return = 'STRING', $glue = ',')
{
global $vbulletin, $allforumcache;
static $childlist;
if (!is_array($allforumcache))
{
if ($return == 'ARRAY')
{
$childlist = array();
}
else
{
$childlist = 0;
}
foreach(array_keys($vbulletin->forumcache) AS $forumid)
{
$f =& $vbulletin->forumcache["$forumid"];
$allforumcache["$f[parentid]"]["$forumid"] = $forumid;
}
}
if (!is_array($allforumcache["$parentid"]))
{
return $childlist;
}
else
{
foreach($allforumcache["$parentid"] AS $forumid)
{
if ($return == 'ARRAY')
{
$childlist[] = $forumid;
}
else
{
$childlist .= "$glue$forumid";
}
fetch_child_forums($forumid, $return, $glue);
}
}
return $childlist;
}
/**
* Marks a forum, its child forums and all contained posts as read
*
* @param integer Forum ID to be marked as read - leave blank to mark all forums as read
*
* @return array Array of affected forum IDs
*/
function mark_forums_read($forumid = false)
{
global $vbulletin;
$db =& $vbulletin->db;
$return_url = $vbulletin->options['forumhome'] . '.php' . $vbulletin->session->vars['sessionurl_q'];
$return_phrase = 'markread';
$return_forumids = array();
if (!$forumid)
{
if ($vbulletin->userinfo['userid'])
{
// init user data manager
$userdata =& datamanager_init('User', $vbulletin, ERRTYPE_STANDARD);
$userdata->set_existing($vbulletin->userinfo);
$userdata->set('lastactivity', TIMENOW);
$userdata->set('lastvisit', TIMENOW - 1);
$userdata->save();
if ($vbulletin->options['threadmarking'])
{
$query = '';
foreach ($vbulletin->forumcache AS $fid => $finfo)
{
// mark the forum and all child forums read
$query .= ", ($fid, " . $vbulletin->userinfo['userid'] . ", " . TIMENOW . ")";
}
if ($query)
{
$query = substr($query, 2);
$db->query_write("
REPLACE INTO " . TABLE_PREFIX . "forumread
(forumid, userid, readtime)
VALUES
$query
");
}
}
}
else
{
vbsetcookie('lastvisit', TIMENOW);
}
$return_forumids = array_keys($vbulletin->forumcache);
}
else
{
// temp work around code, I need to find another way to mass set some values to the cookie
$vbulletin->input->clean_gpc('c', COOKIE_PREFIX . 'forum_view', TYPE_STR);
global $bb_cache_forum_view;
$bb_cache_forum_view = @unserialize(convert_bbarray_cookie($vbulletin->GPC[COOKIE_PREFIX . 'forum_view']));
require_once(DIR . '/includes/functions_misc.php');
$childforums = fetch_child_forums($forumid, 'ARRAY');
$return_forumids = $childforums;
$return_forumids[] = $forumid;
if ($vbulletin->options['threadmarking'] AND $vbulletin->userinfo['userid'])
{
$query = "($forumid, " . $vbulletin->userinfo['userid'] . ", " . TIMENOW . ")";
foreach ($childforums AS $child_forumid)
{
// mark the forum and all child forums read
$query .= ", ($child_forumid, " . $vbulletin->userinfo['userid'] . ", " . TIMENOW . ")";
}
$db->query_write("
REPLACE INTO " . TABLE_PREFIX . "forumread
(forumid, userid, readtime)
VALUES
$query
");
require_once(DIR . '/includes/functions_bigthree.php');
$foruminfo = fetch_foruminfo($forumid);
$parent_marks = mark_forum_read($foruminfo, $vbulletin->userinfo['userid'], TIMENOW);
if (is_array($parent_marks))
{
$return_forumids = array_unique(array_merge($return_forumids, $parent_marks));
}
}
else
{
foreach ($childforums AS $child_forumid)
{
// mark the forum and all child forums read
$bb_cache_forum_view["$child_forumid"] = TIMENOW;
}
set_bbarray_cookie('forum_view', $forumid, TIMENOW);
}
if ($vbulletin->forumcache["$forumid"]['parentid'] == -1)
{
$return_url = $vbulletin->options['forumhome'] . '.php' . $vbulletin->session->vars['sessionurl_q'];
}
else
{
$forumid = $vbulletin->forumcache["$forumid"]['parentid'];
$return_url = fetch_seo_url('forum', array('forumid' => $forumid, 'title' => $vbulletin->forumcache["$forumid"]['title']));
}
$return_phrase = 'markread_single';
}
return array(
'url' => $return_url,
'phrase' => $return_phrase,
'forumids' => $return_forumids
);
}
// ###################### Start verify autosubscribe #######################
// function to verify that the subscription type is valid
function verify_subscription_choice($choice, &$userinfo, $default = 9999, $doupdate = true)
{
global $vbulletin;
// check that the subscription choice is valid
switch ($choice)
{
// the choice is good
case 0:
case 1:
case 2:
case 3:
break;
// check that ICQ number is valid
case 4:
if (!preg_match('#^[0-9\-]+$', $userinfo['icq']))
{
// icq number is bad
if ($doupdate)
{
global $vbulletin;
// init user datamanager
$userdata =& datamanager_init('User', $vbulletin, ERRTYPE_STANDARD);
$userdata->set_existing($userinfo);
$userdata->set('icq', '');
$userdata->set('autosubscribe', 1);
$userdata->save();
}
$userinfo['icq'] = '';
$userinfo['autosubscribe'] = 1;
$choice = 1;
}
break;
// all other options
default:
$choice = $default;
break;
}
return $choice;
}
// ###################### Start countchar #######################
function fetch_character_count($string, $char)
{
//counts number of times $char occus in $string
return substr_count(strtolower($string), strtolower($char));
}
/**
* Replaces legacy variable names in templates with their modern equivalents
*
* @param string Template to be processed
* @param boolean Handle replacement of vars outside of quotes
*
* @return string
*/
function replace_template_variables($template, $do_outside_regex = false)
{
// matches references to specifc arrays in templates and maps them to a better internal format
// this function name is a slight misnomer; it can be run on phrases with variables in them too!
// include the $, but escape it in the key
static $variables = array(
'\$vboptions' => '$GLOBALS[\'vbulletin\']->options',
'\$bbuserinfo' => '$GLOBALS[\'vbulletin\']->userinfo',
'\$session' => '$GLOBALS[\'vbulletin\']->session->vars',
'\$stylevar' => 'vB_Template_Runtime::fetchStylevar',
);
// regexes to do the replacements; __FINDVAR__ and __REPLACEVAR__ are replaced before execution
static $basic_find = array(
'#\' \. __FINDVAR__\[(\'|)(\w+)\\1\] \. \'#',
'#\{__FINDVAR__\[(\\\\?\'|"|)([\w$[\]]+)\\1\]\}#',
'#__FINDVAR__\[\$(\w+)\]#',
'#__FINDVAR__\[(\w+)\]#',
);
static $basic_replace1 = array(
'\' . __REPLACEVAR__[$1$2$1] . \'',
'" . __REPLACEVAR__[$1$2$1] . "',
'" . __REPLACEVAR__[$$1] . "',
'" . __REPLACEVAR__[\'$1\'] . "',
);
static $basic_replace2 = array(
'\' . __REPLACEVAR__($1$2$1) . \'',
'" . __REPLACEVAR__($1$2$1) . "',
'" . __REPLACEVAR__($$1) . "',
'" . __REPLACEVAR__(\'$1\') . "',
);
global $replacevar, $findvar;
foreach ($variables AS $findvar => $replacevar)
{
if ($do_outside_regex)
{
// this is handles replacing of vars outside of quotes
do
{
$new_template = preg_replace_callback(
array(
'#^([^"]*?("(?>(?>(\\\\{2})+?)|\\\\"|[^"])*"([^"]*?))*)' . $findvar . '\[(\\\\?\'|"|)([\w$[\]]+)\\5\]#sU',
'#^([^"]*?("(?>(?>(\\\\{2})+?)|\\\\"|[^"])*"([^"]*?))*)' . $findvar . '([^[]|$)#sU',
),
/*
array(
$_replacevar,
'$1' . $replacevar . '$5',
),
*/
'replace_replacevar'
,
$template
);
if ($new_template == $template)
{
break;
}
$template = $new_template;
}
while (true);
}
if ($replacevar[0] == '$')
{
$basic_replace =& $basic_replace1;
}
else
{
$basic_replace =& $basic_replace2;
}
// these regular expressions handle replacement of vars inside quotes
$this_find = str_replace('__FINDVAR__', $findvar, $basic_find);
$this_replace = str_replace('__REPLACEVAR__', $replacevar, $basic_replace);
$template = preg_replace($this_find, $this_replace, $template);
}
// straight replacements - for example $scriptpath becomes $GLOBALS['vbulletin']->scriptpath
static $str_replace = array(
'$scriptpath' => '" . $GLOBALS[\'vbulletin\']->scriptpath . "',
'$navbar_reloadurl' => '" . $GLOBALS[\'vbulletin\']->reloadurl . "',
);
$template = str_replace(array_keys($str_replace), $str_replace, $template);
return $template;
}
function replace_replacevar($matches)
{
global $replacevar, $findvar;
if ($replacevar[0] == '$')
{
if (count($matches) == 6)
{
return $matches[1] . $replacevar . $matches[5];
}
else
{
return $matches[1] . $replacevar . '[' . $matches[5] . $matches[6] . $matches[5] . ']';
}
}
else
{
if (count($matches) == 6 AND $findvar == '\$stylevar')
{
// This doesn't really work since $stylevar doesn't exist .. but it stops a parse error
return $matches[1] . '$stylevar' . $matches[5];
}
if (!$matches[5])
{
$matches[5] = "'";
}
return $matches[1] . $replacevar . '(' . $matches[5] . $matches[6] . $matches[5] . ')';
}
}
/**
* Returns a hidden input field containing the serialized $_POST array
*
* @return string HTML code containing hidden fields
*/
function construct_post_vars_html()
{
global $vbulletin;
$vbulletin->input->clean_gpc('p', 'postvars', TYPE_BINARY);
if ($vbulletin->GPC['postvars'] != '' AND verify_client_string($vbulletin->GPC['postvars']) !== false)
{
return '<input type="hidden" name="postvars" value="' . htmlspecialchars_uni($vbulletin->GPC['postvars']) . '" />' . "\n";
}
else if ($vbulletin->superglobal_size['_POST'] > 0)
{
return '<input type="hidden" name="postvars" value="' . htmlspecialchars_uni(sign_client_string(serialize($_POST))) . '" />' . "\n";
}
else
{
return '';
}
}
/**
* Returns a collection of <input type="hidden" /> fields containing the values specified in the serialized array provided
*
* @param string Serialized array of name=value pairs
*
* @return string HTML hidden fields
*/
function construct_hidden_var_fields($serializedarr)
{
$temp = unserialize($serializedarr);
if (!is_array($temp))
{
return '';
}
$html = '';
foreach ($temp AS $key => $val)
{
if ($key == 'submit' OR $key == 'action' OR $key == 'method')
{ // reserved in JS
continue;
}
$html .= construct_hidden_var_field_value($key, $val);
}
return $html;
}
function construct_hidden_var_field_value($key, $val, $key_prefix = '')
{
global $vbulletin;
$html = '';
if (is_array($val))
{
if (empty($key_prefix))
{
$key_prefix = $key;
}
else
{
$key_prefix .= "[$key]";
}
foreach ($val AS $key2 => $val2)
{
$html .= construct_hidden_var_field_value($key2, $val2, $key_prefix);
}
}
else
{
if ($key == 's' AND !$key_prefix)
{
$val = $vbulletin->session->vars['dbsessionhash'];
}
$key = (!empty($key_prefix) ? $key_prefix . "[$key]" : $key);
$html .= '<input type="hidden" name="' . htmlspecialchars_uni($key) . '" value="' . htmlspecialchars_uni($val) . '" />' . "\n";
}
return $html;
}
/**
* Fetches a specific type of phrase from the database
*
* @param string Varname of the phrase to be fetched
* @param integer Phrase Type ID of the phrase to be fetched
* @param string String to be removed from the beginning of specified phrase varname (varname = 'moo_thing', strreplace = 'moo_' => varname = 'thing')
* @param boolean Whether or not to parse any quotes in the fetched text ready for eval()
* @param boolean Fetch phrase from all languages (?)
* @param integer Desired language ID from which to pull the phrase text
* @param boolean If true, converts '{1}' and '{2}' into '%1$s' and '%2$s' etc., in preparation for sprintf() parsing
*
* @return string
*/
function fetch_phrase($phrasename, $fieldname, $strreplace = '', $doquotes = true, $alllanguages = false, $languageid = -1, $dobracevars = true)
{
// we need to do some caching in this function I believe
global $vbulletin, $vbphrase;
static $phrase_cache;
if (!empty($strreplace))
{
if (strpos("$phrasename", $strreplace) === 0)
{
$phrasename = substr($phrasename, strlen($strreplace));
}
}
$languageid = intval($languageid);
if (!isset($phrase_cache["{$fieldname}-{$phrasename}"]))
{
$getphrases = $vbulletin->db->query_read_slave("
SELECT text, languageid, special
FROM " . TABLE_PREFIX . "phrase AS phrase
LEFT JOIN " . TABLE_PREFIX . "phrasetype USING (fieldname)
WHERE phrase.fieldname = '" . $vbulletin->db->escape_string($fieldname) . "'
AND varname = '" . $vbulletin->db->escape_string($phrasename) . "' "
. iif(!$alllanguages, "AND languageid IN (-1, 0, " . ($languageid > 0 ? $languageid : intval(LANGUAGEID)) . ")")
);
while ($getphrase = $vbulletin->db->fetch_array($getphrases))
{
$phrase_cache["{$fieldname}-{$phrasename}"]["$getphrase[languageid]"] = $getphrase['text'];
$phrase_cache["{$fieldname}-{$phrasename}"]['special'] = $getphrase['special'];
}
unset($getphrase);
$vbulletin->db->free_result($getphrases);
}
$phrase =& $phrase_cache["{$fieldname}-{$phrasename}"];
$special = $phrase['special'];
if ($languageid == -1)
{
// didn't pass in a languageid as this is the default value so use the browsing user's languageid
$languageid = LANGUAGEID;
}
else if ($languageid == 0)
{
// the user is using forum default
$languageid = $vbulletin->options['languageid'];
}
if (isset($phrase["$languageid"]))
{
$messagetext = $phrase["$languageid"];
}
else if (isset($phrase[0]))
{
$messagetext = $phrase[0];
}
else if (isset($phrase['-1']))
{
$messagetext = $phrase['-1'];
}
else if (isset($vbphrase["$phrasename"]) AND (VB_AREA == 'Upgrade' OR VB_AREA == 'Install'))
{
$messagetext = $vbphrase["$phrasename"];
}
else
{
$messagetext = "Could not find phrase '$phrasename'.";
}
if ($dobracevars)
{
$messagetext = str_replace('%', '%%', $messagetext);
$messagetext = preg_replace('#\{([0-9]+)\}#sU', '%\\1$s', $messagetext);
}
if ($doquotes)
{
$messagetext = str_replace("\\'", "'", addslashes($messagetext));
if ($special)
{
// these phrases have variables in them. Thus, they could have variables like $vboptions that need to be replaced
$messagetext = replace_template_variables($messagetext, false);
}
}
return $messagetext;
}
/**
* Returns either the complete array of timezones, or the timezone phrase name corresponding to $offset
*
* @param mixed If specified, returns the corresponding timezone phrase name. Otherwise, all timezones will be returned
*
* @return mixed
*/
function fetch_timezone($offset = 'all')
{
$timezones = array(
'-12' => 'timezone_gmt_minus_1200',
'-11' => 'timezone_gmt_minus_1100',
'-10' => 'timezone_gmt_minus_1000',
'-9' => 'timezone_gmt_minus_0900',
'-8' => 'timezone_gmt_minus_0800',
'-7' => 'timezone_gmt_minus_0700',
'-6' => 'timezone_gmt_minus_0600',
'-5' => 'timezone_gmt_minus_0500',
'-4.5' => 'timezone_gmt_minus_0430',
'-4' => 'timezone_gmt_minus_0400',
'-3.5' => 'timezone_gmt_minus_0330',
'-3' => 'timezone_gmt_minus_0300',
'-2' => 'timezone_gmt_minus_0200',
'-1' => 'timezone_gmt_minus_0100',
'0' => 'timezone_gmt_plus_0000',
'1' => 'timezone_gmt_plus_0100',
'2' => 'timezone_gmt_plus_0200',
'3' => 'timezone_gmt_plus_0300',
'3.5' => 'timezone_gmt_plus_0330',
'4' => 'timezone_gmt_plus_0400',
'4.5' => 'timezone_gmt_plus_0430',
'5' => 'timezone_gmt_plus_0500',
'5.5' => 'timezone_gmt_plus_0530',
'5.75' => 'timezone_gmt_plus_0545',
'6' => 'timezone_gmt_plus_0600',
'6.5' => 'timezone_gmt_plus_0630',
'7' => 'timezone_gmt_plus_0700',
'8' => 'timezone_gmt_plus_0800',
'9' => 'timezone_gmt_plus_0900',
'9.5' => 'timezone_gmt_plus_0930',
'10' => 'timezone_gmt_plus_1000',
'11' => 'timezone_gmt_plus_1100',
'12' => 'timezone_gmt_plus_1200'
);
if ($offset === 'all')
{
return $timezones;
}
else
{
return $timezones["$offset"];
}
}
/**
* Checks if a user has currently exceeded their private message quota
*
* @param integer $userid Id of the user to check
* @return boolean Whether they have exceeded their quota
*/
function fetch_privatemessage_throttle_reached($userid)
{
global $vbulletin;
if (!$vbulletin->options['pmthrottleperiod'])
{
return false;
}
if (!$vbulletin->userinfo['permissions']['pmthrottlequantity'])
{
return false;
}
$count = $vbulletin->db->query_first("
SELECT COUNT(userid) AS total
FROM " . TABLE_PREFIX . "pmthrottle
WHERE userid = " . intval($vbulletin->userinfo['userid']) . "
AND dateline > " . (TIMENOW - ($vbulletin->options['pmthrottleperiod'] * 60))
);
return ($count['total'] >= $vbulletin->userinfo['permissions']['pmthrottlequantity']);
}
function validate_string_for_interpolation($string)
{
$start = '{$';
$end = '}';
$pos = 0;
$start_count = 0;
$content_start = 0;
while ($pos < strlen($string))
{
if($start_count == 0)
{
$pos = strpos($string, $start, $pos);
//no curlies
if ($pos === false)
{
break;
}
$pos += strlen($start);
$start_count = 1;
$content_start = $pos;
}
else
{
$start_pos = strpos($string, $start, $pos);
$end_pos = strpos($string, $end, $pos);
//nothing more to find.
if ($start_pos === false AND $end_pos === false)
{
break;
}
//end_pos is the next position found
else if ($start_pos === false OR ($end_pos < $start_pos))
{
$start_count--;
$pos = $end_pos + strlen($end);
}
//otherwise start_pos must've been next
else
{
$start_count++;
$pos = $end_pos + strlen($end);
}
if ($start_count == 0)
{
//this is the string from contentstart to the place before the last brace
$curly_content = substr($string, $content_start, $pos-$content_start-1);
if (!preg_match('#^[A-Za-z0-9-_>\\[\\]"\'\\s]*$#', $curly_content))
{
return false;
}
}
}
}
return true;
}
/*
This will escape any dangerous interpolation expressions so they they display literally
instead of being replaced (and executing potentially dangerious code).
This is used were attempting to validate the string and/or displaying an error is problematic.
This allows us to have *somthing* to display.
*/
function make_string_interpolation_safe($string)
{
$start = '{$';
$end = '}';
$pos = 0;
$start_count = 0;
$content_start = 0;
while ($pos < strlen($string))
{
if($start_count == 0)
{
$pos = strpos($string, $start, $pos);
//no curlies
if ($pos === false)
{
break;
}
$pos += strlen($start);
$start_count = 1;
$content_start = $pos;
}
else
{
$start_pos = strpos($string, $start, $pos);
$end_pos = strpos($string, $end, $pos);
//nothing more to find.
if ($start_pos === false AND $end_pos === false)
{
break;
}
//end_pos is the next position found
else if ($start_pos === false OR ($end_pos < $start_pos))
{
$start_count--;
$pos = $end_pos + strlen($end);
}
//otherwise start_pos must've been next
else
{
$start_count++;
$pos = $end_pos + strlen($end);
}
if ($start_count == 0)
{
//this is the string from contentstart to the place before the last brace
$curly_content = substr($string, $content_start, $pos-$content_start-1);
if (!preg_match('#^[A-Za-z0-9-_>\\[\\]"\'\\s]*$#', $curly_content))
{
$count = 0;
$curly_content = '{\\$' . str_replace('{$', '{\\$', $curly_content, $count) . '}';
$string = substr_replace($string, $curly_content, $content_start - strlen($start),
$pos-$content_start-1+strlen($start)+strlen($end));
//adjust the pos to account for the fact that we've added characters to the string. After this, pos
//should still be on the closing brace of the curly expression.
$pos += ($count + 1);
}
}
}
}
return $string;
}
/*======================================================================*\
|| ####################################################################
|| # CVS: $RCSfile$ - $Revision: 36117 $
|| ####################################################################
\*======================================================================*/
?>