function _stripos($haystack, $needle) { if ($this->_charset == 'utf-8') { if (MBYTE_strlen($needle) > 0) { $haystack = MBYTE_strtolower($haystack); return MBYTE_strpos($haystack, $needle); } else { return false; } } if (function_exists('stripos')) { return stripos($haystack, $needle); } else { return strpos(strtolower($haystack), strtolower($needle)); } }
/** * Unescapes certain HTML for editing again. * * @access Private * @param string $in Text escaped to unescape for editing * @return string Unescaped string */ function _editUnescape($in) { if ($this->_postmode == 'html' || $this->_postmode == 'wikitext') { /* Raw and code blocks need entity decoding. Other areas do not. * otherwise, annoyingly, < will end up as < on preview 1, on * preview 2 it'll be stripped by KSES. Can't beleive I missed that * in rewrite phase 1. * * First, raw */ $inlower = MBYTE_strtolower($in); $buffer = $in; $start_pos = MBYTE_strpos($inlower, '[raw]'); if ($start_pos !== false) { $out = ''; while ($start_pos !== false) { /* Copy in to start to out */ $out .= MBYTE_substr($buffer, 0, $start_pos); /* Find end */ $end_pos = MBYTE_strpos($inlower, '[/raw]'); if ($end_pos !== false) { /* Encode body and append to out */ $encoded = html_entity_decode(MBYTE_substr($buffer, $start_pos, $end_pos - $start_pos)); $out .= $encoded . '[/raw]'; /* Nibble in */ $inlower = MBYTE_substr($inlower, $end_pos + 6); $buffer = MBYTE_substr($buffer, $end_pos + 6); } else { // missing [/raw] // Treat the remainder as code, but this should have been // checked prior to calling: $out .= html_entity_decode(MBYTE_substr($buffer, $start_pos + 5)); $inlower = ''; } $start_pos = MBYTE_strpos($inlower, '[raw]'); } // Append remainder: if ($buffer != '') { $out .= $buffer; } $in = $out; } /* * Then, code */ $inlower = MBYTE_strtolower($in); $buffer = $in; $start_pos = MBYTE_strpos($inlower, '[code]'); if ($start_pos !== false) { $out = ''; while ($start_pos !== false) { /* Copy in to start to out */ $out .= MBYTE_substr($buffer, 0, $start_pos); /* Find end */ $end_pos = MBYTE_strpos($inlower, '[/code]'); if ($end_pos !== false) { /* Encode body and append to out */ $encoded = html_entity_decode(MBYTE_substr($buffer, $start_pos, $end_pos - $start_pos)); $out .= $encoded . '[/code]'; /* Nibble in */ $inlower = MBYTE_substr($inlower, $end_pos + 7); $buffer = MBYTE_substr($buffer, $end_pos + 7); } else { // missing [/code] // Treat the remainder as code, but this should have been // checked prior to calling: $out .= html_entity_decode(MBYTE_substr($buffer, $start_pos + 6)); $inlower = ''; } $start_pos = MBYTE_strpos($inlower, '[code]'); } // Append remainder: if ($buffer != '') { $out .= $buffer; } $in = $out; } return $in; } else { // advanced editor or plaintext can handle themselves... return $in; } }
private static function _unescapeSpecialTag($in, $tags) { $inlower = MBYTE_strtolower($in); $start_pos = MBYTE_strpos($inlower, $tags[0]); if ($start_pos === false) { return $in; } $buffer = $in; $out = ''; while ($start_pos !== false) { // Copy in to start to out $out .= MBYTE_substr($buffer, 0, $start_pos); // Find end $end_pos = MBYTE_strpos($inlower, $tags[1]); if ($end_pos !== false) { // Encode body and append to out $encoded = html_entity_decode(MBYTE_substr($buffer, $start_pos, $end_pos - $start_pos)); $out .= $encoded . $tags[1]; $len_end = strlen($tags[1]); // Nibble in $inlower = MBYTE_substr($inlower, $end_pos + $len_end); $buffer = MBYTE_substr($buffer, $end_pos + $len_end); } else { // missing end $len_start = strlen($tags[0]); // Treat the remainder as code, but this should have been // checked prior to calling: $out .= html_entity_decode(MBYTE_substr($buffer, $start_pos + $len_start)); $inlower = ''; } $start_pos = MBYTE_strpos($inlower, $tags[0]); } // Append remainder: if ($buffer != '') { $out .= $buffer; } return $out; }
public function testMBYTE_strposWhenOffsetNotNull() { $this->markTestSkipped(); $this->assertEquals(4, MBYTE_strpos(utf8_encode('Användare'), 'n', 2)); }
/** * This function will allow plugins to support the use of custom autolinks * in other site content. Plugins can now use this API when saving content * and have the content checked for any autolinks before saving. * The autolink would be like: [story:20040101093000103 here] * * @param string $content Content that should be parsed for autolinks * @param string $plugin Optional if you only want to parse using a specific plugin * @param string $remove Optional if you want to remove the autotag from the content * */ function PLG_replaceTags($content, $plugin = '', $remove = false) { global $_CONF, $_TABLES, $LANG32; if (isset($_CONF['disable_autolinks']) && $_CONF['disable_autolinks'] == 1) { // autolinks are disabled - return $content unchanged return $content; } if ($remove) { $autolinkModules = PLG_collectTags('nopermission'); if (!is_array($autolinkModules)) { // a permission check may not return any data so no point parsing content return $content; } } else { $autolinkModules = PLG_collectTags(); } for ($i = 1; $i <= 5; $i++) { // For each supported module, scan the content looking for any AutoLink tags $tags = array(); $contentlen = MBYTE_strlen($content); $content_lower = MBYTE_strtolower($content); foreach ($autolinkModules as $moduletag => $module) { $autotag_prefix = '[' . $moduletag . ':'; $offset = 0; $prev_offset = 0; while ($offset < $contentlen) { $start_pos = MBYTE_strpos($content_lower, $autotag_prefix, $offset); if ($start_pos === false) { break; } else { $end_pos = MBYTE_strpos($content_lower, ']', $start_pos); $next_tag = MBYTE_strpos($content_lower, '[', $start_pos + 1); if ($end_pos > $start_pos and ($next_tag === false or $end_pos < $next_tag)) { $taglength = $end_pos - $start_pos + 1; $tag = MBYTE_substr($content, $start_pos, $taglength); $parms = explode(' ', $tag); // Extra test to see if autotag was entered with a space // after the module name if (MBYTE_substr($parms[0], -1) == ':') { $startpos = MBYTE_strlen($parms[0]) + MBYTE_strlen($parms[1]) + 2; $label = str_replace(']', '', MBYTE_substr($tag, $startpos)); $tagid = $parms[1]; } else { $label = str_replace(']', '', MBYTE_substr($tag, MBYTE_strlen($parms[0]) + 1)); $parms = explode(':', $parms[0]); if (count($parms) > 2) { // whoops, there was a ':' in the tag id ... array_shift($parms); $tagid = implode(':', $parms); } else { $tagid = $parms[1]; } } $newtag = array('module' => $module, 'tag' => $moduletag, 'tagstr' => $tag, 'startpos' => $start_pos, 'length' => $taglength, 'parm1' => str_replace(']', '', $tagid), 'parm2' => $label); $tags[] = $newtag; } else { // Error: tags do not match - return with no changes return $content . $LANG32[32]; } $prev_offset = $offset; $offset = $end_pos; } } } // If we have found 1 or more AutoLink tag if (count($tags) > 0) { // Found the [tag] - Now process them all foreach ($tags as $autotag) { if ($remove) { $content = str_replace($autotag['tagstr'], '', $content); } else { $function = 'plugin_autotags_' . $autotag['module']; if (function_exists($function) and (empty($plugin) or $plugin == $autotag['module'])) { $content = $function('parse', $content, $autotag); } } } } else { break; } } return $content; }
} $p->set_var('LANG_SUBMITDATE', _MD_SUBMITDATE); $p->set_var('datetime', $datetime); $p->set_var('version', $version); // Check if restricted access has been enabled for download report to admin's only if ($hits > 0 && !$mydownloads_dlreport || $hits > 0 && SEC_hasRights('filemgmt.edit')) { $p->set_var('begin_dlreport_link', "<a href=\"{$_CONF['site_url']}/filemgmt/downloadhistory.php?lid={$lid}\" target=\"_blank\">"); $p->set_var('end_dlreport_link', '</a>'); } else { $p->set_var('begin_dlreport_link', ''); $p->set_var('end_dlreport_link', ''); } $p->set_var('download_times', sprintf(_MD_DLTIMES, $hits)); $p->set_var('download_count', $hits); $p->set_var('LANG_FILESIZE', _MD_FILESIZE); $pos = MBYTE_strpos($url, ':'); if ($pos === false) { $p->set_var('file_size', PrettySize($size)); } else { if ($size != 0) { $p->set_var('file_size', PrettySize($size)); } else { $p->set_var('file_size', 'Remote'); } } $p->set_var('homepage_url', $homepage); $p->set_var('LANG_HOMEPAGE', _MD_HOMEPAGE); $p->set_var('homepage', $homepage); if ($comments) { USES_lib_comments(); $commentCount = DB_count($_TABLES['comments'], 'sid', "fileid_{$lid}");
/** * Saves the user's information back to the database * * @param array $A User's data * @return string HTML error message or meta redirect * */ function saveuser($A) { global $_CONF, $_TABLES, $_USER, $LANG04, $LANG24, $_US_VERBOSE; if ($_US_VERBOSE) { COM_errorLog('**** Inside saveuser in usersettings.php ****', 1); } $reqid = DB_getItem($_TABLES['users'], 'pwrequestid', "uid = {$_USER['uid']}"); if ($reqid != $A['uid']) { DB_change($_TABLES['users'], 'pwrequestid', "NULL", 'uid', $_USER['uid']); COM_accessLog("An attempt was made to illegally change the account information of user {$_USER['uid']}."); return COM_refresh($_CONF['site_url'] . '/index.php'); } if (!isset($A['cooktime'])) { // If not set or possibly removed from template - set to default $A['cooktime'] = $_CONF['default_perm_cookie_timeout']; } else { $A['cooktime'] = COM_applyFilter($A['cooktime'], true); } // If empty or invalid - set to user default // So code after this does not fail the user password required test if ($A['cooktime'] < 0) { // note that == 0 is allowed! $A['cooktime'] = $_USER['cookietimeout']; } // to change the password, email address, or cookie timeout, // we need the user's current password $current_password = DB_getItem($_TABLES['users'], 'passwd', "uid = {$_USER['uid']}"); if (!empty($A['passwd']) || $A['email'] != $_USER['email'] || $A['cooktime'] != $_USER['cookietimeout']) { if (empty($A['old_passwd']) || SEC_encryptPassword($A['old_passwd']) != $current_password) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=83'); } elseif ($_CONF['custom_registration'] && function_exists('CUSTOM_userCheck')) { $ret = CUSTOM_userCheck($A['username'], $A['email']); if (!empty($ret)) { // Need a numeric return for the default message handler // - if not numeric use default message if (!is_numeric($ret['number'])) { $ret['number'] = 400; } return COM_refresh("{$_CONF['site_url']}/usersettings.php?msg={$ret['number']}"); } } } elseif ($_CONF['custom_registration'] && function_exists('CUSTOM_userCheck')) { $ret = CUSTOM_userCheck($A['username'], $A['email']); if (!empty($ret)) { // Need a numeric return for the default message handler // - if not numeric use default message if (!is_numeric($ret['number'])) { $ret['number'] = 400; } return COM_refresh("{$_CONF['site_url']}/usersettings.php?msg={$ret['number']}"); } } // no need to filter the password as it's encoded anyway if ($_CONF['allow_username_change'] == 1) { $A['new_username'] = COM_applyFilter($A['new_username']); if (!empty($A['new_username']) && $A['new_username'] != $_USER['username']) { $A['new_username'] = addslashes($A['new_username']); if (DB_count($_TABLES['users'], 'username', $A['new_username']) == 0) { if ($_CONF['allow_user_photo'] == 1) { $photo = DB_getItem($_TABLES['users'], 'photo', "uid = {$_USER['uid']}"); if (!empty($photo)) { $newphoto = preg_replace('/' . $_USER['username'] . '/', $A['new_username'], $photo, 1); $imgpath = $_CONF['path_images'] . 'userphotos/'; if (rename($imgpath . $photo, $imgpath . $newphoto) === false) { $display = COM_siteHeader('menu', $LANG04[21]); $display .= COM_errorLog('Could not rename userphoto "' . $photo . '" to "' . $newphoto . '".'); $display .= COM_siteFooter(); return $display; } DB_change($_TABLES['users'], 'photo', addslashes($newphoto), "uid", $_USER['uid']); } } DB_change($_TABLES['users'], 'username', $A['new_username'], "uid", $_USER['uid']); } else { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=51'); } } } // a quick spam check with the unfiltered field contents $profile = '<h1>' . $LANG04[1] . ' ' . $_USER['username'] . '</h1>' . '<p>' . COM_createLink($A['homepage'], $A['homepage']) . '<br' . XHTML . '>' . $A['location'] . '<br' . XHTML . '>' . $A['sig'] . '<br' . XHTML . '>' . $A['about'] . '<br' . XHTML . '>' . $A['pgpkey'] . '</p>'; $result = PLG_checkforSpam($profile, $_CONF['spamx']); if ($result > 0) { COM_displayMessageAndAbort($result, 'spamx', 403, 'Forbidden'); } $A['email'] = COM_applyFilter($A['email']); $A['email_conf'] = COM_applyFilter($A['email_conf']); $A['homepage'] = COM_applyFilter($A['homepage']); // basic filtering only $A['fullname'] = strip_tags(COM_stripslashes($A['fullname'])); $A['location'] = strip_tags(COM_stripslashes($A['location'])); $A['sig'] = strip_tags(COM_stripslashes($A['sig'])); $A['about'] = strip_tags(COM_stripslashes($A['about'])); $A['pgpkey'] = strip_tags(COM_stripslashes($A['pgpkey'])); if (!COM_isEmail($A['email'])) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=52'); } else { if ($A['email'] !== $A['email_conf']) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=78'); } else { if (emailAddressExists($A['email'], $_USER['uid'])) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=56'); } else { if (!empty($A['passwd'])) { if ($A['passwd'] == $A['passwd_conf'] && SEC_encryptPassword($A['old_passwd']) == $current_password) { $passwd = SEC_encryptPassword($A['passwd']); DB_change($_TABLES['users'], 'passwd', "{$passwd}", "uid", $_USER['uid']); if ($A['cooktime'] > 0) { $cooktime = $A['cooktime']; } else { $cooktime = -1000; } SEC_setCookie($_CONF['cookie_password'], $passwd, time() + $cooktime); } elseif (SEC_encryptPassword($A['old_passwd']) != $current_password) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=68'); } elseif ($A['passwd'] != $A['passwd_conf']) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=67'); } } if ($_US_VERBOSE) { COM_errorLog('cooktime = ' . $A['cooktime'], 1); } if ($A['cooktime'] <= 0) { $cooktime = 1000; SEC_setCookie($_CONF['cookie_name'], $_USER['uid'], time() - $cooktime); } else { SEC_setCookie($_CONF['cookie_name'], $_USER['uid'], time() + $A['cooktime']); } if ($_CONF['allow_user_photo'] == 1) { $delete_photo = ''; if (isset($A['delete_photo'])) { $delete_photo = $A['delete_photo']; } $filename = handlePhotoUpload($delete_photo); } if (!empty($A['homepage'])) { $pos = MBYTE_strpos($A['homepage'], ':'); if ($pos === false) { $A['homepage'] = 'http://' . $A['homepage']; } else { $prot = substr($A['homepage'], 0, $pos + 1); if ($prot != 'http:' && $prot != 'https:') { $A['homepage'] = 'http:' . substr($A['homepage'], $pos + 1); } } $A['homepage'] = addslashes($A['homepage']); } $A['fullname'] = addslashes($A['fullname']); $A['email'] = addslashes($A['email']); $A['location'] = addslashes($A['location']); $A['sig'] = addslashes($A['sig']); $A['about'] = addslashes($A['about']); $A['pgpkey'] = addslashes($A['pgpkey']); if (!empty($filename)) { if (!file_exists($_CONF['path_images'] . 'userphotos/' . $filename)) { $filename = ''; } } DB_query("UPDATE {$_TABLES['users']} SET fullname='{$A['fullname']}',email='{$A['email']}',homepage='{$A['homepage']}',sig='{$A['sig']}',cookietimeout={$A['cooktime']},photo='{$filename}' WHERE uid={$_USER['uid']}"); DB_query("UPDATE {$_TABLES['userinfo']} SET pgpkey='{$A['pgpkey']}',about='{$A['about']}',location='{$A['location']}' WHERE uid={$_USER['uid']}"); // Call custom registration save function if enabled and exists if ($_CONF['custom_registration'] and function_exists('CUSTOM_userSave')) { CUSTOM_userSave($_USER['uid']); } PLG_userInfoChanged($_USER['uid']); if ($_US_VERBOSE) { COM_errorLog('**** Leaving saveuser in usersettings.php ****', 1); } return COM_refresh($_CONF['site_url'] . '/users.php?mode=profile&uid=' . $_USER['uid'] . '&msg=5'); } } } }
/** * Saves the user's information back to the database * * @param array $A User's data * @return string HTML error message or meta redirect * */ function saveuser($A) { global $_CONF, $_TABLES, $_USER, $LANG04, $LANG24, $_US_VERBOSE; if ($_US_VERBOSE) { COM_errorLog('**** Inside saveuser in usersettings.php ****', 1); } $reqid = DB_getItem($_TABLES['users'], 'pwrequestid', "uid = {$_USER['uid']}"); if ($reqid != $A['uid']) { DB_change($_TABLES['users'], 'pwrequestid', "NULL", 'uid', $_USER['uid']); COM_accessLog("An attempt was made to illegally change the account information of user {$_USER['uid']}."); return COM_refresh($_CONF['site_url'] . '/index.php'); } if (!isset($A['cooktime'])) { // If not set or possibly removed from template - set to default $A['cooktime'] = $_CONF['default_perm_cookie_timeout']; } else { $A['cooktime'] = COM_applyFilter($A['cooktime'], true); } // If empty or invalid - set to user default // So code after this does not fail the user password required test if ($A['cooktime'] < 0) { // note that == 0 is allowed! $A['cooktime'] = $_USER['cookietimeout']; } // to change the password, email address, or cookie timeout, // we need the user's current password $service = DB_getItem($_TABLES['users'], 'remoteservice', "uid = {$_USER['uid']}"); if ($service == '') { if (!empty($A['passwd']) || $A['email'] != $_USER['email'] || $A['cooktime'] != $_USER['cookietimeout']) { // verify password if (empty($A['old_passwd']) || SEC_encryptUserPassword($A['old_passwd'], $_USER['uid']) < 0) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=83'); } elseif ($_CONF['custom_registration'] && function_exists('CUSTOM_userCheck')) { $ret = CUSTOM_userCheck($A['username'], $A['email']); if (!empty($ret)) { // Need a numeric return for the default message handler // - if not numeric use default message if (!is_numeric($ret['number'])) { $ret['number'] = 400; } return COM_refresh("{$_CONF['site_url']}/usersettings.php?msg={$ret['number']}"); } } } elseif ($_CONF['custom_registration'] && function_exists('CUSTOM_userCheck')) { $ret = CUSTOM_userCheck($A['username'], $A['email']); if (!empty($ret)) { // Need a numeric return for the default message handler // - if not numeric use default message if (!is_numeric($ret['number'])) { $ret['number'] = 400; } return COM_refresh("{$_CONF['site_url']}/usersettings.php?msg={$ret['number']}"); } } } else { if ($A['email'] != $_USER['email'] || $A['cooktime'] != $_USER['cookietimeout']) { // re athenticate remote user again for these changes to take place // Can't just be done here since user may have to relogin to his service which then sends us back here and we lose his changes } } // no need to filter the password as it's encoded anyway if ($_CONF['allow_username_change'] == 1) { $A['new_username'] = COM_applyFilter($A['new_username']); if (!empty($A['new_username']) && $A['new_username'] != $_USER['username']) { $A['new_username'] = DB_escapeString($A['new_username']); if (DB_count($_TABLES['users'], 'username', $A['new_username']) == 0) { if ($_CONF['allow_user_photo'] == 1) { $photo = DB_getItem($_TABLES['users'], 'photo', "uid = {$_USER['uid']}"); if (!empty($photo)) { $newphoto = preg_replace('/' . $_USER['username'] . '/', $A['new_username'], $photo, 1); $imgpath = $_CONF['path_images'] . 'userphotos/'; if (rename($imgpath . $photo, $imgpath . $newphoto) === false) { $display = COM_errorLog('Could not rename userphoto "' . $photo . '" to "' . $newphoto . '".'); $display = COM_createHTMLDocument($display, array('pagetitle' => $LANG04[21])); return $display; } DB_change($_TABLES['users'], 'photo', DB_escapeString($newphoto), "uid", $_USER['uid']); } } DB_change($_TABLES['users'], 'username', $A['new_username'], "uid", $_USER['uid']); } else { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=51'); } } } // a quick spam check with the unfiltered field contents $profile = '<h1>' . $LANG04[1] . ' ' . $_USER['username'] . '</h1><p>'; // this is a hack, for some reason remoteservice links made SPAMX SLV check barf if (empty($service)) { $profile .= COM_createLink($A['homepage'], $A['homepage']) . '<br' . XHTML . '>'; } $profile .= $A['location'] . '<br' . XHTML . '>' . $A['sig'] . '<br' . XHTML . '>' . $A['about'] . '<br' . XHTML . '>' . $A['pgpkey'] . '</p>'; $result = PLG_checkforSpam($profile, $_CONF['spamx']); if ($result > 0) { COM_displayMessageAndAbort($result, 'spamx', 403, 'Forbidden'); } $A['email'] = COM_applyFilter($A['email']); $A['email_conf'] = COM_applyFilter($A['email_conf']); $A['homepage'] = COM_applyFilter($A['homepage']); // basic filtering only $A['fullname'] = strip_tags(COM_stripslashes($A['fullname'])); $A['location'] = strip_tags(COM_stripslashes($A['location'])); $A['sig'] = strip_tags(COM_stripslashes($A['sig'])); $A['about'] = strip_tags(COM_stripslashes($A['about'])); $A['pgpkey'] = strip_tags(COM_stripslashes($A['pgpkey'])); if (!COM_isEmail($A['email'])) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=52'); } else { if ($A['email'] !== $A['email_conf']) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=78'); } else { if (emailAddressExists($A['email'], $_USER['uid'])) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=56'); } else { $passwd = ''; if ($service == '') { if (!empty($A['passwd'])) { if ($A['passwd'] == $A['passwd_conf'] && SEC_encryptUserPassword($A['old_passwd'], $_USER['uid']) == 0) { SEC_updateUserPassword($A['passwd'], $_USER['uid']); if ($A['cooktime'] > 0) { $cooktime = $A['cooktime']; } else { $cooktime = -1000; } SEC_setCookie($_CONF['cookie_password'], $passwd, time() + $cooktime); } elseif (SEC_encryptUserPassword($A['old_passwd'], $_USER['uid']) < 0) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=68'); } elseif ($A['passwd'] != $A['passwd_conf']) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=67'); } } } else { // Cookie if ($A['cooktime'] > 0) { $cooktime = $A['cooktime']; } else { $cooktime = -1000; } SEC_setCookie($_CONF['cookie_password'], $passwd, time() + $cooktime); } if ($_US_VERBOSE) { COM_errorLog('cooktime = ' . $A['cooktime'], 1); } if ($A['cooktime'] <= 0) { $cooktime = 1000; SEC_setCookie($_CONF['cookie_name'], $_USER['uid'], time() - $cooktime); } else { SEC_setCookie($_CONF['cookie_name'], $_USER['uid'], time() + $A['cooktime']); } if ($_CONF['allow_user_photo'] == 1) { $delete_photo = ''; if (isset($A['delete_photo'])) { $delete_photo = $A['delete_photo']; } $filename = handlePhotoUpload($delete_photo); } if (!empty($A['homepage'])) { $pos = MBYTE_strpos($A['homepage'], ':'); if ($pos === false) { $A['homepage'] = 'http://' . $A['homepage']; } else { $prot = substr($A['homepage'], 0, $pos + 1); if ($prot != 'http:' && $prot != 'https:') { $A['homepage'] = 'http:' . substr($A['homepage'], $pos + 1); } } $A['homepage'] = DB_escapeString($A['homepage']); } $A['fullname'] = DB_escapeString($A['fullname']); $A['email'] = DB_escapeString($A['email']); $A['location'] = DB_escapeString($A['location']); $A['sig'] = DB_escapeString($A['sig']); $A['about'] = DB_escapeString($A['about']); $A['pgpkey'] = DB_escapeString($A['pgpkey']); if (!empty($filename)) { if (!file_exists($_CONF['path_images'] . 'userphotos/' . $filename)) { $filename = ''; } } DB_query("UPDATE {$_TABLES['users']} SET fullname='{$A['fullname']}',email='{$A['email']}',homepage='{$A['homepage']}',sig='{$A['sig']}',cookietimeout={$A['cooktime']},photo='{$filename}' WHERE uid={$_USER['uid']}"); DB_query("UPDATE {$_TABLES['userinfo']} SET pgpkey='{$A['pgpkey']}',about='{$A['about']}',location='{$A['location']}' WHERE uid={$_USER['uid']}"); // Call custom registration save function if enabled and exists if ($_CONF['custom_registration'] and function_exists('CUSTOM_userSave')) { CUSTOM_userSave($_USER['uid']); } PLG_userInfoChanged($_USER['uid']); // at this point, the user information has been saved, but now we're going to check to see if // the user has requested resynchronization with their remoteservice account $msg = 5; // default msg = Your account information has been successfully saved if (isset($A['resynch'])) { if ($_CONF['user_login_method']['oauth'] && strpos($_USER['remoteservice'], 'oauth.') === 0) { $modules = SEC_collectRemoteOAuthModules(); $active_service = count($modules) == 0 ? false : in_array(substr($_USER['remoteservice'], 6), $modules); if (!$active_service) { $status = -1; $msg = 115; // Remote service has been disabled. } else { require_once $_CONF['path_system'] . 'classes/oauthhelper.class.php'; $service = substr($_USER['remoteservice'], 6); $consumer = new OAuthConsumer($service); $callback_url = $_CONF['site_url']; $consumer->setRedirectURL($callback_url); $user = $consumer->authenticate_user(); $consumer->doSynch($user); } } if ($msg != 5) { $msg = 114; // Account saved but re-synch failed. COM_errorLog($MESSAGE[$msg]); } } if ($_US_VERBOSE) { COM_errorLog('**** Leaving saveuser in usersettings.php ****', 1); } return COM_refresh($_CONF['site_url'] . '/users.php?mode=profile&uid=' . $_USER['uid'] . '&msg=' . $msg); } } } }
/** * Sanitize a URL * * @param string $url URL to sanitized * @param array $allowed_protocols array of allowed protocols * @param string $default_protocol replacement protocol (default: http) * @return string sanitized URL * */ function COM_sanitizeUrl($url, $allowed_protocols = '', $default_protocol = '') { global $_CONF; if (empty($allowed_protocols)) { $allowed_protocols = $_CONF['allowed_protocols']; } else { if (!is_array($allowed_protocols)) { $allowed_protocols = array($allowed_protocols); } } if (empty($default_protocol)) { $default_protocol = 'http:'; } else { if (substr($default_protocol, -1) != ':') { $default_protocol .= ':'; } } $url = strip_tags($url); if (!empty($url)) { $pos = MBYTE_strpos($url, ':'); if ($pos === false) { $url = $default_protocol . '//' . $url; } else { $protocol = MBYTE_substr($url, 0, $pos + 1); $found_it = false; foreach ($allowed_protocols as $allowed) { if (substr($allowed, -1) != ':') { $allowed .= ':'; } if ($protocol == $allowed) { $found_it = true; break; } } if (!$found_it) { $url = $default_protocol . MBYTE_substr($url, $pos + 1); } } } return $url; }
/** * Return the topic tree structure in an array. * id ID of topic parent_id ID of parent topic branch_level Level of branch in tree structure title Title of topic language_id Language of topic inherit If topic inherits objects from child topics hidden If topic is hidden exclude If topic is in current users exclude list (1), (0) if not in list access Access current user has with topic owner_id ID of the owner of the topic group_id ID of group topic belongs to perm_owner Permissions the owner has perm_group Permissions the group has perm_members Permissions logged in members have perm_anon Permissions anonymous users have * * @return array * */ function TOPIC_buildTree($id, $parent = '', $branch_level = -1, $tree_array = array()) { global $_TABLES, $_CONF, $_USER, $LANG27; $branch_level = $branch_level + 1; $total_topic = count($tree_array) + 1; if ($id == TOPIC_ROOT) { // Root $tree_array[$total_topic]['id'] = TOPIC_ROOT; $tree_array[$total_topic]['parent_id'] = ''; $tree_array[$total_topic]['branch_level'] = $branch_level; $tree_array[$total_topic]['title'] = $LANG27[37]; $tree_array[$total_topic]['language_id'] = ''; $tree_array[$total_topic]['inherit'] = 1; $tree_array[$total_topic]['hidden'] = 0; $tree_array[$total_topic]['exclude'] = 0; $tree_array[$total_topic]['access'] = 2; // Read Access $tree_array[$total_topic]['owner_id'] = SEC_getDefaultRootUser(); $tree_array[$total_topic]['group_id'] = 1; $tree_array[$total_topic]['perm_owner'] = 2; $tree_array[$total_topic]['perm_group'] = 2; $tree_array[$total_topic]['perm_members'] = 2; $tree_array[$total_topic]['perm_anon'] = 2; $branch_level = $branch_level + 1; } if ($_CONF['sortmethod'] != 'alpha') { $sql_sort = " ORDER BY sortnum"; } else { $sql_sort = " ORDER BY topic ASC"; } if ($parent) { $sql = "SELECT * FROM {$_TABLES['topics']} WHERE parent_id = '{$id}' " . $sql_sort; } else { $sql = "SELECT * FROM {$_TABLES['topics']} WHERE tid = '{$id}' " . $sql_sort; } $result = DB_query($sql); $nrows = DB_numRows($result); if ($nrows > 0) { // Figure out if any excluded topics $excluded_tids = ''; if (!COM_isAnonUser()) { $excluded_tids = DB_getItem($_TABLES['userindex'], 'tids', "uid = '{$_USER['uid']}'"); if (!empty($excluded_tids)) { $excluded_tids = "'" . str_replace(' ', "','", $excluded_tids) . "'"; } } for ($i = 0; $i < $nrows; $i++) { $A = DB_fetchArray($result); $total_topic = count($tree_array) + 1; $tree_array[$total_topic]['id'] = $A['tid']; $tree_array[$total_topic]['parent_id'] = $A['parent_id']; $tree_array[$total_topic]['branch_level'] = $branch_level; $tree_array[$total_topic]['title'] = stripslashes($A['topic']); $tree_array[$total_topic]['language_id'] = COM_getLanguageIdForObject($A['tid']); // figure out language if need be $tree_array[$total_topic]['inherit'] = $A['inherit']; $tree_array[$total_topic]['hidden'] = $A['hidden']; $tree_array[$total_topic]['exclude'] = 0; if (!empty($excluded_tids)) { if (MBYTE_strpos($excluded_tids, $A['tid']) !== false) { $tree_array[$total_topic]['exclude'] = 1; } } $tree_array[$total_topic]['access'] = SEC_hasAccess($A['owner_id'], $A['group_id'], $A['perm_owner'], $A['perm_group'], $A['perm_members'], $A['perm_anon']); // Current User Access $tree_array[$total_topic]['owner_id'] = $A['owner_id']; $tree_array[$total_topic]['group_id'] = $A['group_id']; $tree_array[$total_topic]['perm_owner'] = $A['perm_owner']; $tree_array[$total_topic]['perm_group'] = $A['perm_group']; $tree_array[$total_topic]['perm_members'] = $A['perm_members']; $tree_array[$total_topic]['perm_anon'] = $A['perm_anon']; // See if this topic has any children $tree_array = TOPIC_buildTree($tree_array[$total_topic]['id'], true, $branch_level, $tree_array); } } return $tree_array; }
/** * This function will allow plugins to support the use of custom autolinks * in other site content. Plugins can now use this API when saving content * and have the content checked for any autolinks before saving. * The autolink would be like: [story:20040101093000103 here] * * @param string $content Content that should be parsed for autolinks * @param string $plugin Optional if you only want to parse using a specific plugin * */ function PLG_replaceTags($content, $plugin = '') { global $_CONF, $_TABLES, $LANG32; if (isset($_CONF['disable_autolinks']) && $_CONF['disable_autolinks'] == 1) { // autolinks are disabled - return $content unchanged return $content; } $autolinkModules = PLG_collectTags(); // For each supported module, scan the content looking for any AutoLink tags $tags = array(); $contentlen = MBYTE_strlen($content); $content_lower = MBYTE_strtolower($content); foreach ($autolinkModules as $moduletag => $module) { $autotag_prefix = '[' . $moduletag . ':'; $offset = 0; $prev_offset = 0; while ($offset < $contentlen) { $start_pos = MBYTE_strpos($content_lower, $autotag_prefix, $offset); if ($start_pos === false) { break; } else { $end_pos = MBYTE_strpos($content_lower, ']', $start_pos); $next_tag = MBYTE_strpos($content_lower, '[', $start_pos + 1); if ($end_pos > $start_pos and ($next_tag === false or $end_pos < $next_tag)) { $taglength = $end_pos - $start_pos + 1; $tag = MBYTE_substr($content, $start_pos, $taglength); $parms = explode(' ', $tag); // Extra test to see if autotag was entered with a space // after the module name if (MBYTE_substr($parms[0], -1) == ':') { $startpos = MBYTE_strlen($parms[0]) + MBYTE_strlen($parms[1]) + 2; $label = str_replace(']', '', MBYTE_substr($tag, $startpos)); $tagid = $parms[1]; } else { $label = str_replace(']', '', MBYTE_substr($tag, MBYTE_strlen($parms[0]) + 1)); $parms = explode(':', $parms[0]); if (count($parms) > 2) { // whoops, there was a ':' in the tag id ... array_shift($parms); $tagid = implode(':', $parms); } else { $tagid = $parms[1]; } } $newtag = array('module' => $module, 'tag' => $moduletag, 'tagstr' => $tag, 'startpos' => $start_pos, 'length' => $taglength, 'parm1' => str_replace(']', '', $tagid), 'parm2' => $label); $tags[] = $newtag; } else { // Error: tags do not match - return with no changes return $content . $LANG32[32]; } $prev_offset = $offset; $offset = $end_pos; } } } // If we have found 1 or more AutoLink tag if (count($tags) > 0) { // Found the [tag] - Now process them all foreach ($tags as $autotag) { $function = 'plugin_autotags_' . $autotag['module']; if ($autotag['module'] == 'geeklog' and (empty($plugin) or $plugin == 'geeklog')) { $url = ''; $linktext = $autotag['parm2']; if ($autotag['tag'] == 'story') { $autotag['parm1'] = COM_applyFilter($autotag['parm1']); if (!empty($autotag['parm1'])) { $url = COM_buildUrl($_CONF['site_url'] . '/article.php?story=' . $autotag['parm1']); if (empty($linktext)) { $linktext = stripslashes(DB_getItem($_TABLES['stories'], 'title', "sid = '{$autotag['parm1']}'")); } } } if (!empty($url)) { $filelink = COM_createLink($linktext, $url); $content = str_replace($autotag['tagstr'], $filelink, $content); } } elseif (function_exists($function) and (empty($plugin) or $plugin == $autotag['module'])) { $content = $function('parse', $content, $autotag); } } } return $content; }
/** * Saves the user's information back to the database * * @A array User's data * */ function saveuser($A) { global $_CONF, $_TABLES, $_USER, $LANG04, $LANG24, $_US_VERBOSE; if ($_US_VERBOSE) { COM_errorLog('**** Inside saveuser in usersettings.php ****', 1); } $reqid = DB_getItem($_TABLES['users'], 'pwrequestid', "uid = " . (int) $_USER['uid']); if ($reqid != $A['uid']) { DB_change($_TABLES['users'], 'pwrequestid', "NULL", 'uid', (int) $_USER['uid']); COM_accessLog("An attempt was made to illegally change the account information of user {$_USER['uid']}."); return COM_refresh($_CONF['site_url'] . '/index.php'); } if (isset($_POST['merge'])) { if (COM_applyFilter($_POST['remoteuid'], true) != $_USER['uid']) { echo COM_refresh($_CONF['site_url'] . '/usersettings.php?mode=edit'); } USER_mergeAccounts(); } // If not set or possibly removed from template - initialize variable if (!isset($A['cooktime'])) { $A['cooktime'] = 0; } else { $A['cooktime'] = COM_applyFilter($A['cooktime'], true); } // If empty or invalid - set to user default // So code after this does not fail the user password required test if ($A['cooktime'] < 0) { // note that == 0 is allowed! $A['cooktime'] = $_USER['cookietimeout']; } // to change the password, email address, or cookie timeout, // we need the user's current password $account_type = DB_getItem($_TABLES['users'], 'account_type', "uid = {$_USER['uid']}"); $service = DB_getItem($_TABLES['users'], 'remoteservice', "uid = {$_USER['uid']}"); if ($service == '') { $current_password = DB_getItem($_TABLES['users'], 'passwd', "uid = {$_USER['uid']}"); if (!empty($A['newp']) || $A['email'] != $_USER['email'] || $A['cooktime'] != $_USER['cookietimeout']) { if (empty($A['passwd']) || !SEC_check_hash($A['passwd'], $current_password)) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=83'); } elseif ($_CONF['custom_registration'] && function_exists('CUSTOM_userCheck')) { $ret = CUSTOM_userCheck($A['username'], $A['email']); if (!empty($ret)) { // Need a numeric return for the default message handler // - if not numeric use default message if (!is_numeric($ret)) { $ret['number'] = 97; } return COM_refresh("{$_CONF['site_url']}/usersettings.php?msg={$ret}"); } } } elseif ($_CONF['custom_registration'] && function_exists('CUSTOM_userCheck')) { $ret = CUSTOM_userCheck($A['username'], $A['email']); if (!empty($ret)) { // Need a numeric return for the default message hander - if not numeric use default message // - if not numeric use default message if (!is_numeric($ret)) { $ret = 97; } return COM_refresh("{$_CONF['site_url']}/usersettings.php?msg={$ret}"); } } } // Let plugins have a chance to decide what to do before saving the user, return errors. $msg = PLG_itemPreSave('useredit', $A['username']); if (!empty($msg)) { // need a numeric return value - otherwise use default message if (!is_numeric($msg)) { $msg = 97; } return COM_refresh("{$_CONF['site_url']}/usersettings.php?msg={$msg}"); } // no need to filter the password as it's encoded anyway if ($_CONF['allow_username_change'] == 1) { $A['new_username'] = $A['new_username']; if (!empty($A['new_username']) && USER_validateUsername($A['new_username']) && $A['new_username'] != $_USER['username']) { $A['new_username'] = DB_escapeString($A['new_username']); if (DB_count($_TABLES['users'], 'username', $A['new_username']) == 0) { if ($_CONF['allow_user_photo'] == 1) { $photo = DB_getItem($_TABLES['users'], 'photo', "uid = " . (int) $_USER['uid']); if (!empty($photo) && strstr($photo, $_USER['username']) !== false) { $newphoto = preg_replace('/' . $_USER['username'] . '/', $_USER['uid'], $photo, 1); $imgpath = $_CONF['path_images'] . 'userphotos/'; @rename($imgpath . $photo, $imgpath . $newphoto); DB_change($_TABLES['users'], 'photo', DB_escapeString($newphoto), "uid", (int) $_USER['uid']); } } DB_change($_TABLES['users'], 'username', $A['new_username'], "uid", (int) $_USER['uid']); } else { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=51'); } } } // a quick spam check with the unfiltered field contents $profile = '<h1>' . $LANG04[1] . ' ' . $_USER['username'] . '</h1><p>'; // this is a hack, for some reason remoteservice links made SPAMX SLV check barf if (empty($service)) { $profile .= COM_createLink($A['homepage'], $A['homepage']) . '<br />'; } $profile .= $A['location'] . '<br />' . $A['sig'] . '<br />' . $A['about'] . '<br />' . $A['pgpkey'] . '</p>'; $result = PLG_checkforSpam($profile, $_CONF['spamx']); if ($result > 0) { COM_displayMessageAndAbort($result, 'spamx', 403, 'Forbidden'); } $A['email'] = COM_applyFilter($A['email']); $A['email_conf'] = COM_applyFilter($A['email_conf']); $A['homepage'] = COM_applyFilter($A['homepage']); // basic filtering only $A['fullname'] = COM_truncate(trim(USER_sanitizeName($A['fullname'])), 80); $A['location'] = strip_tags($A['location']); $A['sig'] = strip_tags($A['sig']); $A['about'] = strip_tags($A['about']); $A['pgpkey'] = strip_tags($A['pgpkey']); if (!COM_isEmail($A['email'])) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=52'); } else { if ($A['email'] !== $A['email_conf']) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=78'); } else { if (emailAddressExists($A['email'], $_USER['uid'])) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=56'); } else { if ($service == '') { if (!empty($A['newp'])) { $A['newp'] = trim($A['newp']); $A['newp_conf'] = trim($A['newp_conf']); if ($A['newp'] == $A['newp_conf'] && SEC_check_hash($A['passwd'], $current_password)) { $passwd = SEC_encryptPassword($A['newp']); DB_change($_TABLES['users'], 'passwd', DB_escapeString($passwd), "uid", (int) $_USER['uid']); if ($A['cooktime'] > 0) { $cooktime = $A['cooktime']; $token_ttl = $A['cooktime']; } else { $cooktime = 0; $token_ttl = 14400; } $ltToken = SEC_createTokenGeneral('ltc', $token_ttl); SEC_setCookie($_CONF['cookie_password'], $ltToken, time() + $cooktime); } elseif (!SEC_check_hash($A['passwd'], $current_password)) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=68'); } elseif ($A['newp'] != $A['newp_conf']) { return COM_refresh($_CONF['site_url'] . '/usersettings.php?msg=67'); } } } else { // Cookie if ($A['cooktime'] > 0) { $cooktime = $A['cooktime']; } else { $cooktime = 0; } $ltToken = SEC_createTokenGeneral('ltc', $cooktime); SEC_setCookie($_CONF['cookie_password'], $ltToken, time() + $cooktime); } if ($_US_VERBOSE) { COM_errorLog('cooktime = ' . $A['cooktime'], 1); } if ($A['cooktime'] <= 0) { $cookie_timeout = 0; $token_ttl = 14400; } else { $cookie_timeout = time() + $A['cooktime']; $token_ttl = $A['cooktime']; } SEC_setCookie($_CONF['cookie_name'], $_USER['uid'], $cookie_timeout, $_CONF['cookie_path'], $_CONF['cookiedomain'], $_CONF['cookiesecure'], true); DB_query("DELETE FROM {$_TABLES['tokens']} WHERE owner_id=" . (int) $_USER['uid'] . " AND urlfor='ltc'"); if ($cookie_timeout > 0) { $ltToken = SEC_createTokenGeneral('ltc', $token_ttl); SEC_setCookie($_CONF['cookie_password'], $ltToken, $cookie_timeout, $_CONF['cookie_path'], $_CONF['cookiedomain'], $_CONF['cookiesecure'], true); } else { SEC_setCookie($_CONF['cookie_password'], '', -10000, $_CONF['cookie_path'], $_CONF['cookiedomain'], $_CONF['cookiesecure'], true); } if ($_CONF['allow_user_photo'] == 1) { $delete_photo = ''; if (isset($A['delete_photo'])) { $delete_photo = $A['delete_photo']; } $filename = handlePhotoUpload($delete_photo); } if (!empty($A['homepage'])) { $pos = MBYTE_strpos($A['homepage'], ':'); if ($pos === false) { $A['homepage'] = 'http://' . $A['homepage']; } else { $prot = substr($A['homepage'], 0, $pos + 1); if ($prot != 'http:' && $prot != 'https:') { $A['homepage'] = 'http:' . substr($A['homepage'], $pos + 1); } } $A['homepage'] = DB_escapeString($A['homepage']); } $A['fullname'] = DB_escapeString($A['fullname']); $A['email'] = DB_escapeString($A['email']); $A['location'] = DB_escapeString($A['location']); $A['sig'] = DB_escapeString($A['sig']); $A['about'] = DB_escapeString($A['about']); $A['pgpkey'] = DB_escapeString($A['pgpkey']); if (!empty($filename)) { if (!file_exists($_CONF['path_images'] . 'userphotos/' . $filename)) { $filename = ''; } } DB_query("UPDATE {$_TABLES['users']} SET fullname='{$A['fullname']}',email='{$A['email']}',homepage='{$A['homepage']}',sig='{$A['sig']}',cookietimeout=" . (int) $A['cooktime'] . ",photo='" . DB_escapeString($filename) . "' WHERE uid=" . (int) $_USER['uid']); DB_query("UPDATE {$_TABLES['userinfo']} SET pgpkey='{$A['pgpkey']}',about='{$A['about']}',location='{$A['location']}' WHERE uid=" . (int) $_USER['uid']); // Call custom registration save function if enabled and exists if ($_CONF['custom_registration'] and function_exists('CUSTOM_userSave')) { CUSTOM_userSave($_USER['uid']); } PLG_userInfoChanged((int) $_USER['uid']); // at this point, the user information has been saved, but now we're going to check to see if // the user has requested resynchronization with their remoteservice account $msg = 5; // default msg = Your account information has been successfully saved if (isset($A['resynch'])) { if ($_CONF['user_login_method']['oauth'] && strpos($_USER['remoteservice'], 'oauth.') === 0) { $modules = SEC_collectRemoteOAuthModules(); $active_service = count($modules) == 0 ? false : in_array(substr($_USER['remoteservice'], 6), $modules); if (!$active_service) { $status = -1; $msg = 115; // Remote service has been disabled. } else { require_once $_CONF['path_system'] . 'classes/oauthhelper.class.php'; $service = substr($_USER['remoteservice'], 6); $consumer = new OAuthConsumer($service); $callback_url = $_CONF['site_url']; $consumer->setRedirectURL($callback_url); $user = $consumer->authenticate_user(); $consumer->doSynch($user); } } if ($msg != 5) { $msg = 114; // Account saved but re-synch failed. COM_errorLog($MESSAGE[$msg]); } } PLG_profileExtrasSave(); PLG_profileSave(); if ($_US_VERBOSE) { COM_errorLog('**** Leaving saveuser in usersettings.php ****', 1); } return COM_refresh($_CONF['site_url'] . '/users.php?mode=profile&uid=' . $_USER['uid'] . '&msg=' . $msg); } } } }
public function testMBYTE_strposWhenoOffsetNotNull() { $this->assertEquals(5, MBYTE_strpos('strpos this.', 's', 1)); }
/** * Create an excerpt from some piece of HTML containing a given URL * * This somewhat convoluted piece of code will extract the text around a * given link located somewhere in the given piece of HTML. It returns * the actual link text plus some of the text before and after the link. * * NOTE: Returns an empty string when $url is not found in $html. * * @param string $html The piece of HTML to search through * @param string $url URL that should be contained in $html somewhere * @param int $xlen Max. length of excerpt (default: 255 characters) * @return string Extract: The link text and some surrounding text * */ function PNB_makeExcerpt($html, $url, $xlen = 255) { $retval = ''; // the excerpt will come out as // [...] before linktext after [...] $fill_start = '[...] '; $fill_end = ' [...]'; $f1len = MBYTE_strlen($fill_start); $f2len = MBYTE_strlen($fill_end); // extract all links preg_match_all("/<a[^>]*href=[\"']([^\"']*)[\"'][^>]*>(.*?)<\\/a>/i", $html, $matches); $before = ''; $after = ''; $linktext = ''; $num_matches = count($matches[0]); for ($i = 0; $i < $num_matches; $i++) { if ($matches[1][$i] == $url) { $pos = MBYTE_strpos($html, $matches[0][$i]); $before = COM_getTextContent(MBYTE_substr($html, 0, $pos)); $pos += MBYTE_strlen($matches[0][$i]); $after = COM_getTextContent(MBYTE_substr($html, $pos)); $linktext = COM_getTextContent($matches[2][$i]); break; } } $tlen = MBYTE_strlen($linktext); if ($tlen >= $xlen) { // Special case: The actual link text is already longer (or as long) as // requested. We don't use the "fillers" here but only return the // (shortened) link text itself. if ($tlen > $xlen) { $retval = MBYTE_substr($linktext, 0, $xlen - 3) . '...'; } else { $retval = $linktext; } } else { if (!empty($before)) { $tlen++; } if (!empty($after)) { $tlen++; } // make "before" and "after" text have equal length $rest = ($xlen - $tlen) / 2; // format "before" text $blen = MBYTE_strlen($before); if ($blen < $rest) { // if "before" text is too short, make "after" text longer $rest += $rest - $blen; $retval .= $before; } else { if ($blen > $rest) { $work = MBYTE_substr($before, -($rest * 2)); $w = explode(' ', $work); array_shift($w); // drop first word, as it's probably truncated $w = array_reverse($w); $fill = $rest - $f1len; $b = ''; foreach ($w as $word) { if (MBYTE_strlen($b) + MBYTE_strlen($word) + 1 > $fill) { break; } $b = $word . ' ' . $b; } $b = trim($b); $retval .= $fill_start . $b; $blen = MBYTE_strlen($b); if ($blen < $fill) { $rest += $fill - $blen; } } } // actual link text if (!empty($before)) { $retval .= ' '; } $retval .= $linktext; if (!empty($after)) { $retval .= ' '; } // format "after" text if (!empty($after)) { $alen = MBYTE_strlen($after); if ($alen > $rest) { $work = MBYTE_substr($after, 0, $rest * 2); $w = explode(' ', $work); array_pop($w); // drop last word, as it's probably truncated $fill = $rest - $f2len; $a = ''; foreach ($w as $word) { if (MBYTE_strlen($a) + MBYTE_strlen($word) + 1 > $fill) { break; } $a .= $word . ' '; } $retval .= trim($a) . $fill_end; } } } return $retval; }