replace) // returns substituted string. // WARNING: this is pretty basic, and doesn't properly handle search strings that are substrings of each other. // For instance if 'test' => "foo" and 'testing' => "bar", testing could become either bar or fooing, // depending on the order in which they were declared in the array. require_once("include/template_processor.php"); if(! function_exists('replace_macros')) { function replace_macros($s,$r) { global $t; return $t->replace($s,$r); }} // random string, there are 86 characters max in text mode, 128 for hex // output is urlsafe define('RANDOM_STRING_HEX', 0x00 ); define('RANDOM_STRING_TEXT', 0x01 ); if(! function_exists('random_string')) { function random_string($size = 64,$type = RANDOM_STRING_HEX) { // generate a bit of entropy and run it through the whirlpool $s = hash('whirlpool', (string) rand() . uniqid(rand(),true) . (string) rand(),(($type == RANDOM_STRING_TEXT) ? true : false)); $s = (($type == RANDOM_STRING_TEXT) ? str_replace("\n","",base64url_encode($s,true)) : $s); return(substr($s,0,$size)); }} /** * This is our primary input filter. * * The high bit hack only involved some old IE browser, forget which (IE5/Mac?) * that had an XSS attack vector due to stripping the high-bit on an 8-bit character * after cleansing, and angle chars with the high bit set could get through as markup. * * This is now disabled because it was interfering with some legitimate unicode sequences * and hopefully there aren't a lot of those browsers left. * * Use this on any text input where angle chars are not valid or permitted * They will be replaced with safer brackets. This may be filtered further * if these are not allowed either. * */ if(! function_exists('notags')) { function notags($string) { return(str_replace(array("<",">"), array('[',']'), $string)); // High-bit filter no longer used // return(str_replace(array("<",">","\xBA","\xBC","\xBE"), array('[',']','','',''), $string)); }} // use this on "body" or "content" input where angle chars shouldn't be removed, // and allow them to be safely displayed. if(! function_exists('escape_tags')) { function escape_tags($string) { return(htmlspecialchars($string)); }} // generate a string that's random, but usually pronounceable. // used to generate initial passwords if(! function_exists('autoname')) { function autoname($len) { $vowels = array('a','a','ai','au','e','e','e','ee','ea','i','ie','o','ou','u'); if(mt_rand(0,5) == 4) $vowels[] = 'y'; $cons = array( 'b','bl','br', 'c','ch','cl','cr', 'd','dr', 'f','fl','fr', 'g','gh','gl','gr', 'h', 'j', 'k','kh','kl','kr', 'l', 'm', 'n', 'p','ph','pl','pr', 'qu', 'r','rh', 's','sc','sh','sm','sp','st', 't','th','tr', 'v', 'w','wh', 'x', 'z','zh' ); $midcons = array('ck','ct','gn','ld','lf','lm','lt','mb','mm', 'mn','mp', 'nd','ng','nk','nt','rn','rp','rt'); $noend = array('bl', 'br', 'cl','cr','dr','fl','fr','gl','gr', 'kh', 'kl','kr','mn','pl','pr','rh','tr','qu','wh'); $start = mt_rand(0,2); if($start == 0) $table = $vowels; else $table = $cons; $word = ''; for ($x = 0; $x < $len; $x ++) { $r = mt_rand(0,count($table) - 1); $word .= $table[$r]; if($table == $vowels) $table = array_merge($cons,$midcons); else $table = $vowels; } $word = substr($word,0,$len); foreach($noend as $noe) { if((strlen($word) > 2) && (substr($word,-2) == $noe)) { $word = substr($word,0,-1); break; } } if(substr($word,-1) == 'q') $word = substr($word,0,-1); return $word; }} // escape text ($str) for XML transport // returns escaped text. if(! function_exists('xmlify')) { function xmlify($str) { $buffer = ''; for($x = 0; $x < mb_strlen($str); $x ++) { $char = $str[$x]; switch( $char ) { case "\r" : break; case "&" : $buffer .= '&'; break; case "'" : $buffer .= '''; break; case "\"" : $buffer .= '"'; break; case '<' : $buffer .= '<'; break; case '>' : $buffer .= '>'; break; case "\n" : $buffer .= "\n"; break; default : $buffer .= $char; break; } } $buffer = trim($buffer); return($buffer); }} // undo an xmlify // pass xml escaped text ($s), returns unescaped text if(! function_exists('unxmlify')) { function unxmlify($s) { $ret = str_replace('&','&', $s); $ret = str_replace(array('<','>','"','''),array('<','>','"',"'"),$ret); return $ret; }} // convenience wrapper, reverse the operation "bin2hex" if(! function_exists('hex2bin')) { function hex2bin($s) { if(! (is_string($s) && strlen($s))) return ''; if(! ctype_xdigit($s)) { logger('hex2bin: illegal input: ' . print_r(debug_backtrace(), true)); return($s); } return(pack("H*",$s)); }} // Automatic pagination. // To use, get the count of total items. // Then call $a->set_pager_total($number_items); // Optionally call $a->set_pager_itemspage($n) to the number of items to display on each page // Then call paginate($a) after the end of the display loop to insert the pager block on the page // (assuming there are enough items to paginate). // When using with SQL, the setting LIMIT %d, %d => $a->pager['start'],$a->pager['itemspage'] // will limit the results to the correct items for the current page. // The actual page handling is then accomplished at the application layer. if(! function_exists('paginate')) { function paginate(&$a) { $o = ''; $stripped = preg_replace('/(&page=[0-9]*)/','',$a->query_string); $stripped = str_replace('q=','',$stripped); $stripped = trim($stripped,'/'); $pagenum = $a->pager['page']; $url = $a->get_baseurl() . '/' . $stripped; if($a->pager['total'] > $a->pager['itemspage']) { $o .= '
(.*?)<\/pre>/ism','smile_encode',$s);
	$s = preg_replace_callback('/(.*?)<\/code>/ism','smile_encode',$s);
	$texts =  array( 
		'<3', 
		'</3', 
		'<\\3', 
		':-)', 
//		':)', 
		';-)', 
//		';)', 
		':-(', 
//		':(', 
		':-P', 
//		':P', 
		':-"', 
		':-"', 
		':-x', 
		':-X', 
		':-D', 
//		':D', 
		'8-|', 
		'8-O', 
		':-O', 
		'\\o/', 
		'o.O', 
		'O.o', 
		'\\.../', 
		'\\ooo/', 
		":'(", 
		":-!", 
		":-/", 
		":-[", 
		"8-)",
		':beer', 
		':homebrew', 
		':coffee', 
		':facepalm',
		':headdesk',
		'~friendika', 
		'~friendica', 
		'Diaspora*' 
	);
	$icons = array(
		' . '/images/smiley-heart.gif) ',
		'
