<?php
/**
* functions.php - General purpose functions
* @package phlyMail Nahariya 4.0+ Default branch
* @copyright 2001-2010 phlyLabs, Berlin (http://phlylabs.de)
* @version 4.1.8mod1 2010-11-08
*/
function version_format($version = '')
{
$return = '';
for ($i = strlen($version); $i >= 0; $i--) {
if (((strlen($version) - $i) % 2 == 1) && (strlen($version) - $i) != 1) $return = '.' . $return;
$return = substr($version, $i, 1) . $return;
}
return $return;
}
/**
* Recursive stripslashes of a given data structure
* @param string|array String / array to be stripped from slashes
* @return all slashes stripped
*/
function phm_stripslashes($return = '')
{
if (!get_magic_quotes_gpc()) return $return;
if (is_array($return)) {
foreach ($return as $k => $v) {
$return[$k] = (is_array($v)) ? phm_stripslashes($return[$k]) : stripslashes($return[$k]);
}
return $return;
}
return stripslashes($return);
}
/**
* most useful in sending JSON / javascript arrays out, which may contain "evil" characters
*
* @param string $str The string to be escaped
* @param string $chars List of characters to escape @see addcslashes()
* @return string The escaped string
* @since 4.0.1
*/
function phm_addcslashes($str, $chars = '"/\\')
{
return str_replace(array(CRLF, LF, "\r", "\t", "\b"), array('\n', '\n', '', '\t', '\b'), addcslashes(uctc::convert($str, 'utf8', 'utf8', true, 0x3F), $chars));
}
function phm_entities($str)
{
return htmlentities($str, ENT_QUOTES, 'UTF-8');
}
/**
* Searches through the subject for mailto links and changes these in a way, that clicking on one of
* those opens the compose window of phlyMail, currently situated in the "core" handler
* @param string The string to search in
* @return string The same string, but mailto: replaced
* @since 3.0.7
*/
function mailto_2_send($return = '')
{
return preg_replace
('!(mailto:)([^\s<>"?]+)(\?subject=([^\s<>"]+))?!i'
,PHP_SELF.'?load=compose_email&handler=core&'.give_passthrough(1).'&to=\2&subj=\4'
,$return
);
}
/**
* Used to effectively preparing the input string for output in the frontend
* Links and milto:s are replaced, HTML will be optionally sanitized (no external references)
* @param string The string to process
* @param string Output mode: Can be either 'text' for "Plain text" output or 'html'
* @param boolean Sanitize the output (only used, if param 2 is 'text'
* @param string Base link for referring to CID: references for inline elements like images
* @param boolean reference Reference to a variable, where the status is stored, whether the function found inline elements
* @since 3.0.0
*/
function links($return = '', $mode = 'text', $sanitize = false, $cid_link = '', &$found_inline = false)
{
$found_inline = false;
if('text' == $mode) { // Plain text...
// Emailadressen
$return = preg_replace
('!(mailto:)([^\s<>"?]+)(\?subject=([^\s<>"]+))?!i'
,'<a href="'.PHP_SELF.'?load=compose_email&handler=core&'.give_passthrough(1).'&to=\2&subj=\4" target="_blank">\2\3</a>'
,$return
);
// Internet-Protokolle:
$return = preg_replace
('!(http://|https:|ftp://|gopher://|news:|www\.)(.+)(?=<|>|\W[\s\n\r]|[\s\r\n])!Umie'
,"'<a href=\"".addslashes($GLOBALS['_PM_']['path']['frontend'])
."/derefer.php?go='.derefer('\\1\\2').'\" target=\"_blank\">'.links_linebreak('\\1\\2').'</a>'"
,$return
);
return $return;
} else { // HTML ...
// Remove all dangerous items
$return = preg_replace('!<(script|frame|iframe|embed|object|applet).*?>.*?</\1>!si', '', $return);
// Try some basic cleanup to make the parser simpler
$return = preg_replace('!(\</?)(\w+)!e', '"\1".strtolower("\2")', $return);
// Identify style settings for background images
preg_match_all('!\<style.*\>(.+)?\<\/style\>|style="(.+)?"!Us', $return, $found, PREG_SET_ORDER);
if (isset($found) && !empty($found)) {
foreach ($found as $k => $style) {
if (isset($style[2])) $style[1] = $style[2];
if (!isset($style[1])) continue;
preg_match_all('!background.*:.*url\((.+)\)!Ui', $style[1], $found2, PREG_SET_ORDER);
if (isset($found2) && !empty($found2)) {
$found_inline = true;
foreach ($found2 as $k2 => $url) {
$new_url = str_replace
($url[1]
,($sanitize) ? '' : addslashes($GLOBALS['_PM_']['path']['frontend']).'/derefer.php?go='.links_html($url[1])
,$url[0]
);
$style[1] = str_replace($url[0], $new_url, $style[0]);
}
$return = str_replace($style[0], $style[1], $return);
}
}
}
// Prevent external stylesheets from being loaded if Sanitize is on!
preg_match_all('!\<link(.+)href=("|\'|)(.+)(\s|"|\'|\>)!Uis', $return, $found, PREG_SET_ORDER);
if (isset($found) && !empty($found)) {
foreach ($found as $k => $link) {
if ($link[3]{0} == '#') continue;
if (substr($link[3], 0, 4) == 'cid:') {
$neu_link = $cid_link.urlencode(substr($link[3], 4));
} else {
$found_inline = true;
$neu_link = ($sanitize) ? '' : addslashes($GLOBALS['_PM_']['path']['frontend']).'/derefer.php?go='.links_html($link[3]);
}
$neu_link = str_replace($link[3], $neu_link, $link[0]);
$return = str_replace($link[0], $neu_link, $return);
}
}
// Derefer
preg_match_all('!(href|src|action|background|on[a-zA-Z]+)=("|\')?([^\<\>"\']+)!is', $return, $found, PREG_SET_ORDER);
if (isset($found) && !empty($found)) {
foreach ($found as $k => $link) {
if ($link[3]{0} == '#') continue;
$pruef = strtolower($link[1]);
if (substr($link[3], 0, 4) == 'cid:') {
$neu_link = $cid_link.urlencode(substr($link[3], 4));
} else {
$found_inline = true;
if ('src' == $pruef || 'background' == $pruef) {
$neu_link = ($sanitize)
? ('src' == $pruef ? addslashes($GLOBALS['_PM_']['path']['theme']).'/images/blocked.gif' : '')
: addslashes($GLOBALS['_PM_']['path']['frontend']).'/derefer.php?go='.links_html($link[3])
;
} elseif ('href' == $pruef || 'action' == $pruef) {
$ignore = false;
$link_html = links_html($link[3], $ignore);
$neu_link = ($ignore) ? $link_html : addslashes($GLOBALS['_PM_']['path']['frontend']).'/derefer.php?go='.$link_html;
} else {
$neu_link = '';
}
}
$neu_link = str_replace($link[3], $neu_link, $link[0]);
$return = str_replace($link[0], $neu_link, $return);
}
}
// target="_blank"
preg_match_all('!\<a\b.+\>!Us', $return, $found, PREG_SET_ORDER);
if ($found && !empty($found)) {
foreach ($found as $k => $href) {
if (preg_match('!href="?#!i', $href[0])) continue;
if (!preg_match('!href=!i', $href[0])) continue;
$neu_href = $href[0];
$neu_href = preg_replace(array('!target="?\w+"?!i', '!(\<a\s)(.+\>)!Usi'), array('', '\1target="_blank" \2'), $neu_href);
$return = str_replace($href[0], $neu_href, $return);
}
}
return $return;
}
}
function links_html($return = '', &$ignore = null)
{
if (substr(strtolower($return), 0, 7) == 'mailto:') {
$ignore = true;
return mailto_2_send($return);
} else {
$ignore = false;
return derefer($return);
}
}
function derefer($return = '')
{
return htmlentities(urlencode(un_html($return)));
}
function links_linebreak($return = '')
{
if (isset($GLOBALS['_PM_']['core']['read_wordwrap']) && '0' != $GLOBALS['_PM_']['core']['read_wordwrap']
&& preg_match('/([^\s]{'.$GLOBALS['_PM_']['core']['read_wordwrap'].',})/', $return)) {
return htmlspecialchars(preg_replace('/([^\s]{'.$GLOBALS['_PM_']['core']['read_wordwrap'].'})/', '\\1 ',
un_html($return)));
} else return $return;
}
function un_html($return = '')
{
return preg_replace
(array('!>!i', '!<!i', '!"!i', '!&!i', '! !i', '!©!i')
,array('>', '<', '"', '&', ' ', '(c)')
,$return
);
}
/**
* Converts plain text to HTML,underlines links
* @param string Text to convert
* @return string HTMLized text
* @since 3.1.7
*/
function text2html($text)
{
$text = nl2br(htmlspecialchars($text, ENT_COMPAT, 'utf-8'));
// Emailadressen
$text = preg_replace
('!(mailto:)([^\s<>"?]+)(\?subject=([^\s<>"]+))?!i'
,'<a href="\1\2\3">\2</a>'
,$text
);
// Internet-Protokolle:
$text = preg_replace
('!(http://|https:|ftp://|gopher://|news:|www\.)(.+)(?=<|>|\W[\s\n\r]|[\s\r\n]|$)!Umi'
,'<a href="\\1\\2">\\1\\2</a>'
,$text.LF
);
return $text;
}
/**
* Runs thorugh any mail header field containing multiple addresses such as To: or Cc:
* What you receive as return value(s) quiet much depends on the parameters.
* You can either set $print, $sendtoadb or $separate to true.
*
* @param string $address The header fields' value
* @param int $limit Maximum number of individual addresses to process, pass 0 for no limit; Default: 10
* @param print|maillist|read
* 'print': Prepare the return val for printing (no linkage, complete adress and real name)
* 'read': Prepare the "add to address book" linkage
* 'maillist': Return an array structurally compatible to mailparser::parse_email_address()
*[@param int $shorten_to Whether to shorten the return value to a certain length; Default: 0 (no)]
* @return mixed
*/
function multi_address($address = '', $limit = 10, $usage = 'read', $shorten_to = 0)
{
if ($usage == 'read') {
require_once($GLOBALS['_PM_']['path']['handler'].'/contacts/api.php');
$cAPI = new api_contacts($GLOBALS['_PM_'], $_SESSION['phM_uid']);
}
$return = ('maillist' == $usage || 'sort' == $usage) ? array('', '', '') : '';
$duration = strlen($address);
$mode = '';
$j = 1;
$add = '';
for ($i = 0; $i <= $duration; ++$i) {
$test = substr($address, $i, 1);
if ('comment' == $mode && ')' == $test) { $mode = ''; continue; }
if ('string' == $mode && '"' == $test) { $mode = ''; continue; }
if ('' == $mode) {
if ('(' == $test) { $mode = 'comment'; continue; }
if ('"' == $test) { $mode = 'string'; continue; }
if (',' == $test) {
$found[$j] = $i;
$j++;
if ($limit > 0 && $j > $limit) {
if ($duration > $i && $usage != 'sort') $add = ', ...';
$duration = $i;
$address = substr($address, 0, $i);
break;
}
}
}
}
$found[0] = 0;
$found[$j] = $duration;
for ($k = 0; $k < $j; ++$k) {
$l = $k + 1;
if (0 != $k) ++$found[$k];
$build = substr($address, $found[$k], ($found[$l] - $found[$k]));
$build = mailparser::parse_email_address($build, 0, ($usage == 'send'));
if ('print' == $usage) {
$build = htmlspecialchars($build[2]);
if (0 != $k) $return .= ', ';
$return .= $build;
} elseif ('maillist' == $usage || 'sort' == $usage) {
if (0 != $k) {
$return[0] .= ', ';
$return[1] .= ', ';
$return[2] .= ', ';
}
$return[0] .= $build[0];
$return[1] .= $build[1];
$return[2] .= $build[2];
} elseif ('send' == $usage) {
if (0 != $k) $return .= ', ';
$return .= $build[0].(!empty($build[1]) ? ' ('.$build[1].')' : '');
} else {
if ($build[2] == '') continue;
$AID = $cAPI->search_contact($build[0], 'email', true);
if (!$AID) {
$sendtoadb = '<img src="$themes$/icons/contacts_sendto.gif" title="$title$" class="sendtoadb" onclick="sendtoadb(\''
.phm_addcslashes($build[0], "'").'\', \''.phm_addcslashes($build[1], "'").'\');" />';
} else {
$sendtoadb = '<img src="$themes$/icons/contacts_isindb.gif" title="" class="sendtoadb" onclick="openadb('.$AID.');" />';
}
$build = '<span title="'.$build[2].'">'.$build[1].$sendtoadb.'</span>';
if (0 != $k) $return .= ', ';
$return .= $build;
}
}
if ('maillist' == $usage) {
if ($shorten_to && strlen($return[1]) > $shorten_to) {
$return[1] = substr($return[1], 0, ($shorten_to - 3)) . '...';
} else {
$return[1] = $return[1].$add;
}
return array($return[0].$add, $return[1], $return[2].$add);
} elseif ('sort' == $usage) {
return $return[0];
}
return $return.$add;
}
function give_passthrough($mode = 1)
{
$return = '';
if (isset($GLOBALS['_PM_']['core']['pass_through'])) {
if (1 == $mode) {
foreach ($GLOBALS['_PM_']['core']['pass_through'] as $key => $value) {
if (0 < $key) $return .= '&';
if (is_array($GLOBALS[$value])) {
$i = 0;
foreach ($GLOBALS[$value] as $ke2 => $valu2) {
if (0 < $i) $return .= '&';
$return .= $value.'['.$ke2.']='.$valu2;
++$i;
}
} else $return .= $value.'='.$GLOBALS[$value];
}
} elseif (2 == $mode) {
foreach ($GLOBALS['_PM_']['core']['pass_through'] as $key => $value) {
if (is_array($GLOBALS[$value])) {
foreach ($GLOBALS[$value] as $ke2 => $valu2) {
$return .= '<input type="hidden" name="'.$value.'['.$ke2.']" value="'.$valu2.'" />'.LF;
}
} else {
$return .= '<input type="hidden" name="'.$value.'" value="'.$GLOBALS[$value].'" />'.LF;
}
}
} elseif (3 == $mode) {
foreach ($GLOBALS['_PM_']['core']['pass_through'] as $key => $value) {
if (is_array($GLOBALS[$value])) {
foreach($GLOBALS[$value] as $ke2 => $valu2) {
$return[$value.'['.$ke2.']'] = $valu2;
}
} else $return[$value] = $GLOBALS[$value];
}
}
}
if (1 == $mode) {
if ($return) $return .= '&';
$return .= SESS_NAME.'='.SESS_ID;
} elseif (2 == $mode) {
$return .= '<input type="hidden" name="'.SESS_NAME.'" value="'.SESS_ID.'" />'.LF;
} elseif (3 == $mode) {
$return[SESS_NAME] = SESS_ID;
}
return $return;
}
/**
* Meant for formatting byte values (file / mail sizes and the like) to make a sensible but short output
* Capable of GB, MB, B(ytes)
* @param int The value to format
*[@param bool Set to true, the spacer between the number and the "B(yte)" will be just a space else
*[@param bool true for Bytes, MBytes, ...; else B, MB, ... will be output
*[@param bool true for using units of 1000 (binary prefix), else units of 1024 (SI prefixes) will be used
* @since 3.0.0
*/
function size_format($size = '', $plain = false, $long = false, $si = false)
{
// Is probably wrong, better a input switch which tells, whether the input uses 1024 or 1000
if (preg_match('!^(\d+)(M|K|G)$!', trim($size), $found)) {
$size = $found[1] * ($found[2] == 'K' ? pow(2, 10) : ($found[2] == 'M' ? pow(2, 20) : pow(2, 30)));
}
if (preg_match('!^(\d+)(M|K|G)iB$!', trim($size), $found)) {
$size = $found[1] * ($found[2] == 'K' ? pow(10, 3) : ($found[2] == 'M' ? pow(10, 6) : pow(10, 9)));
}
$msg = &$GLOBALS['WP_msg'];
$n = ($plain) ? ' ' : ' ';
$b = (!$long) ? 'B' : 'Bytes';
if ($si) {
if (floor($size/pow(10, 9)) > 0) return number_format(($size/pow(10, 9)), 1, $msg['dec'], $msg['tho']).$n.'G'.$b;
if (floor($size/pow(10, 6)) > 0) return number_format(($size/pow(10, 6)), 1, $msg['dec'], $msg['tho']).$n.'M'.$b;
if (floor($size/pow(10, 3)) > 0) return number_format(($size/pow(10, 3)), 1, $msg['dec'], $msg['tho']).$n.'K'.$b;
} else {
if (floor($size/pow(2, 30)) > 0) return number_format(($size/pow(2, 30)), 1, $msg['dec'], $msg['tho']).$n.'Gi'.$b;
if (floor($size/pow(2, 20)) > 0) return number_format(($size/pow(2, 20)), 1, $msg['dec'], $msg['tho']).$n.'Mi'.$b;
if (floor($size/pow(2, 10)) > 0) return number_format(($size/pow(2, 10)), 1, $msg['dec'], $msg['tho']).$n.'Ki'.$b;
}
return trim(floor($size)).$n.$b;
}
/**
* Nicely formats plain text body parts for HTML output in the forntend
*
* @param strin $return The body part to format
* @param string $teletype Either sys or pro
* @param bool $parseFormat Whether to replace *bold*, /italic/ and _underline_ by HTML markup
*/
function nice_view($return = '', $teletype = '', $parseFormat = true)
{
$sigon = false;
$return = str_replace(array(CRLF, "\r"), array(LF, LF), $return);
$lines = explode(LF, $return);
if (!count($lines)) return '';
foreach ($lines as $ky => $val) {
if ($val == '-- ') $sigon = true;
if ($sigon) {
$lines[$ky] = '<span class="quote_1">'.$val.'</span>';
continue;
}
if (isset($GLOBALS['_PM_']['theme']['read_wordwrap']) && $GLOBALS['_PM_']['theme']['read_wordwrap'] &&
preg_match('/([^\s]{'.$GLOBALS['_PM_']['theme']['read_wordwrap'].',})/', $val)) {
if(!preg_match('!(http://|https://|ftp://|gopher://|mailto:|news:)!', $val)) {
$val = preg_replace('/([^\s]{'.$GLOBALS['_PM_']['theme']['read_wordwrap'].'})/', '\\1 ', $val);
}
}
$val = htmlspecialchars($val);
// Replace text formattings (if set)
if ($parseFormat) {
$val = preg_replace
(array('/(?<=^|\s)\*(?=\S)(.+)(?<=\S)\*(?=\s|,|.|$)/U'
,'/(?<=^|\s)\/(?=\S)(.+)(?<=\S)\/(?=\s|,|.|$)/U'
,'/(?<=^|\s)\_(?=\S)(.+)(?<=\S)\_(?=\s|,|.|$)/U'
)
,array('<strong>*\1*</strong>', '<em>/\1/</em>', '<span class="underline">_\1_</span>')
,$val
);
}
unset($found);
if (preg_match_all('!^(\ ?(\>\ ?)+)!i', $val, $found)) {
$farbe = (substr_count($found[0][0], '>') % 4);
if (0 == $farbe) $farbe = 4;
$lines[$ky] = '<span class="quote_'.$farbe.'">'. (('sys' == $teletype) ? '<tt>'.$val.'</tt>' : $val) . '</span>';
} else $lines[$ky] = $val;
}
return links(implode('sys' == $teletype ? LF : '<br />'.LF, $lines));
}
function save_config($file, $tokens, $tokval)
{
if (!file_exists($file)) {
touch($file);
chmod($file, $GLOBALS['_PM_']['core']['file_umask']);
}
$GlChFile = file_get_contents($file);
// Remove PHP tags
$GlChFile = preg_replace('!^'.preg_quote('<?php die(); ?>', '!').LF.'!', '', $GlChFile);
foreach ($tokens as $k => $v) {
if (preg_match('/^'.$tokens[$k].';;[^\r^\n]*/mi', $GlChFile)) {
$tokval[$k] = str_replace('$', '\$', $tokval[$k]); // Treat '$' literally
$GlChFile = preg_replace('/^'.$tokens[$k].';;[^\r^\n]*/mi', $tokens[$k].';;'.$tokval[$k], $GlChFile);
} else {
$GlChFile .= $tokens[$k].';;'.$tokval[$k].LF;
}
}
$stat = file_put_contents($file, '<?php die(); ?>'.LF.$GlChFile);
if ($$stat) return true;
return false;
}
function wash_size_field($size = '0')
{
$size = preg_replace('![\ \.,]!', '', $size);
$size = preg_replace('!^([^0-9]*)([0-9]+)(t|m|k|g){0,1}!i', '\\2 \\3', $size);
$parts = explode(' ', $size, 2);
if (!isset($parts[1])) return $parts[0];
$size = $parts[0];
switch (strtolower($parts[1])) {
case 't': $size *= 1024; # fall through
case 'g': $size *= 1024; # fall through
case 'm': $size *= 1024; # fall through
case 'k': $size *= 1024;
}
return $size;
}
// Encrypt a string
// Input: confuse(string $data, string $key);
// Returns: encrypted string
function confuse($data = '', $key = '')
{
$encoded = ''; $DataLen = strlen($data);
if (strlen($key) < $DataLen) $key = str_repeat($key, ceil($DataLen/strlen($key)));
for ($i = 0; $i < $DataLen; ++$i) $encoded .= chr((ord($data{$i}) + ord($key{$i})) % 256);
return base64_encode($encoded);
}
// Decrypt a string
// Input: deconfuse(string $data, string $key);
// Returns: decrypted String
function deconfuse($data = '', $key = '')
{
$data = base64_decode($data);
$decoded = ''; $DataLen = strlen($data);
if (strlen($key) < $DataLen) $key = str_repeat($key, ceil($DataLen/strlen($key)));
for($i = 0; $i < $DataLen; ++$i) $decoded .= chr((256 + ord($data{$i}) - ord($key{$i})) % 256);
return $decoded;
}
/**
* Convert a string from any of various encodings to UTF-8
*
* @param string String to encode
* [@param string Encoding; Default: ISO-8859-1]
* [@param bool Safe Mode: if set to TRUE, the original string is retunred on errors]
* @return string The encoded string or false on failure
* @since 3.0.5
*/
function encode_utf8($string = '', $encoding = 'iso-8859-1', $safe_mode = false)
{
$safe = ($safe_mode) ? $string : false;
if (strtoupper($encoding) == 'UTF-8' || strtoupper($encoding) == 'UTF8') {
return $string;
} elseif (strtoupper($encoding) == 'ISO-8859-1') {
return utf8_encode($string);
} elseif (strtoupper($encoding) == 'WINDOWS-1252') {
return utf8_encode(map_w1252_iso8859_1($string));
} elseif (strtoupper($encoding) == 'UNICODE-1-1-UTF-7') {
$encoding = 'utf-7';
}
if (function_exists('mb_convert_encoding')) {
$conv = @mb_convert_encoding($string, 'UTF-8', strtoupper($encoding));
if ($conv) return $conv;
}
if (function_exists('iconv')) {
$conv = @iconv(strtoupper($encoding), 'UTF-8', $string);
if ($conv) return $conv;
}
if (function_exists('libiconv')) {
$conv = @libiconv(strtoupper($encoding), 'UTF-8', $string);
if ($conv) return $conv;
}
return $safe;
}
/**
* Convert a string from UTF-8 to any of various encodings
*
* @param string String to decode
* [@param string Encoding; Default: ISO-8859-1]
* [@param bool Safe Mode: if set to TRUE, the original string is retunred on errors]
* @return string The decoded string or false on failure
* @since 3.0.5
*/
function decode_utf8($string = '', $encoding = 'iso-8859-1', $safe_mode = false)
{
$safe = ($safe_mode) ? $string : false;
if (!$encoding) $encoding = 'ISO-8859-1';
if (strtoupper($encoding) == 'UTF-8' || strtoupper($encoding) == 'UTF8') {
return $string;
} elseif (strtoupper($encoding) == 'ISO-8859-1') {
return utf8_decode($string);
} elseif (strtoupper($encoding) == 'WINDOWS-1252') {
return map_iso8859_1_w1252(utf8_decode($string));
} elseif (strtoupper($encoding) == 'UNICODE-1-1-UTF-7') {
$encoding = 'utf-7';
}
if (function_exists('mb_convert_encoding')) {
$conv = @mb_convert_encoding($string, strtoupper($encoding), 'UTF-8');
if ($conv) return $conv;
}
if (function_exists('iconv')) {
$conv = @iconv('UTF-8', strtoupper($encoding), $string);
if ($conv) return $conv;
}
if (function_exists('libiconv')) {
$conv = @libiconv('UTF-8', strtoupper($encoding), $string);
if ($conv) return $conv;
}
return $safe;
}
/**
* Special treatment for our guys in Redmond
* Windows-1252 is basically ISO-8859-1 -- with some exceptions, which get accounted for here
* @param string Your input in Win1252
* @param string The resulting ISO-8859-1 string
* @since 3.0.8
*/
function map_w1252_iso8859_1($string = '')
{
if ($string == '') return '';
$return = '';
for ($i = 0; $i < strlen($string); ++$i) {
$c = ord($string{$i});
switch ($c) {
case 129: $return .= chr(252); break;
case 132: $return .= chr(228); break;
case 142: $return .= chr(196); break;
case 148: $return .= chr(246); break;
case 153: $return .= chr(214); break;
case 154: $return .= chr(220); break;
case 225: $return .= chr(223); break;
default: $return .= chr($c); break;
}
}
return $return;
}
/**
* Special treatment for our guys in Redmond
* Windows-1252 is basically ISO-8859-1 -- with some exceptions, which get accounted for here
* @param string Your input in ISO-8859-1
* @param string The resulting Win1252 string
* @since 3.0.8
*/
function map_iso8859_1_w1252($string = '')
{
if ($string == '') return '';
$return = '';
for ($i = 0; $i < strlen($string); ++$i) {
$c = ord($string{$i});
switch ($c) {
case 196: $return .= chr(142); break;
case 214: $return .= chr(153); break;
case 220: $return .= chr(154); break;
case 223: $return .= chr(225); break;
case 228: $return .= chr(132); break;
case 246: $return .= chr(148); break;
case 252: $return .= chr(129); break;
default: $return .= chr($c); break;
}
}
return $return;
}
/**
* Compares to version of a specific software with each other. Both arguments should follow the same versioning scheme
* @param string Version of the software, which is currently in use or checked for
* @param string Minimum required version for a certain functionality
* @return bool TRUE, if the required version is there, FALSE if not
* @since 3.2.2
*/
function PHM_version_compare($is, $should)
{
$is = preg_replace('![^0-9\.]!', '', $is);
$is = explode('.', $is);
$should = preg_replace('![^0-9\.]!', '', $should);
$should = explode('.', $should);
foreach ($should as $k => $v) {
if (!isset($is[$k])) $is[$k] = 0;
if ($should[$k] < $is[$k]) return true;
if ($should[$k] > $is[$k]) return false;
}
return true;
}
/**
* Function to join _PM_ with other config sources (like user settings).
* Since array_merge canonly merge flat arrays and array_merge_recursive appends doublettes
* to the father element we have to do the merge "manually"
* @param array inital _PM_ array
* @param array Data to join the array with (identical structure!)
* @return array Merged _PM_ array
* @since 3.2.4
*/
function merge_PM($_PM_, $import)
{
if (!is_array($import) || empty($import)) return $_PM_;
foreach ($import as $k => $v) {
if (is_array($v)) {
foreach ($v as $k2 => $v2) $_PM_[$k][$k2] = $v2;
} else $_PM_[$k] = $v;
}
return $_PM_;
}
/**
* Outputs Javascript to the client to allow communication between frontend and application.
* In case of JSON data to send, just pass the array, object or scalar to send, otherwise
* pass a string.
*
* @param string|array Javascript command string / JSON structure to send
* @param bool Whether this is JSON or real javascript code; Default: TRUE
* @param bool Whether to exit right after sending the output; Defautl true
* @return void
* @since 3.3.6
*/
function sendJS($command, $is_json = true, $exit = true)
{
if (!headers_sent()) {
header('ETag: PUB' . time());
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()-10) . ' GMT');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 5) . ' GMT');
header('Pragma: no-cache');
header('Cache-Control: max-age=1, s-maxage=1, no-cache, must-revalidate');
header('Content-Type: '.($is_json ? 'application/json' : 'text/javascript').'; charset=utf-8');
}
if ($is_json) {
echo json_encode($command);
} else {
echo $command, LF;
}
if ($exit) exit;
}
/**
* Use our own implementation of QP encoder
*
* @param string $return Unencoded string
*[@param int $maxlen Maimum line length; Deafult: 75]
* @return string Encoded string
* @since 4.1.2
*/
function phm_quoted_printable_encode($return = '', $maxlen = 75)
{
$schachtel = '';
$return = rtrim($return, "\r\n");
// Ersetzen der lt. RFC 1521 nötigen Zeichen
$return = preg_replace('/([^\t\x20\x2E\041-\074\076-\176])/ie', "sprintf('=%2X',ord('\\1'))", $return);
$return = preg_replace('!=\ ([A-F0-9])!', '=0\\1', $return);
// Einfügen von QP-Breaks (=\r\n)
if ($maxlen && strlen($return) > $maxlen) {
$length = strlen($return); $offset = 0;
do {
$step = 76;
$add_mode = (($offset+$step) < $length) ? 1 : 0;
$auszug = substr($return, $offset, $step);
if (preg_match('!\=$!', $auszug)) $step = 75;
if (preg_match('!\=.$!', $auszug)) $step = 74;
if (preg_match('!\=..$!', $auszug)) $step = 73;
$auszug = substr($return, $offset, $step);
$offset += $step;
$schachtel .= $auszug;
if (1 == $add_mode) $schachtel.= '='.CRLF;
} while ($offset < $length);
$return = $schachtel;
}
$return = preg_replace('!\.$!', '. ', $return);
return rtrim($return, "\r\n").CRLF;
}
// if sha1() is not available, we use the PHP implementation
if (!function_exists('sha1')) {
if (function_exists('hash_algos') && in_array('sha1', hash_algos())) {
function sha1($str) { return hash('sha1', $str); }
} else {
require_once(dirname(__FILE__).'/sha1.inc.php');
function sha1($str) { return sha1::compute($str); }
}
}
// Likewise for sha256
if (!function_exists('sha256')) {
if (function_exists('hash_algos') && in_array('sha256', hash_algos())) {
function sha256($str) { return hash('sha256', $str); }
} else {
require_once(dirname(__FILE__).'/sha256.inc.php');
function sha256($str) { return SHA256::hash($str, 'hex'); }
}
}
?>