',
		' . '/images/smiley-brokenheart.gif) ',
		'
',
		' . '/images/smiley-brokenheart.gif) ',
		'
',
		' . '/images/smiley-smile.gif) ',
//		'
',
//		' . '/images/smiley-smile.gif) ',
		'
',
		' . '/images/smiley-wink.gif) ',
//		'
',
//		' . '/images/smiley-wink.gif) ',                
		'
',                
		' . '/images/smiley-frown.gif) ',
//		'
',
//		' . '/images/smiley-frown.gif) ',
		'
',
		' . '/images/smiley-tongue-out.gif) ',
//		'
',
//		' . '/images/smiley-tongue-out.gif) ',
		'
',
		' . '/images/smiley-kiss.gif) ',
		'
',
		' . '/images/smiley-kiss.gif) ',
		'
',
		' . '/images/smiley-kiss.gif) ',
		'
',
		' . '/images/smiley-kiss.gif) ',
		'
',
		' . '/images/smiley-laughing.gif) ',
//		'
',
//		' . '/images/smiley-laughing.gif) ',                
		'
',                
		' . '/images/smiley-surprised.gif) ',
		'
',
		' . '/images/smiley-surprised.gif) ',
		'
',
		' . '/images/smiley-surprised.gif) ',                
		'
',                
		' . '/images/smiley-thumbsup.gif) ',
		'
',
		' . '/images/smiley-Oo.gif) ',
		'
',
		' . '/images/smiley-Oo.gif) ',
		'
',
		' . '/images/smiley-shaka.gif) ',
		'
',
		' . '/images/smiley-shaka.gif) ',
		'
',
		' . '/images/smiley-cry.gif) ',
		'
',
		' . '/images/smiley-foot-in-mouth.gif) ',
		'
',
		' . '/images/smiley-undecided.gif) ',
		'
',
		' . '/images/smiley-embarassed.gif) ',
		'
',
		' . '/images/smiley-cool.gif) ',
		'
',
		' . '/images/beer_mug.gif) ',
		'
',
		' . '/images/beer_mug.gif) ',
		'
',
		' . '/images/coffee.gif) ',
		'
',
		' . '/images/smiley-facepalm.gif) ',
		'
',
		' . '/images/smiley-bangheaddesk.gif) ',
		'~friendika
',
		'~friendika  . '/images/friendika-16.png) ',
		'~friendica
',
		'~friendica  . '/images/friendica-16.png) ',
		'Diaspora
',
		'Diaspora . '/images/diaspora.png) ',
	);
	$params = array('texts' => $texts, 'icons' => $icons, 'string' => $s);
	call_hooks('smilie', $params);
	if($sample) {
		$s = '';
		for($x = 0; $x < count($params['texts']); $x ++) {
			$s .= '
',
	);
	$params = array('texts' => $texts, 'icons' => $icons, 'string' => $s);
	call_hooks('smilie', $params);
	if($sample) {
		$s = '';
		for($x = 0; $x < count($params['texts']); $x ++) {
			$s .= '- ' . $params['texts'][$x] . '
- ' . $params['icons'][$x] . '
';
		}
	}
	else {
		$params['string'] = preg_replace_callback('/<(3+)/','preg_heart',$params['string']);
		$s = str_replace($params['texts'],$params['icons'],$params['string']);
	}
	$s = preg_replace_callback('/(.*?)<\/pre>/ism','smile_decode',$s);
	$s = preg_replace_callback('/(.*?)<\/code>/ism','smile_decode',$s);
	return $s;
}}
function smile_encode($m) {
	return(str_replace($m[1],base64url_encode($m[1]),$m[0]));
}
function smile_decode($m) {
	return(str_replace($m[1],base64url_decode($m[1]),$m[0]));
}
// expand <3333 to the correct number of hearts
function preg_heart($x) {
	$a = get_app();
	if(strlen($x[1]) == 1)
		return $x[0];
	$t = '';
	for($cnt = 0; $cnt < strlen($x[1]); $cnt ++)
		$t .= ' . '/images/smiley-heart.gif) ';
	$r =  str_replace($x[0],$t,$x[0]);
	return $r;
}
if(! function_exists('day_translate')) {
function day_translate($s) {
	$ret = str_replace(array('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'),
		array( t('Monday'), t('Tuesday'), t('Wednesday'), t('Thursday'), t('Friday'), t('Saturday'), t('Sunday')),
		$s);
	$ret = str_replace(array('January','February','March','April','May','June','July','August','September','October','November','December'),
		array( t('January'), t('February'), t('March'), t('April'), t('May'), t('June'), t('July'), t('August'), t('September'), t('October'), t('November'), t('December')),
		$ret);
	return $ret;
}}
if(! function_exists('normalise_link')) {
function normalise_link($url) {
	$ret = str_replace(array('https:','//www.'), array('http:','//'), $url);
	return(rtrim($ret,'/'));
}}
/**
 *
 * Compare two URLs to see if they are the same, but ignore
 * slight but hopefully insignificant differences such as if one 
 * is https and the other isn't, or if one is www.something and 
 * the other isn't - and also ignore case differences.
 *
 * Return true if the URLs match, otherwise false.
 *
 */
if(! function_exists('link_compare')) {
function link_compare($a,$b) {
	if(strcasecmp(normalise_link($a),normalise_link($b)) === 0)
		return true;
	return false;
}}
// Given an item array, convert the body element from bbcode to html and add smilie icons.
// If attach is true, also add icons for item attachments
if(! function_exists('prepare_body')) {
function prepare_body($item,$attach = false) {
	call_hooks('prepare_body_init', $item); 
	$s = prepare_text($item['body']);
	$prep_arr = array('item' => $item, 'html' => $s);
	call_hooks('prepare_body', $prep_arr);
	$s = $prep_arr['html'];
	if(! $attach)
		return $s;
	$arr = explode(',',$item['attach']);
	if(count($arr)) {
		$s .= '';
		foreach($arr as $r) {
			$matches = false;
			$icon = '';
			$cnt = preg_match('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"\[\/attach\]|',$r,$matches);
			if($cnt) {
				$icontype = strtolower(substr($matches[3],0,strpos($matches[3],'/')));
				switch($icontype) {
					case 'video':
					case 'audio':
					case 'image':
					case 'text':
						$icon = '';
						break;
					default:
						$icon = '';
						break;
				}
				$title = ((strlen(trim($matches[4]))) ? escape_tags(trim($matches[4])) : escape_tags($matches[1]));
				$title .= ' ' . $matches[2] . ' ' . t('bytes');
				$s .= '' . $icon . '';
			}
		}
		$s .= '';
	}
	$prep_arr = array('item' => $item, 'html' => $s);
	call_hooks('prepare_body_final', $prep_arr);
	return $prep_arr['html'];
}}
// Given a text string, convert from bbcode to html and add smilie icons.
if(! function_exists('prepare_text')) {
function prepare_text($text) {
	require_once('include/bbcode.php');
	if(stristr($text,'[nosmile]'))
		$s = bbcode($text);
	else
		$s = smilies(bbcode($text));
	return $s;
}}
/**
 * return atom link elements for all of our hubs
 */
if(! function_exists('feed_hublinks')) {
function feed_hublinks() {
	$hub = get_config('system','huburl');
	$hubxml = '';
	if(strlen($hub)) {
		$hubs = explode(',', $hub);
		if(count($hubs)) {
			foreach($hubs as $h) {
				$h = trim($h);
				if(! strlen($h))
					continue;
				$hubxml .= '' . "\n" ;
			}
		}
	}
	return $hubxml;
}}
/* return atom link elements for salmon endpoints */
if(! function_exists('feed_salmonlinks')) {
function feed_salmonlinks($nick) {
	$a = get_app();
	$salmon  = '' . "\n" ;
	// old style links that status.net still needed as of 12/2010 
	$salmon .= '  ' . "\n" ; 
	$salmon .= '  ' . "\n" ; 
	return $salmon;
}}
if(! function_exists('get_plink')) {
function get_plink($item) {
	$a = get_app();	
	if (x($item,'plink') && (! $item['private'])){
		return array(
			'href' => $item['plink'],
			'title' => t('link to source'),
		);
	} else {
		return false;
	}
}}
if(! function_exists('unamp')) {
function unamp($s) {
	return str_replace('&', '&', $s);
}}
if(! function_exists('lang_selector')) {
function lang_selector() {
	global $lang;
	$o = '';
	$o .= '';
	return $o;
}}
if(! function_exists('return_bytes')) {
function return_bytes ($size_str) {
    switch (substr ($size_str, -1))
    {
        case 'M': case 'm': return (int)$size_str * 1048576;
        case 'K': case 'k': return (int)$size_str * 1024;
        case 'G': case 'g': return (int)$size_str * 1073741824;
        default: return $size_str;
    }
}}
function generate_user_guid() {
	$found = true;
	do {
		$guid = random_string(16);
		$x = q("SELECT `uid` FROM `user` WHERE `guid` = '%s' LIMIT 1",
			dbesc($guid)
		);
		if(! count($x))
			$found = false;
	} while ($found == true );
	return $guid;
}
function base64url_encode($s, $strip_padding = false) {
	$s = strtr(base64_encode($s),'+/','-_');
	if($strip_padding)
		$s = str_replace('=','',$s);
	return $s;
}
function base64url_decode($s) {
	if(is_array($s)) {
		logger('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true));
		return $s;
	}
/*
 *  // Placeholder for new rev of salmon which strips base64 padding.
 *  // PHP base64_decode handles the un-padded input without requiring this step
 *  // Uncomment if you find you need it.
 *
 *	$l = strlen($s);
 *	if(! strpos($s,'=')) {
 *		$m = $l % 4;
 *		if($m == 2)
 *			$s .= '==';
 *		if($m == 3)
 *			$s .= '=';
 *	}
 *
 */
	return base64_decode(strtr($s,'-_','+/'));
}
if (!function_exists('str_getcsv')) {
    function str_getcsv($input, $delimiter = ',', $enclosure = '"', $escape = '\\', $eol = '\n') {
        if (is_string($input) && !empty($input)) {
            $output = array();
            $tmp    = preg_split("/".$eol."/",$input);
            if (is_array($tmp) && !empty($tmp)) {
                while (list($line_num, $line) = each($tmp)) {
                    if (preg_match("/".$escape.$enclosure."/",$line)) {
                        while ($strlen = strlen($line)) {
                            $pos_delimiter       = strpos($line,$delimiter);
                            $pos_enclosure_start = strpos($line,$enclosure);
                            if (
                                is_int($pos_delimiter) && is_int($pos_enclosure_start)
                                && ($pos_enclosure_start < $pos_delimiter)
                                ) {
                                $enclosed_str = substr($line,1);
                                $pos_enclosure_end = strpos($enclosed_str,$enclosure);
                                $enclosed_str = substr($enclosed_str,0,$pos_enclosure_end);
                                $output[$line_num][] = $enclosed_str;
                                $offset = $pos_enclosure_end+3;
                            } else {
                                if (empty($pos_delimiter) && empty($pos_enclosure_start)) {
                                    $output[$line_num][] = substr($line,0);
                                    $offset = strlen($line);
                                } else {
                                    $output[$line_num][] = substr($line,0,$pos_delimiter);
                                    $offset = (
                                                !empty($pos_enclosure_start)
                                                && ($pos_enclosure_start < $pos_delimiter)
                                                )
                                                ?$pos_enclosure_start
                                                :$pos_delimiter+1;
                                }
                            }
                            $line = substr($line,$offset);
                        }
                    } else {
                        $line = preg_split("/".$delimiter."/",$line);
   
                        /*
                         * Validating against pesky extra line breaks creating false rows.
                         */
                        if (is_array($line) && !empty($line[0])) {
                            $output[$line_num] = $line;
                        } 
                    }
                }
                return $output;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
} 
function cleardiv() {
	return '';
}
function bb_translate_video($s) {
	$matches = null;
	$r = preg_match_all("/\[video\](.*?)\[\/video\]/ism",$s,$matches,PREG_SET_ORDER);
	if($r) {
		foreach($matches as $mtch) {
			if((stristr($mtch[1],'youtube')) || (stristr($mtch[1],'youtu.be')))
				$s = str_replace($mtch[0],'[youtube]' . $mtch[1] . '[/youtube]',$s);
			elseif(stristr($mtch[1],'vimeo'))
				$s = str_replace($mtch[0],'[vimeo]' . $mtch[1] . '[/vimeo]',$s);
		}
	}
	return $s;	
}
function html2bb_video($s) {
	$s = preg_replace('##ism',
			'[youtube]$2[/youtube]', $s);
	$s = preg_replace('##ism',
			'[youtube]$2[/youtube]', $s);
	$s = preg_replace('##ism',
			'[vimeo]$2[/vimeo]', $s);
	return $s;
}
/**
 * apply xmlify() to all values of array $val, recursively
 */
function array_xmlify($val){
	if (is_bool($val)) return $val?"true":"false";
	if (is_array($val)) return array_map('array_xmlify', $val);
	return xmlify((string) $val);
}
function reltoabs($text, $base)
{
  if (empty($base))
    return $text;
  $base = rtrim($base,'/');
  $base2 = $base . "/";
 	
  // Replace links
  $pattern = "/]*) href=\"(?!http|https|\/)([^\"]*)\"/";
  $replace = "]*) href=\"(?!http|https)([^\"]*)\"/";
  $replace = "]*) src=\"(?!http|https|\/)([^\"]*)\"/";
  $replace = "
';
	$r =  str_replace($x[0],$t,$x[0]);
	return $r;
}
if(! function_exists('day_translate')) {
function day_translate($s) {
	$ret = str_replace(array('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'),
		array( t('Monday'), t('Tuesday'), t('Wednesday'), t('Thursday'), t('Friday'), t('Saturday'), t('Sunday')),
		$s);
	$ret = str_replace(array('January','February','March','April','May','June','July','August','September','October','November','December'),
		array( t('January'), t('February'), t('March'), t('April'), t('May'), t('June'), t('July'), t('August'), t('September'), t('October'), t('November'), t('December')),
		$ret);
	return $ret;
}}
if(! function_exists('normalise_link')) {
function normalise_link($url) {
	$ret = str_replace(array('https:','//www.'), array('http:','//'), $url);
	return(rtrim($ret,'/'));
}}
/**
 *
 * Compare two URLs to see if they are the same, but ignore
 * slight but hopefully insignificant differences such as if one 
 * is https and the other isn't, or if one is www.something and 
 * the other isn't - and also ignore case differences.
 *
 * Return true if the URLs match, otherwise false.
 *
 */
if(! function_exists('link_compare')) {
function link_compare($a,$b) {
	if(strcasecmp(normalise_link($a),normalise_link($b)) === 0)
		return true;
	return false;
}}
// Given an item array, convert the body element from bbcode to html and add smilie icons.
// If attach is true, also add icons for item attachments
if(! function_exists('prepare_body')) {
function prepare_body($item,$attach = false) {
	call_hooks('prepare_body_init', $item); 
	$s = prepare_text($item['body']);
	$prep_arr = array('item' => $item, 'html' => $s);
	call_hooks('prepare_body', $prep_arr);
	$s = $prep_arr['html'];
	if(! $attach)
		return $s;
	$arr = explode(',',$item['attach']);
	if(count($arr)) {
		$s .= '';
		foreach($arr as $r) {
			$matches = false;
			$icon = '';
			$cnt = preg_match('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"\[\/attach\]|',$r,$matches);
			if($cnt) {
				$icontype = strtolower(substr($matches[3],0,strpos($matches[3],'/')));
				switch($icontype) {
					case 'video':
					case 'audio':
					case 'image':
					case 'text':
						$icon = '';
						break;
					default:
						$icon = '';
						break;
				}
				$title = ((strlen(trim($matches[4]))) ? escape_tags(trim($matches[4])) : escape_tags($matches[1]));
				$title .= ' ' . $matches[2] . ' ' . t('bytes');
				$s .= '' . $icon . '';
			}
		}
		$s .= '';
	}
	$prep_arr = array('item' => $item, 'html' => $s);
	call_hooks('prepare_body_final', $prep_arr);
	return $prep_arr['html'];
}}
// Given a text string, convert from bbcode to html and add smilie icons.
if(! function_exists('prepare_text')) {
function prepare_text($text) {
	require_once('include/bbcode.php');
	if(stristr($text,'[nosmile]'))
		$s = bbcode($text);
	else
		$s = smilies(bbcode($text));
	return $s;
}}
/**
 * return atom link elements for all of our hubs
 */
if(! function_exists('feed_hublinks')) {
function feed_hublinks() {
	$hub = get_config('system','huburl');
	$hubxml = '';
	if(strlen($hub)) {
		$hubs = explode(',', $hub);
		if(count($hubs)) {
			foreach($hubs as $h) {
				$h = trim($h);
				if(! strlen($h))
					continue;
				$hubxml .= '' . "\n" ;
			}
		}
	}
	return $hubxml;
}}
/* return atom link elements for salmon endpoints */
if(! function_exists('feed_salmonlinks')) {
function feed_salmonlinks($nick) {
	$a = get_app();
	$salmon  = '' . "\n" ;
	// old style links that status.net still needed as of 12/2010 
	$salmon .= '  ' . "\n" ; 
	$salmon .= '  ' . "\n" ; 
	return $salmon;
}}
if(! function_exists('get_plink')) {
function get_plink($item) {
	$a = get_app();	
	if (x($item,'plink') && (! $item['private'])){
		return array(
			'href' => $item['plink'],
			'title' => t('link to source'),
		);
	} else {
		return false;
	}
}}
if(! function_exists('unamp')) {
function unamp($s) {
	return str_replace('&', '&', $s);
}}
if(! function_exists('lang_selector')) {
function lang_selector() {
	global $lang;
	$o = '';
	$o .= '';
	return $o;
}}
if(! function_exists('return_bytes')) {
function return_bytes ($size_str) {
    switch (substr ($size_str, -1))
    {
        case 'M': case 'm': return (int)$size_str * 1048576;
        case 'K': case 'k': return (int)$size_str * 1024;
        case 'G': case 'g': return (int)$size_str * 1073741824;
        default: return $size_str;
    }
}}
function generate_user_guid() {
	$found = true;
	do {
		$guid = random_string(16);
		$x = q("SELECT `uid` FROM `user` WHERE `guid` = '%s' LIMIT 1",
			dbesc($guid)
		);
		if(! count($x))
			$found = false;
	} while ($found == true );
	return $guid;
}
function base64url_encode($s, $strip_padding = false) {
	$s = strtr(base64_encode($s),'+/','-_');
	if($strip_padding)
		$s = str_replace('=','',$s);
	return $s;
}
function base64url_decode($s) {
	if(is_array($s)) {
		logger('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true));
		return $s;
	}
/*
 *  // Placeholder for new rev of salmon which strips base64 padding.
 *  // PHP base64_decode handles the un-padded input without requiring this step
 *  // Uncomment if you find you need it.
 *
 *	$l = strlen($s);
 *	if(! strpos($s,'=')) {
 *		$m = $l % 4;
 *		if($m == 2)
 *			$s .= '==';
 *		if($m == 3)
 *			$s .= '=';
 *	}
 *
 */
	return base64_decode(strtr($s,'-_','+/'));
}
if (!function_exists('str_getcsv')) {
    function str_getcsv($input, $delimiter = ',', $enclosure = '"', $escape = '\\', $eol = '\n') {
        if (is_string($input) && !empty($input)) {
            $output = array();
            $tmp    = preg_split("/".$eol."/",$input);
            if (is_array($tmp) && !empty($tmp)) {
                while (list($line_num, $line) = each($tmp)) {
                    if (preg_match("/".$escape.$enclosure."/",$line)) {
                        while ($strlen = strlen($line)) {
                            $pos_delimiter       = strpos($line,$delimiter);
                            $pos_enclosure_start = strpos($line,$enclosure);
                            if (
                                is_int($pos_delimiter) && is_int($pos_enclosure_start)
                                && ($pos_enclosure_start < $pos_delimiter)
                                ) {
                                $enclosed_str = substr($line,1);
                                $pos_enclosure_end = strpos($enclosed_str,$enclosure);
                                $enclosed_str = substr($enclosed_str,0,$pos_enclosure_end);
                                $output[$line_num][] = $enclosed_str;
                                $offset = $pos_enclosure_end+3;
                            } else {
                                if (empty($pos_delimiter) && empty($pos_enclosure_start)) {
                                    $output[$line_num][] = substr($line,0);
                                    $offset = strlen($line);
                                } else {
                                    $output[$line_num][] = substr($line,0,$pos_delimiter);
                                    $offset = (
                                                !empty($pos_enclosure_start)
                                                && ($pos_enclosure_start < $pos_delimiter)
                                                )
                                                ?$pos_enclosure_start
                                                :$pos_delimiter+1;
                                }
                            }
                            $line = substr($line,$offset);
                        }
                    } else {
                        $line = preg_split("/".$delimiter."/",$line);
   
                        /*
                         * Validating against pesky extra line breaks creating false rows.
                         */
                        if (is_array($line) && !empty($line[0])) {
                            $output[$line_num] = $line;
                        } 
                    }
                }
                return $output;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
} 
function cleardiv() {
	return '';
}
function bb_translate_video($s) {
	$matches = null;
	$r = preg_match_all("/\[video\](.*?)\[\/video\]/ism",$s,$matches,PREG_SET_ORDER);
	if($r) {
		foreach($matches as $mtch) {
			if((stristr($mtch[1],'youtube')) || (stristr($mtch[1],'youtu.be')))
				$s = str_replace($mtch[0],'[youtube]' . $mtch[1] . '[/youtube]',$s);
			elseif(stristr($mtch[1],'vimeo'))
				$s = str_replace($mtch[0],'[vimeo]' . $mtch[1] . '[/vimeo]',$s);
		}
	}
	return $s;	
}
function html2bb_video($s) {
	$s = preg_replace('##ism',
			'[youtube]$2[/youtube]', $s);
	$s = preg_replace('##ism',
			'[youtube]$2[/youtube]', $s);
	$s = preg_replace('##ism',
			'[vimeo]$2[/vimeo]', $s);
	return $s;
}
/**
 * apply xmlify() to all values of array $val, recursively
 */
function array_xmlify($val){
	if (is_bool($val)) return $val?"true":"false";
	if (is_array($val)) return array_map('array_xmlify', $val);
	return xmlify((string) $val);
}
function reltoabs($text, $base)
{
  if (empty($base))
    return $text;
  $base = rtrim($base,'/');
  $base2 = $base . "/";
 	
  // Replace links
  $pattern = "/]*) href=\"(?!http|https|\/)([^\"]*)\"/";
  $replace = "]*) href=\"(?!http|https)([^\"]*)\"/";
  $replace = "]*) src=\"(?!http|https|\/)([^\"]*)\"/";
  $replace = " ]*) src=\"(?!http|https)([^\"]*)\"/";
  $replace = "
]*) src=\"(?!http|https)([^\"]*)\"/";
  $replace = "