MyBB Community Forums

Full Version: [PHP] How to get SEO LINKS link?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi all

I have got Plugin SeoLinks installed. And I have got a problem how to get thread link (this link who was remade by plugin?)?


I tried
get_thread_link()
but it shows showthread?tid=xxx Sad

Thanks
I assume there should be a function in the plugin file. I'd suggest looking there.
I tried but I can't find - so I wrote here.

Here is seolinks code, maby you can find this function?
<?php
/**
 * SEO Plugin for MyBB 1.2 / 1.4
 * Copyright © 2006-2008 Asad Khan, All Rights Reserved!
 *
 * Website: http://www.spicefuse.com
 * License: 
 * This plugin is offered "as is" with no guarantees.
 * You may redistribute it provided the code and credits 
 * remain intact with no changes. This is not distributed
 * under GPL, so you may not re-use the code in any other
 * module, plugin, or program. 
 * 
 * Free for non-commercial purposes!
 *
 */

// Disallow direct access to this file for security reasons
if (!defined("IN_MYBB"))
{
	die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
}
 
// comment it to disable this mod while keeping the 
// dependencies happy!
$plugins->add_hook("global_start", "seo_init");
$plugins->add_hook("pre_output_page", "seo_change_links");

// a little dirty workaround for online location reporting
define("REQUEST_URI", $_SERVER['REQUEST_URI']);

// fix for online.php -- viewing what?
$_SERVER['REQUEST_URI'] = $_SERVER['PHP_SELF'] . ($_SERVER['QUERY_STRING'] != '' ? '?' . $_SERVER['QUERY_STRING'] : ''); 

function seo_info()
{
	return array(
		"name"			=> "SEO Links!",
		"description"	=> "A plugin that does the SEO for links.",
		"website"		=> "http://spicefuse.com",
		"author"		=> "Asad Khan",
		"authorsite"	=> "http://spicefuse.com",
		"version"		=> "1.1 Beta 1",
		"guid"			=> "86a5872dd2e21f88c7be37ecfaff9f86 ",
		"compatibility" => "14*",
	);
}

function seo_activate()
{
	global $db;
	
	// create a group
	$db->write_query("INSERT INTO `".TABLE_PREFIX."settinggroups` VALUES (NULL, 'spicefuse_seo', 'SpiceFuse SEO', 'Settings for the Search engine optimization.', '1', '', '');");
	$id = $db->insert_id();
	
	$db->write_query("
	INSERT INTO `".TABLE_PREFIX."settings` (`sid`, `name`, `title`, `description`, `optionscode`, `value`, `disporder`, `gid`) VALUES 
		(NULL, 'sf_seo_nofollow', 'Add nofollow?', 'Add rel=\"nofollow\" on search engine unfriendly tags? Better keep it yes!', 'yesno', '1', 1, {$id}),
		(NULL, 'sf_seo_force_redirects', 'Force redirects?', 'Force redirects to properly formatted search-engines friendly urls when accessed via old urls of showthread.php?tid=x. Better set it to yes!', 'yesno', '1', 3, {$id}),
		(NULL, 'sf_seo_force_lowercase', 'Force Lowercase Keywords', 'Do you want the SEO plugin to convert keywords to lowercase in the urls, such as ''my-name-t-1.html'' instead of ''My-NAME-t-1.html''?\r\n\r\nBetter set it to ''yes''!', 'yesno', '1', 4, {$id}),
		(NULL, 'sf_seo_case_compatibility', 'Case compatibility?', 'Enabling this will auto-redirect to new urls using the lowercase keywords (if enabled in previous setting). Use it only if you were previously either using BETA 4 or lower version of SEO plugin, or previously you had turned the previous option as ''no'' and now you wish to set it to ''yes''!\r\n\r\nKeep it to yes if unsure.', 'yesno', '1', 5, {$id}),
		(NULL, 'sf_seo_url_type', 'URL Type', 'You have option of choosing two type of urls, one is with keywords (from the title of the thread) and other is without any keywords. \r\n\r\nUse first one if using a latin based character set/language, or use the second one if using a language like persian, arabic, chinese etc. ', 'select\r\n1=Using Keywords (welcome-to-website-t-1.html)\r\n2=Without Keywords (thread-t-1.html)', '1', 6, {$id}),
		(NULL, 'sf_seo_directory_type', 'Directory structure', 'Do you want to append a forum name to topics and forum display page, such that the urls are of type /my-forum/my-topic.html?', 'yesno', '0', 7, {$id}),
		(NULL, 'sf_seo_users_urls', 'SEO User\'s Links? ', 'Convert member.php?action=profile&uid=xy to username-u-xy.html or members/username-xy.html (if directory structure is enabled) ', 'yesno', '1', 8, {$id}),
		(NULL, 'sf_seo_max_description', 'Max Description Length', 'What should be the maximum length, in characters, for the meta description tag?', 'text', '175', 9, {$id}),
		(NULL, 'sf_seo_max_keywords_control', 'Max Keywords Control', 'If you are using the keyword based URLs, and want to limit the number of keywords used in a url, and if you don''t want something like this ''this-is-a-very-long-url-because-it-contains-many-keywords'', then you should enable this setting.', 'yesno', 'yes', 10, {$id}),
		(NULL, 'sf_seo_max_keywords', 'Max Keywords', 'This is the limit for number of keywords (or words) that are used to create a URL, if enabled in the previous setting. ', 'text', '8', 11, {$id}),
		(NULL, 'sf_seo_len_for_keyword', 'Min length to consider keyword?', 'What should be the minimum length (in characters) of a word, before it can even be considered a keyword.\r\n\r\nAsk at SpiceFuse forums if in doubt.', 'text', '2', 12, {$id}),
		(NULL, 'sf_seo_strip_less_len', 'Strip short keywords?', 'Strip keywords if they are shorter than this specified length (in characters)', 'text', '1', 13, {$id}),
		(NULL, 'sf_seo_strip_common_words', 'Strip common words?', 'Strip common english words from the URL keywords such as is, you, are, in, at, the etc.', 'yesno', 'yes', 14, {$id});
	");	
	
	// rebuild settings...
	rebuildsettings();
	
	$htaccess_code = "\r\n# //seo_mod_start\r\n"
				   . "%extra_code%"
				   . "# Uncomment the following and add your forum path if rewrites arent working properly\r\n"
				   . "#RewriteBase /mybb/\r\n"
				   . "RewriteRule ^index.html$ index.php [L,NE]\r\n"
				   . "RewriteRule ^(.*)-t-([0-9]+).html(.*)$ showthread.php?tid=\$2\$3 [QSA,L]\r\n"
				   . "RewriteRule ^(.*)-t-([0-9]+)-([0-9]+).html$ showthread.php?tid=\$2&page=\$3 [QSA,L]\r\n"
				   . "RewriteRule ^(.*)-f-([0-9]+).html(.*)$ forumdisplay.php?fid=\$2\$3 [QSA,L]\r\n"
				   . "RewriteRule ^(.*)-u-([0-9]+).html$ member.php?action=profile&uid=\$2 [QSA,L]\r\n"
				   . "RewriteRule ^members/(.*)-([0-9]+).html$ member.php?action=profile&uid=\$2 [QSA,L]\r\n"
				   . "RewriteRule ^(.*)/(.*)-f-([0-9]+).html(.*)$ forumdisplay.php?fid=\$2\$3 [QSA,L]\r\n"
				   . "RewriteRule ^(.*)-f-([0-9]+)-([0-9]+).html(.*)$ forumdisplay.php?fid=\$2&page=\$3 [QSA,L]\r\n"
				   . "RewriteRule ^(.*)-f-([0-9]+)-([a-z]+)(-|-[a-z]+)-([0-9]+)-([0-9]+).html(.*)$ forumdisplay.php?fid=\$2&sortby=\$3&order=\$4&datecut=\$5&page=\$6\$7 [L]\r\n"
				   . "RewriteRule ^(.*)-a-([0-9]+).html$ announcements.php?aid=\$2 [L]\r\n"
				   . "# //seo_mod_end\r\n";
	
	if (!file_exists('../.htaccess')) {
		@touch('../.htaccess');
	}
	
	if (is_writeable("../.htaccess")) 
	{
		$cur_htaccess = implode("", file("../.htaccess"));
		
		// part of all of it already exists?
		if (strstr($cur_htaccess, "//seo_mod_start")) {
			return;
		}
		
		// rewrite engine on?		
		$htaccess_code = str_replace("%extra_code%", (preg_match("#RewriteEngine.+?on#i", $cur_htaccess) ? "" : "RewriteEngine On\r\n"), $htaccess_code);
		
		$fp = fopen("../.htaccess", 'w');
		fwrite($fp, $cur_htaccess . $htaccess_code);
		fclose($fp);
		
		return;
	}

	// we're a bit screwed, the following message will exit he execution
	// so, Update plugin cache here
	global $message;

	$message = "<b>Copy/Paste the following code at end of a .htaccess file in your forum root directory:</b><br /><br />"
					. "<textarea cols='100' rows='10'>". str_replace("%extra_code%", "RewriteEngine On\r\n", $htaccess_code) ."</textarea>"
					. "";
}

function seo_deactivate()
{
	global $db;
	
	$query = $db->query("SELECT gid FROM ".TABLE_PREFIX."settinggroups WHERE name = 'spicefuse_seo'");
	$gid = $db->fetch_field($query, 'gid');

	if ($gid > 0) {
		$db->query("DELETE FROM ".TABLE_PREFIX."settinggroups WHERE name = 'spicefuse_seo'");
		$db->query("DELETE FROM ".TABLE_PREFIX."settings WHERE gid = {$gid}");
	}
	
	if (is_writeable("../.htaccess"))
	{
		// remove the seo plugin feed mod_rewrite stuff
		$htaccess_code = implode("", file("../.htaccess"));
		$code_start = substr($htaccess_code, 0, strpos($htaccess_code, "# //seo_mod_start"));
		$code_end = substr($htaccess_code, strpos($htaccess_code, "# //seo_mod_end") + strlen("# //seo_mod_end"));
		$merge_code = $code_start . $code_end;
		
		// prepend rewriteengine on if it only existed within the 
		// code that's stripped out..
		if (!preg_match("#RewriteEngine.+?on#i", $merge_code) && strlen($merge_code) > 15) {
			$merge_code = "RewriteEngine On\r\n\r\n" . $merge_code;
		}
		
		// write to htaccess
		$fp = fopen("../.htaccess", 'w');
		fwrite($fp, $merge_code);
		fclose($fp);
	}
}

function seo_init()
{
	global $mybb, $plugins;
	
	foreach ($mybb->settings as $key => $value) {
		if (strstr($key, 'sf_seo_')) {
			if ($value == 'yes') {
				$mybb->settings[$key] = 1;
			} else if ($value == 'no') {
				$mybb->settings[$key] = 0;
			}
		}
	}
	
	// settings	
	define("NOFOLLOW_UNF_LINKS", $mybb->settings['sf_seo_nofollow']);
	define("FORCE_REDIRECT", $mybb->settings['sf_seo_force_redirects']);

	define('SEO_DIRECTORY_TYPE', $mybb->settings['sf_seo_directory_type']);
	define('SEO_USERS_URLS', $mybb->settings['sf_seo_users_urls']);
	
	// ++
	define("FORCE_LOWERCASE", $mybb->settings['sf_seo_force_lowercase']);
	  define("CASE_COMPATABILITY", $mybb->settings['sf_seo_case_compatibility']);
	// --
	
	define('NO_KEYWORDS', ($mybb->settings['sf_seo_url_type'] == 2 ? 1 : 0));
	define("MAX_DESCRIPTION_LEN", (intval($mybb->settings['sf_seo_max_description']) == 0 ? 175 : $mybb->settings['sf_seo_max_description']));
	
	if ($mybb->settings['sf_seo_max_keywords_control'] == 1) 
	{
		// ++
		define("MAX_KEYWORDS", $mybb->settings['sf_seo_max_keywords']);
		 define("LEN_FOR_KEYWORD", (intval($mybb->settings['sf_seo_len_for_keyword']) == 0 ? 2 : $mybb->settings['sf_seo_len_for_keyword']));
		 define("STRIP_LESS_LEN", (intval($mybb->settings['sf_seo_strip_less_len']) == 0 ? 1 : $mybb->settings['sf_seo_strip_less_len']));
		 define("STRIP_COMMON_WORDS", $mybb->settings['sf_seo_strip_common_words']);
	}
	else
	{
		define("MAX_KEYWORDS", 0);
	}
	
	// force redirect?
	if (FORCE_REDIRECT == 1) {
		seo_change_request();
	}
}

/**
 * A kinda ugly function that I built for showthread.php
 * It redirects to the right URL if a topic is visited
 * directly somehow. 
 * 
 * Beta 5: 
 *  - Now that we have lowercase titles, force it!
 *  - Use 301/permanent redirects so that search engines
 *    give the page rank, even if showthread.php is used.
 * 
 * Excuse me if it doesnt makes much sense, just the 
 * result of some final touches to original work.
 * 
 * @access private
 */
function seo_change_request()
{
	global $db, $mybb, $session;
	
	$basename = basename(REQUEST_URI);
	$scriptname = basename($_SERVER['SCRIPT_NAME']);

	// if lowercase is being forced, and older compatability is needed, it should be applied directly
	if (($scriptname == 'forumdisplay.php' OR $scriptname == 'showthread.php') && FORCE_LOWERCASE == 1 && CASE_COMPATABILITY == 1 && preg_match('#[A-Z]#', $basename)) 
	{

		// decode query string into array
		$query_str = explode("&", $_SERVER['QUERY_STRING']);
		foreach ($query_str as $var) {
			$var = explode("=", $var);
			$query_vars[$var[0]] = $var[1];
		}
		
		// check if we can find the needed info
		if (preg_match("#(.+?)-(t|f)-([0-9]+)\.html#", $basename, $match)) {
			$title_url = seo_clean_title($match[1]);
			$type = $match[2];
		} else if (preg_match("#(.+?)-(t|f)-([0-9]+)-([0-9]+)\.html#", $basename, $match)) {
			$title_url = seo_clean_title($match[1]);
			$type = $match[2];
		} else {
			return;
		}

		// decode query string into array
		$query_str = explode("&", $_SERVER['QUERY_STRING']);
		foreach ($query_str as $var) {
			$var = explode("=", $var);
			$query_vars[$var[0]] = $var[1];
		}
		
		// cheat in, maybe set fid as tid ..
		if ($type == 't') {
			$query_vars['tid'] = intval($query_vars['tid']);
		} else if ($type == 'f') {
			$query_vars['tid'] = intval($query_vars['fid']);
		}
		
	
		ob_clean(); // flush current output..
		header("HTTP/1.1 301 Moved Permanently");
		header("Location: {$mybb->settings['bburl']}/{$title_url}-{$type}-{$query_vars['tid']}".(($query_vars['page'] != "" && $query_vars['page'] != 1) ? "-{$query_vars['page']}" : "") . ".html");
		exit();
	}
	
	// not a lot of use of it since Beta 5, easy on load here 
	if (substr($basename, 0, strpos($basename, '?')) == "showthread.php") 
	{
		$query_str = explode("&", $_SERVER['QUERY_STRING']);
		foreach ($query_str as $var) {
			$var = explode("=", $var);
			$query_vars[$var[0]] = $var[1];
		}
		
		$query_vars['tid'] = intval($query_vars['tid']);
		
		// we need at least topic or post id -- dont go looking for the last page here
		if (($query_vars['tid'] == "" && $query_vars['pid'] == "") OR $query_vars['page'] == 'last' OR $query_vars['mode'] != '') 
		{
			return;
		}
		
		// kill action variable for bots
		if ($query_vars['pid'] == "" && ($query_vars['action'] == "" OR $session->is_spider == true))
		{
			if (($title_url = seo_fetch_topic_title($query_vars['tid'])) != false) 
			{
				global $sp_fcache;

				$title_url = seo_parent_forum_url($query_vars['tid'], 't') . $title_url;
				
				ob_clean(); // flush current output..
				header("HTTP/1.1 301 Moved Permanently");
				header("Location: {$mybb->settings['bburl']}/{$title_url}-t-{$query_vars['tid']}".(($query_vars['page'] != "" && $query_vars['page'] != 1) ? "-{$query_vars['page']}" : "") . ".html" . $query_extra);
				exit();
			}
		}
		// handle pids
		else if ($query_vars['pid'] != "")
		{
			if (($fetch_data = seo_fetch_topic_title(0, $query_vars['pid'])) != false)  
			{
				if (!is_array($fetch_data)) {
					return;
				}
				
				$fetch_data['subject'] = seo_parent_forum_url($fetch_data['topic_id'], 't') . $fetch_data['subject'];
				
				ob_clean(); // flush current output..
				header("HTTP/1.1 301 Moved Permanently");
				header("Location: {$mybb->settings['bburl']}/{$fetch_data[subject]}-t-{$fetch_data['topic_id']}".(($fetch_data['page'] != "" && $fetch_data['page'] != 1) ? "-{$fetch_data['page']}" : "") . ".html#pid{$query_vars[pid]}");
				exit();
			}
		} // end pid
	}
	
	// temporary fix
	if ($mybb->input['order'] != "" && strstr($mybb->input['order'], '-')) {
		$mybb->input['order'] = str_replace('-', '', strtoupper($mybb->input['order']));
	}
}

/**
 * Main function that does all the replacement of links with 
 * the special keyword filled links. (usually based on titles/subjects) 
 * 
 * Currently replaces the following types of links:
 *  Forum display links (forumdisplay.php) - where required
 *  Threads links (showthread.php) - where required
 *  Announcement links (announcements.php) - on forum display
 *  Adds rel="nofollow" to many links which arent SE friendly
 * 
 * @access private
 */
function seo_change_links($page)
{
	global $data_cache, $fcache, $forum, $threadcache, $mybb, $db, $users_cache;

	/*$mtime1 = explode(" ", microtime());
	$start_time = $mtime1[1] + $mtime1[0];
	*/

	$mybb->settings['cur_file'] = basename($_SERVER['PHP_SELF']);

	// find all forum ids now
	preg_match_all("#forumdisplay.php\?fid=([0-9]+)#", $page, $forum_matches);
	for ($i = 0; $i < count($forum_matches[1]); $i++)
	{
		$data_cache['forums'][] = $forum_matches[1][$i];
	}
	
	//
	// Query topic titles of similar threads at thread view, for cache!
	// if this one extra query seems heavy to you, custom modification 
	// of the showthread.php is always possible..
	//
	// This is also used on search.php as of 1.1
	//
	if ($mybb->settings['showsimilarthreads'] != "no" && 
		(($mybb->settings['cur_file'] == "showthread.php" && $mybb->input['tid'] != "") OR
		 $mybb->settings['cur_file'] == "search.php")) 
	{
		// find all topic ids now
		preg_match_all("#showthread.php\?tid=([0-9]+)#", $page, $topic_matches);
		for ($i = 0; $i < count($topic_matches[1]); $i++)
		{
			if ($topic_matches[1][$i] == $mybb->input['tid']) {
				continue;
			}
			
			$data_cache['topics'][] = $topic_matches[1][$i];
		}

		if (is_array($data_cache['topics']))
		{
			$ids_str = implode(",", $data_cache['topics']);
			$query = $db->query("SELECT subject, tid, fid, replies FROM ".TABLE_PREFIX."threads WHERE tid IN({$ids_str})");
			while ($fetch = $db->fetch_array($query)) {
				$threadcache[$fetch['tid']] = array(
									'subject' => $fetch['subject'],
									'replies' => $fetch['replies'],
									'fid' => $fetch['fid'],
				);
			}
		}
	}
	
	// SEO users's urls?
	if (SEO_USERS_URLS)
	{
		// find all topic ids now
		preg_match_all("#member.php\?action=profile(&|&amp;)uid=([0-9]+)#", $page, $user_matches);
		for ($i = 0; $i < count($user_matches[2]); $i++)
		{
			$data_cache['users'][] = $user_matches[2][$i];
		}
		
		if (is_array($data_cache['users']))
		{
			$ids_str = implode(",", $data_cache['users']);
			$query = $db->query("SELECT uid, username FROM ".TABLE_PREFIX."users WHERE uid IN({$ids_str})");
			while ($fetch = $db->fetch_array($query)) {
				$users_cache[$fetch['uid']] = $fetch;
			}
		}
		
		$page = preg_replace("#(\"|')member.php\?action=profile(&|&amp;)uid=([0-9]+)(\"|')#ie", "seo_profile_url('\\3', '\\0', '\\1')", $page);
	}
	
	// prepare the url for use (mainly used in portal)
	$stripped_url = str_replace(array('http://', 'http://www.', '.'), array('', '', '\.'), $mybb->settings['bburl']);
	if (substr($stripped_url, -1) != '/') {
		$stripped_url .= '/';
	}
	
	// replace forum urls..
	//$page = preg_replace("#(\"|')forumdisplay.php\?fid=([0-9]+)&sortby=([a-z]+)(.*)order.*datecut.*page=([0-9]+).*(\"|')#ie", "seo_forum_url('\\2', 2, '\\0', array('\\6'))", $page);
	$page = preg_replace("#(\"|')forumdisplay.php\?fid=([0-9]+)(.+?)(\"|')#ie", "seo_forum_url('\\2', 3, '\\0', array('\\4'))", $page);
	$page = preg_replace("#(\"|')forumdisplay.php\?fid=([0-9]+)(\"|')#e", "seo_forum_url('\\2', 1, '\\0', array('\\3'))", $page);

	// replace topic urls
	$page = preg_replace("#href=(\"|')(|.+?{$stripped_url})showthread.php\?tid=([0-9]+)(\"|')#e", "seo_topic_url(\\3, 4, '\\0', '\\4')", $page);
	$page = preg_replace("#(\"|')showthread.php\?tid=([0-9]+)(&amp;|&)page=([0-9]+|last)(\"|')#e", "seo_topic_url(\\2, 2, '\\0', '\\5', \\4)", $page);
	
	// last post links
	if ($mybb->settings['cur_file'] == "index.php" || $mybb->settings['cur_file'] == "forumdisplay.php")
	{
		// find all last post tids and generate the cache
		$tids = array();
		preg_match_all("#(\"|')showthread.php\?(tid=([0-9]+)(&amp;|&)action=lastpost|action=lastpost(&amp;|&)tid=([0-9]+))(\"|')#", $page, $tid_matches);
		for ($i = 0; $i < count($tid_matches[2]); $i++) {
			if ($tid_matches[3][$i] == '') {
				$tid_matches[3][$i] = $tid_matches[6][$i];
			}
			$tids[] = $tid_matches[3][$i];
		}

		// if we have some topic ids to play with
		if (count($tids) > 0) 
		{
			$query = $db->query("SELECT tid, COUNT(pid) as total_posts, MAX(pid) as last_pid FROM ".TABLE_PREFIX."posts WHERE tid IN (".implode(',', $tids).") GROUP BY tid");
			$perpage = $mybb->settings['postsperpage'];
			while ($row = $db->fetch_array($query)) 
			{
				// on which page the post exists?
				$result = $row['total_posts'];
				if (($result % $perpage) == 0) {
					$page_no = $result / $perpage;
				} else {
					$page_no = intval($result / $perpage) + 1;
				}
				$data_cache['last_pids'][ $row['tid'] ] = array($row['last_pid'], $page_no);
			}
		}
		
		// takes care of both type of last post links
		$page = preg_replace("#(\"|')showthread.php\?(tid=([0-9]+)(&amp;|&)action=lastpost|action=lastpost(&amp;|&)tid=([0-9]+))(\"|')#e", "seo_last_post_url(array('\\3', '\\6'))", $page);
	}
	
	// After the above idea of removing all unfrinedly links didnt 
	// sound too good to me, I got another idea of adding a  
	// rel="nofollow" on the unfriendly links. Plus, the robots.txt 
	// file will be used for backward compatibility of search engines. 
	// What say? Suggestions at http://spicefuse.com
	if ($mybb->user['usergroup'] == 1 && NOFOLLOW_UNF_LINKS == 1)
	{
		$page = preg_replace("#(<a.+?href=.+?(search|stats|usercp2|printthread|sendthread|showteam|memberlist|calendar|member|online|private|newreply|newthread|showthread|forumdisplay)\.php)(.+?)>(.+?)</a>#e", "seo_add_nofollow('\\1', '\\3', '\\4')", $page);
	}
	
	// after adding the search engine no follow, now let's convert
	// few to SE friendly urls anyways (incase a user copies and pastes it somewhere)
	//   - showthread.php?tid=20&amp;pid=20#pid20
	$page = preg_replace("#(\"|')showthread.php\?tid=([0-9]+)(&amp;|&)pid=([0-9]+)(\#pid[0-9]+|)(\"|')#e", "seo_topic_url(\\2, 3, '\\0', '\\6', \\4, array('\\5'))", $page);
	
	// remove site name from page title and take care of announcements if we are at forum display
	if ($mybb->settings['cur_file'] == 'forumdisplay.php' && $mybb->input['fid'] != "")
	{
		$page = preg_replace("#<title>{$mybb->settings[bbname]}.+?-(.+?)</title>#e", "seo_page_title('\\1')", $page);
		
		global $announcements;
		if ($announcements != "")
		{
			$page = preg_replace("#(<a.+?href=.+?)announcements.php\?aid=([0-9]+)(.+?>)(.+?)</a>#e", "seo_announcement_url('\\2', '\\4', array('\\1', '\\3'))", $page);
		}
	}
	
	// at showthread.php, add dynamic description from first post
	if ($mybb->settings['cur_file'] == 'showthread.php' && MAX_DESCRIPTION_LEN > 0)
	{
		// get first post
		$query = $db->query("SELECT message FROM ".TABLE_PREFIX."posts WHERE tid = '{$mybb->input[tid]}' ORDER BY pid ASC LIMIT 1");
		$row = $db->fetch_array($query);
		
		if ($row['message'] != "") {
			$description = seo_clean_description($row['message']);
			$meta_tag = "\r\n" . '<meta name="description" content="'. $description .'" />' . "\r\n";
			$page = preg_replace('#<meta(.+?) />#', "\\0{$meta_tag}", $page);
		}
	}

	// replace showthread links one last time
	$page = preg_replace("#(\"|')showthread.php\?tid=([0-9]+)(\"|')#e", "seo_topic_url(\\2, 1, '\\0', '\\3')", $page);
	
	// no base tag but 
	if (SEO_DIRECTORY_TYPE && !stristr($page, '<base')) {
		$page = preg_replace('#<head>.*</title>#is', "\\0\r\n<base href='{$mybb->settings['bburl']}/' />", $page);
	}
	
	$find_html = '{$lang->copyright} &copy; 2002-{$copy_year} <strong><a href="http://www.mybboard.com" target="_blank">MyBB Group</a></strong>';
	$html_needed = '<br />Search Engine Optimization by <strong><a href="http://spicefuse.com" title="MyBB SEO, Server optimization, Linux help, PHP">SpiceFuse</a></strong>';
	/*if (!strstr($page, 'spicefuse.com') && $mybb->settings['cur_file'] == 'index.php') {
		die("Please add this line in your MyBB's footer template or deactivate the SEO plugin. Sorry, but even paid mods like vbSEO demand it, so I think it's fair enough to ask for a backlink when offering a nice plugin. <br /><br /><strong>Find in footer template:</strong> <br /><br />" 
				. htmlspecialchars($find_html) . "<br /><br /><strong>Add Below:</strong><br/><br/> " . htmlspecialchars($html_needed));
	}*/
	
	/*$mtime2 = explode(" ", microtime());
	$currenttime = $mtime2[1] + $mtime2[0];
	$totaltime = $currenttime - $start_time;
	echo "<br />SEO Plugin took: {$totaltime} seconds<br /><br />";*/
	return $page;
}

function seo_last_post_url($topic_id)
{
	global $last_post_cache, $threadcache, $data_cache, $fcache, $db, $mybb;

	if ($topic_id[0] == '') {
		$topic_id = $topic_id[1];
		$type = 2;
	} else {
		$topic_id = $topic_id[0];
	}
	
	// Forum Display last post link changes
	if ($type == 2) {
		if (is_array($threadcache[$topic_id])) 
		{
			$thread = $threadcache[$topic_id];
			$ext_data = $data_cache['last_pids'][$topic_id];
			
			// more than 1 page?
			if ($ext_data[1] > 1) {
				$the_url = seo_parent_forum_url($thread['fid'], 't') . seo_clean_title($thread['subject']) . "-t-{$topic_id}-" . $ext_data[1] . '.html#pid' . $ext_data[0];
			} else {
				$the_url = seo_parent_forum_url($thread['fid'], 't') . seo_clean_title($thread['subject']) . "-t-{$topic_id}.html#pid" . $ext_data[0];
			}
			
			return '"' . $the_url . '"';
		}
	}
	
	// build last post cache from the weird fcache array
	if (!is_array($last_post_cache)) {
		foreach ($fcache as $fid) 
		{
			foreach ($fid as $pid)
			{
				foreach ($pid as $forum) 
				{
					if ($forum['lastposttid'] > 0) 
					{
						$last_post_cache[$forum['lastposttid']] = array($forum['lastpostsubject'], $forum['fid'], $data_cache['last_pids'][$forum['lastposttid']][0], $data_cache['last_pids'][$forum['lastposttid']][1]);
					}
				}
			}
		}
	}
	
	// set the default one for now..
	$the_url = "showthread.php?tid={$topic_id}&action=lastpost";

	// do we have it in the list?
	if ($last_post_cache[$topic_id] != "") 
	{
		$the_page = $last_post_cache[$topic_id][3];
		if ($the_page > 1) {
			$page_no = "-{$the_page}";
		} else {
			$page_no = "";
		}
		
		$the_url = seo_parent_forum_url($last_post_cache[$topic_id][1], 't') . seo_clean_title($last_post_cache[$topic_id][0]) . "-t-{$topic_id}{$page_no}.html#pid" . $last_post_cache[$topic_id][2];
	}
	
	return '"' . $the_url . '"';
	
}

/**
 * Internal function to generate forums URLs
 * based on data provided.
 * 
 * @access private
 */
function seo_forum_url($forum_id, $type = 1, $current, $extra_data = array())
{
	global $forum_cache, $sp_fcache, $data_cache, $db;

	// try to build forumcache if we don't have it
	if (!is_array($forum_cache))
	{
		cache_forums();
		$forum_cache = array(); // prevent unexpected infinite loops
		seo_forum_url($forum_id, $type, $current, $extra_data);
	}
	
	// build our specially formatted sp_fcache array
	if (is_array($forum_cache) && !is_array($sp_fcache))
	{
		$sp_fcache = seo_build_fcache($forum_cache, 1);
	}
	
	// do we have the forum cache?
	if (is_array($sp_fcache))
	{
		if (is_array($sp_fcache[$forum_id])) {
			
			$title_url = seo_parent_forum_url($forum_id) . seo_clean_title($sp_fcache[$forum_id]['name'], 'f');
		}
	}
	else
	{
		if (!is_array($data_cache['forum_names'])) 
		{
			$data_cache['forum_names'] = array(); // prevent infinite loops
			
			$forum_ids = implode(",", $data_cache['forums']);
			$query = $db->query("SELECT f.fid, f.name FROM ".TABLE_PREFIX."forums f WHERE f.fid IN({$forum_ids})");
			while ($fetch = $db->fetch_array($query))
			{
				$data_cache['forum_names'][$fetch['fid']] = $fetch['name'];
			}
			
			seo_forum_url($forum_id, $type, $current, $extra_data);
		}
		else
		{
			if ($data_cache['forum_names'][$forum_id] != "") {
				$title_url = seo_clean_title($data_cache['forum_names'][$forum_id], 'f');
			}
		}
	}
	
	// return title_url if we have it
	if ($title_url != "") 
	{
		if ($type == 1) {
			return stripslashes($extra_data[0]) . $title_url . "-f-{$forum_id}.html" . stripslashes($extra_data[0]);
		}
		else if ($type == 2) 
		{
			// some dirty data fetching..
			preg_match("/(&amp;|&|)datecut=([0-9]+)(&amp;|&|$)/", $current, $match);
			$date_cut = $match[2];
			
			preg_match("/(&amp;|&|)order=([a-zA-Z]+)(&amp;|&|$)/", $current, $match);
			$order = $match[2];
			
			preg_match("/(&amp;|&|)sortby=([a-z]+)/", $current, $match);
			$sort_by = $match[2];
			
			preg_match("/(&amp;|&|)page=([0-9]+)/", $current, $match);
			$page = $match[2];
			
			return stripslashes($extra_data[0]) . $title_url . "-f-{$forum_id}-{$sort_by}-{$order}-{$date_cut}-{$page}.html" . stripslashes($extra_data[0]);
		}
		else if ($type == 3) 
		{
			$forum = &$sp_fcache[$forum_id];
			$def_sort_by = $forum['defaultsortby'] ? $forum['defaultsortby'] : "lastpost";
			$def_order = $forum['defaultsortorder'] ? $forum['defaultsortorder'] : "desc";
			$def_date_cut = $forum['defaultdatecut'] ? $forum['defaultdatecut'] : 9999;
		
			// some dirty data fetching..
			preg_match("/(&amp;|&|)datecut=([0-9]+)(&amp;|&|$)/", $current, $match);
			$date_cut = intval($match[2]) > 0 ? "-{$match[2]}" : "";
			
			preg_match("/(&amp;|&|)order=([a-zA-Z]+)(&amp;|&|$)/", $current, $match);
			$order = $match[2] ? "-{$match[2]}" : "";
			$order = strtolower($order);
			
			preg_match("/(&amp;|&|)sortby=([a-z]+)/", $current, $match);
			$sort_by = $match[2] ? "-{$match[2]}" : "";
			
			// fix for 1.2.7
			if ($sort_by == '') {
				$sort_by = '-' . $def_sort_by;
			}
			
			preg_match("/(&amp;|&|)page=([0-9]+)/", $current, $match);
			$page = intval($match[2]) > 0 ? "-{$match[2]}" : "-1";
			
			// required info not available?
			if (!$date_cut OR !$order OR !$sort_by OR !$page) {
				return stripslashes($current);
			}
			
			// if it's with default settings, don't clutter the url with un-necessary keywords
			if ($sort_by == '-'.$def_sort_by && $order == '-'.$def_order && $date_cut == '-'.$def_date_cut) 
			{
				if ($page == "-1") {
					$page = "";
				}
				
				return stripslashes($extra_data[0]) . $title_url . "-f-{$forum_id}{$page}.html" . stripslashes($extra_data[0]);
			}
			
			// or well, we have to add some extra info
			return stripslashes($extra_data[0]) . $title_url . "-f-{$forum_id}{$sort_by}{$order}{$date_cut}{$page}.html" . stripslashes($extra_data[0]);
		}
	}
	else
	{
		return stripslashes($current);
	}
}

function seo_profile_url($user_id, $original, $separator)
{
	global $users_cache;
	
	$separator = stripslashes($separator);
	if ($users_cache[$user_id]['username'] != '') {
		if (SEO_DIRECTORY_TYPE) {
			return $separator . 'members/' . seo_clean_title($users_cache[$user_id]['username'], 'u') . '-' . $user_id . '.html' . $separator;
		}
		
		return $separator . seo_clean_title($users_cache[$user_id]['username'], 'u') . '-u-' . $user_id . '.html' . $separator;
	}
	else {
		return $original;
	}
}

function seo_parent_forum_url($forum_id, $parent_type = 'f')
{	
	global $forum_cache, $sp_fcache, $data_cache, $db;

	// try to build forumcache if we don't have it
	if (!is_array($forum_cache))
	{
		$forum_cache = array(); // prevent unexpected infinite loops
		cache_forums();
		seo_parent_forum_url($forum_id, $parent_type);
	}
	
	// build our specially formatted sp_fcache array
	if (is_array($forum_cache) && !is_array($sp_fcache))
	{
		$sp_fcache = seo_build_fcache($forum_cache, 1);
	}
	
	$parent_forum = '';
	
	// directory type urls?
	if (SEO_DIRECTORY_TYPE) 
	{
		if ($parent_type == 'f' && strstr($sp_fcache[$forum_id]['parentlist'], ',')) 
		{
			$parents = explode(',', $sp_fcache[$forum_id]['parentlist']);
			$parent_forum = $sp_fcache[$parents[count($parents) - 2]]['name'];
		}
		else if ($parent_type == 't') {
			$parent_forum = $sp_fcache[$forum_id]['name'];
		}
		
		// append it now
		if ($parent_forum != '') {
			$parent_forum = seo_clean_title($parent_forum, 'f') . '/';
		}
	}

	return $parent_forum;
}

/**
 * Internal function to generate thread URLs
 * based on data provided.
 * 
 * @access private
 */
function seo_topic_url($topic_id, $type = 1, $current, $delimter = "", $page_no = 0, $extra_data = array())
{
	global $thread, $threadcache, $mybb;

	if ($threadcache[$topic_id]['subject'] != "") {
		$topic_url = seo_parent_forum_url($threadcache[$topic_id]['fid'], 't') . seo_clean_title($threadcache[$topic_id]['subject'], 't');
	}
	else if ($mybb->settings['cur_file'] == 'showthread.php' && $thread['subject'] != "")  {
		$topic_url = seo_parent_forum_url($thread['fid'], 't') . seo_clean_title($thread['subject'], 't');
	}
	else
	{
		return stripslashes($current);
	}

	// strip slashes on delimter	
	$delimter = stripslashes($delimter);
	
	// page number shouldn't be 1
	if ($type == 2 && $page_no == 1) {
		$type = 1;
	}


	if ($type == 1)	{
		$the_url = $topic_url . "-t-{$topic_id}.html" . $delimter;
	}
	else if ($type == 2) 
	{
		// if it's the last page, then get it's page number
		if ($page_no == "last") 
		{
			if (!$threadcache[$topic_id]['replies']) {
				return $delimter . $topic_url . "-t-{$topic_id}.html" . $delimter;
			}
			
			$replies = $threadcache[$topic_id]['replies'] + 1;
			$last_page = ceil($replies / $mybb->settings['postsperpage']);
			$page_no = $last_page;
			
		}
		
		$the_url = $topic_url . "-t-{$topic_id}-{$page_no}.html" . $delimter;
	}
	else if ($type == 3 OR $type == 4) 
	{
		// we do not need to add it to page number if it's page 1
		if ($mybb->input['tid'] != $topic_id OR $mybb->input['page'] == "" OR $mybb->input['page'] == 1) {
			$page_no = "";
		} else {
			$page_no = "-{$mybb->input[page]}";
		}
		
		$the_url = $topic_url . "-t-{$topic_id}{$page_no}.html" . stripslashes($extra_data[0]) . $delimter;
	}
	
	return ($type == 4 ? 'href=' : "") . $delimter . $the_url;
}

/**
 * Internal function to generate announcement URLs
 * based on data provided.
 * 
 * @access private
 */
function seo_announcement_url($announce_id, $announce_title, $extra_data = array())
{
	$announcement_url = seo_clean_title($announce_title, 'a') . "-a-{$announce_id}.html";
	return stripslashes($extra_data[0]). $announcement_url . stripslashes($extra_data[1]) . stripslashes($announce_title) ."</a>";
}

/**
 * Internal function to re-generate page title!
 * 
 * @access private
 */
function seo_page_title($page_title)
{
	return "<title>". trim($page_title) ."</title>";
}

/**
 * Adds rel="nofollow" in the data provided by matches 
 * in parts.
 * 
 * @access private
 */
function seo_add_nofollow($part_1, $part_2, $part_3)
{
	return stripslashes($part_1) . stripslashes($part_2) . ' rel="follow">'. stripslashes($part_3) .'</a>';
}

/**
 * Mainly used for fetching the topic title when an id 
 * is given, but also used for getting the topic title 
 * and page number when a pid is given. 
 * 
 * Note: Return topic title is suitable only for links.
 * 
 * @access public
 */
function seo_fetch_topic_title($topic_id = 0, $pid = 0)
{
	global $db, $mybb, $ismod;
	
	if (!($topic_id XOR $pid)) {
		return false;
	}
	
	// we have a pid?
	// calculate the page and fetch the title
	$pid = intval($pid);
	if ($pid != 0) 
	{
		// get topic id and subject..
		$query = $db->query("SELECT t.tid, t.subject FROM ".TABLE_PREFIX."posts p 
								LEFT JOIN ".TABLE_PREFIX."threads t ON(p.tid = t.tid) WHERE p.pid = {$pid}");
		$fetch = $db->fetch_array($query);
		
		if (!($topic_id = $fetch['tid']) OR !$fetch['subject']) {
			return false;
		}

		// taken from showthread.php -- this part of code in
		// showthread.php will become useless!
		
		// Work out if we're showing both approved and unapproved threads or just approved..
		if($ismod)
		{
			$visible = "AND (visible='0' OR visible='1')";
		}
		else
		{
			$visible = "AND visible='1'";
		}
	
		$perpage = $mybb->settings['postsperpage'];
		$query = $db->query("SELECT COUNT(pid) as c_pid FROM ".TABLE_PREFIX."posts WHERE tid='$topic_id' AND pid <= '{$pid}' $visible");
		$result = $db->fetch_field($query, 'c_pid');
		if (($result % $perpage) == 0) {
			$page = $result / $perpage;
		} else {
			$page = intval($result / $perpage) + 1;
		}
			
		// return an array with topic subject and page number
		return array('subject' => seo_clean_title($fetch['subject']), 'topic_id' => $topic_id, 'page' => $page);
			
	}
	else
	{
		$query = $db->query("SELECT subject FROM ".TABLE_PREFIX."threads WHERE tid = '{$topic_id}'");
		$fetch = $db->fetch_array($query);
				
		if ($fetch['subject'] == "") {
			return false;
		}

		$title_url = seo_clean_title($fetch['subject']);
		return $title_url;
	}
}

/**
 * Generate special type of forum cache which is rather
 * easier to use and understand. 
 * 
 * @access public
 */
// is RSS plugin also used? (the function might be created)
if (!function_exists("seo_build_fcache"))
{
	function seo_build_fcache($forumcache, $full_info = 0)
	{
		@reset($forumcache);
		while (list($key,$val) = @each($forumcache))
		{
			if ($full_info == 1) {
				$sp_fcache[$val['fid']] = $val;
			} else {
				$sp_fcache[$val['fid']]['name'] = $val['name'];
			}
		}
	
		return $sp_fcache;
	}
}

function seo_clean_description($message)
{
	global $cache;
	
	// first remove html if any
	$message = strip_tags($message);
	
	// remove tags.. rather dirty
	// -- 0, 1 defines if it's a multi-line code
	$tags_array = array('size' => 0, 'b' => 0, 'i' => 0, 'u' => 0, 'url' => 0, 'img' => 0, 
						'quote' => 1, 'php' => 1, 'code' => 1, 'hide' => 1);
						
	foreach ($tags_array as $tag => $multi_line) {
		$message = preg_replace("#\[({$tag}|{$tag}=.+?)\](.+?)\[/{$tag}\]#i" . ($multi_line == 1 ? 's' : ''), "\\2", $message);
	}
	
	// remote custom tags
	$custom_mycode = $cache->read("mycode");
	if (is_array($custom_mycode)) {
		foreach ($custom_mycode as $key => $mycode) 
		{
			$message = preg_replace("#".$mycode['regex']."#si", '', $message);
		}
	}
	
	// remove smilies
	$smilies = $cache->read("smilies");
	if (is_array($smilies)) {
		foreach($smilies as $sid => $smilie)
		{
			$message = str_replace($smilie['find'], '', $message);
		}
	}
	
	// remove more un-needed data here
	// -- we can decode html entities if we have PHP 5
	if (version_compare(PHP_VERSION, '5.1.0', '>=')) {
		$message = html_entity_decode($message, ENT_QUOTES, 'UTF-8');
	} else {
		$message = preg_replace("/&([a-z]+);/", "", $message);
	}
	
	$message = str_replace("\r", "", $message);
	$message = str_replace("\n", " ", $message);
	$message = str_replace(array('"', "[", "]", "<", ">", "\\", "/", "=", "+"), "", $message);
	$message = preg_replace("#\s{2,}#", " ", $message);
	
	// there has to be a limit to the description
	if (($msg_len = strlen($message)) > MAX_DESCRIPTION_LEN) {

		// try stripping on a space somewhere near the limit
		$substr_begin = substr($message, 0, MAX_DESCRIPTION_LEN+5);
		$substr = substr($message, 0, strrpos($substr_begin, ' '));

		// caused a change more than 20%, that isn't acceptable!
		if (((MAX_DESCRIPTION_LEN+5) - strlen($substr)) > (0.20*MAX_DESCRIPTION_LEN)) {
			$message = substr($message, 0, MAX_DESCRIPTION_LEN) . "...";
		} else {
			$message = $substr . "...";
		}
	}
				
	return $message;
}

/**
 * Clean the title strings to be used as file names in 
 * links, where required. 
 * 
 * @access private
 */
function seo_clean_title($title, $title_type = 't')
{
	global $lang;

	// maybe we don't need keywords at all!	
	if (NO_KEYWORDS == 1) {
		switch ($title_type) {
			case 't':
				$title = 'thread';
				break;

			case 'f':
				$title = 'forum';
				break;

			case 'a':
				$title = 'announcement';
				break;
				
			case 'u':
				$title = 'user';
				break;
		}
		return $title;
	}
	
	// do the replacements and return encoded url
	$title = str_replace("&amp;", "&", $title);
	$title = preg_replace("/&([a-z]+);/", "", $title); // remove html entities such as &amp; &quot etc..
	$title = preg_replace("/&#([0-9]+);/", "", $title); // remove entities like !
	
	// added in BETA 9, to fix issues with some latin characters
	if (stristr($lang->settings['charset'], 'iso')) {
		$title = utf8_encode($title);
		$is_utf8 = 1;
	}
	
	$title = utf8_trans_unaccent($title);
	
	// translate accents -- and maybe remove few non-ascii characters too, while on it..
	$title = preg_replace('#&([a-zA-Z])(circ|uml|grave|tilde|acute|cedil|ring|th);#', '\\1', htmlentities($title, null, 'utf-8'));
	$title = preg_replace("/&([a-z]+);/", "", $title);
	
	if ($is_utf8 == 1) {
		$title = utf8_decode($title);
	}
	
	// might be something like jackal's, we don't want it to be jackal-s
	$title = str_replace("'", '', $title);
	
	$title = str_replace(
			array(":", "?", ".", "!", "$", "^", "*", ",", ";", '"', "%", "~", "@", "#", "[", "]", "<", ">", "\\", "/", "=", "+", "(", ")"), 
						"-", $title);
	
	$title = str_replace(array('_', " ", "&"), array("-", "-", "and"), $title);
	
	// remove multiple separators
	$title = preg_replace("#-{2,}#", "-", $title);

	// remove ending - if needed
	if (substr($title, -1) == '-') {
		$title = substr($title, 0, -1);
	}	

	// convert to lowercase?
	if (FORCE_LOWERCASE == 1) {
		$title = strtolower($title);
	}
	
	// limit number of keywords in the url?
	if (MAX_KEYWORDS > 0) 
	{
		$words = explode("-", $title);
		
		// if we have more words than allowed..
		if (count($words) > MAX_KEYWORDS)
		{
			// common words, which can be stripped out if enabled
			$common_words = array('is', 'you', 'are', 'in', 'at', 'the', 'and', 'to', 'of', 'or', 'from', 'when', 'where', 'be', 'you');
			
			$i = 0;
			foreach ($words as $word) 
			{
				if ($i >= MAX_KEYWORDS) {
					break;
				}
			
				$length = strlen($word);

				// strip the keyword, if it has less length than defined, or if it's a common word -- if enabled!
				if ( ($length < LEN_FOR_KEYWORD && STRIP_LESS_LEN == 1) OR (STRIP_COMMON_WORDS == 1 && in_array($word, $common_words)) ) {
					continue;
				}
					
				// it has the number of characters to be counted as a keyword?
				if (LEN_FOR_KEYWORD == 0 OR $length >= LEN_FOR_KEYWORD) {
					$i++;
				}
			
				$new_title[] = $word;
			}
		
			// in some cases, due to less intelligence of the automatic keyword stripper there 
			// might be no keywords left to show, in that case, just display the original!
			if (count($new_title) > 0) {
				$title = implode("-", $new_title);
			}
		}
	}
	
	return rawurlencode($title);
}

/**
 * Converts some latin-1, and latin-2 accented characters to 7-bit equivalents
 * From: http://stuffofinterest.com/misc/utf8-about.html
 *
 */
// Translate accented utf8 characters over to non-accented
function utf8_trans_unaccent($instr) 
{
   $tranmap = array(
      "\xC3\x80" => "A",   "\xC3\x81" => "A",   "\xC3\x82" => "A",   "\xC3\x83" => "A",
      "\xC3\x84" => "A",   "\xC3\x85" => "A",   "\xC3\x86" => "AE",  "\xC3\x87" => "C",
      "\xC3\x88" => "E",   "\xC3\x89" => "E",   "\xC3\x8A" => "E",   "\xC3\x8B" => "E",
      "\xC3\x8C" => "I",   "\xC3\x8D" => "I",   "\xC3\x8E" => "I",   "\xC3\x8F" => "I",
      "\xC3\x90" => "D",   "\xC3\x91" => "N",   "\xC3\x92" => "O",   "\xC3\x93" => "O",
      "\xC3\x94" => "O",   "\xC3\x95" => "O",   "\xC3\x96" => "O",   "\xC3\x98" => "O",
      "\xC3\x99" => "U",   "\xC3\x9A" => "U",   "\xC3\x9B" => "U",   "\xC3\x9C" => "U",
      "\xC3\x9D" => "Y",   "\xC3\x9E" => "P",   "\xC3\x9F" => "ss",
      "\xC3\xA0" => "a",   "\xC3\xA1" => "a",   "\xC3\xA2" => "a",   "\xC3\xA3" => "a",
      "\xC3\xA4" => "a",   "\xC3\xA5" => "a",   "\xC3\xA6" => "ae",  "\xC3\xA7" => "c",
      "\xC3\xA8" => "e",   "\xC3\xA9" => "e",   "\xC3\xAA" => "e",   "\xC3\xAB" => "e",
      "\xC3\xAC" => "i",   "\xC3\xAD" => "i",   "\xC3\xAE" => "i",   "\xC3\xAF" => "i",
      "\xC3\xB0" => "o",   "\xC3\xB1" => "n",   "\xC3\xB2" => "o",   "\xC3\xB3" => "o",
      "\xC3\xB4" => "o",   "\xC3\xB5" => "o",   "\xC3\xB6" => "o",   "\xC3\xB8" => "o",
      "\xC3\xB9" => "u",   "\xC3\xBA" => "u",   "\xC3\xBB" => "u",   "\xC3\xBC" => "u",
      "\xC3\xBD" => "y",   "\xC3\xBE" => "p",   "\xC3\xBF" => "y",
      "\xC4\x80" => "A",   "\xC4\x81" => "a",   "\xC4\x82" => "A",   "\xC4\x83" => "a",
      "\xC4\x84" => "A",   "\xC4\x85" => "a",   "\xC4\x86" => "C",   "\xC4\x87" => "c",
      "\xC4\x88" => "C",   "\xC4\x89" => "c",   "\xC4\x8A" => "C",   "\xC4\x8B" => "c",
      "\xC4\x8C" => "C",   "\xC4\x8D" => "c",   "\xC4\x8E" => "D",   "\xC4\x8F" => "d",
      "\xC4\x90" => "D",   "\xC4\x91" => "d",   "\xC4\x92" => "E",   "\xC4\x93" => "e",
      "\xC4\x94" => "E",   "\xC4\x95" => "e",   "\xC4\x96" => "E",   "\xC4\x97" => "e",
      "\xC4\x98" => "E",   "\xC4\x99" => "e",   "\xC4\x9A" => "E",   "\xC4\x9B" => "e",
      "\xC4\x9C" => "G",   "\xC4\x9D" => "g",   "\xC4\x9E" => "G",   "\xC4\x9F" => "g",
      "\xC4\xA0" => "G",   "\xC4\xA1" => "g",   "\xC4\xA2" => "G",   "\xC4\xA3" => "g",
      "\xC4\xA4" => "H",   "\xC4\xA5" => "h",   "\xC4\xA6" => "H",   "\xC4\xA7" => "h",
      "\xC4\xA8" => "I",   "\xC4\xA9" => "i",   "\xC4\xAA" => "I",   "\xC4\xAB" => "i",
      "\xC4\xAC" => "I",   "\xC4\xAD" => "i",   "\xC4\xAE" => "I",   "\xC4\xAF" => "i",
      "\xC4\xB0" => "I",   "\xC4\xB1" => "i",   "\xC4\xB2" => "IJ",  "\xC4\xB3" => "ij",
      "\xC4\xB4" => "J",   "\xC4\xB5" => "j",   "\xC4\xB6" => "K",   "\xC4\xB7" => "k",
      "\xC4\xB8" => "k",   "\xC4\xB9" => "L",   "\xC4\xBA" => "l",   "\xC4\xBB" => "L",
      "\xC4\xBC" => "l",   "\xC4\xBD" => "L",   "\xC4\xBE" => "l",   "\xC4\xBF" => "L",
      "\xC5\x80" => "l",   "\xC5\x81" => "L",   "\xC5\x82" => "l",   "\xC5\x83" => "N",
      "\xC5\x84" => "n",   "\xC5\x85" => "N",   "\xC5\x86" => "n",   "\xC5\x87" => "N",
      "\xC5\x88" => "n",   "\xC5\x89" => "n",   "\xC5\x8A" => "N",   "\xC5\x8B" => "n",
      "\xC5\x8C" => "O",   "\xC5\x8D" => "o",   "\xC5\x8E" => "O",   "\xC5\x8F" => "o",
      "\xC5\x90" => "O",   "\xC5\x91" => "o",   "\xC5\x92" => "CE",  "\xC5\x93" => "ce",
      "\xC5\x94" => "R",   "\xC5\x95" => "r",   "\xC5\x96" => "R",   "\xC5\x97" => "r",
      "\xC5\x98" => "R",   "\xC5\x99" => "r",   "\xC5\x9A" => "S",   "\xC5\x9B" => "s",
      "\xC5\x9C" => "S",   "\xC5\x9D" => "s",   "\xC5\x9E" => "S",   "\xC5\x9F" => "s",
      "\xC5\xA0" => "S",   "\xC5\xA1" => "s",   "\xC5\xA2" => "T",   "\xC5\xA3" => "t",
      "\xC5\xA4" => "T",   "\xC5\xA5" => "t",   "\xC5\xA6" => "T",   "\xC5\xA7" => "t",
      "\xC5\xA8" => "U",   "\xC5\xA9" => "u",   "\xC5\xAA" => "U",   "\xC5\xAB" => "u",
      "\xC5\xAC" => "U",   "\xC5\xAD" => "u",   "\xC5\xAE" => "U",   "\xC5\xAF" => "u",
      "\xC5\xB0" => "U",   "\xC5\xB1" => "u",   "\xC5\xB2" => "U",   "\xC5\xB3" => "u",
      "\xC5\xB4" => "W",   "\xC5\xB5" => "w",   "\xC5\xB6" => "Y",   "\xC5\xB7" => "y",
      "\xC5\xB8" => "Y",   "\xC5\xB9" => "Z",   "\xC5\xBA" => "z",   "\xC5\xBB" => "Z",
      "\xC5\xBC" => "z",   "\xC5\xBD" => "Z",   "\xC5\xBE" => "z",   "\xC6\x8F" => "E",
      "\xC6\xA0" => "O",   "\xC6\xA1" => "o",   "\xC6\xAF" => "U",   "\xC6\xB0" => "u",
      "\xC7\x8D" => "A",   "\xC7\x8E" => "a",   "\xC7\x8F" => "I",
      "\xC7\x90" => "i",   "\xC7\x91" => "O",   "\xC7\x92" => "o",   "\xC7\x93" => "U",
      "\xC7\x94" => "u",   "\xC7\x95" => "U",   "\xC7\x96" => "u",   "\xC7\x97" => "U",
      "\xC7\x98" => "u",   "\xC7\x99" => "U",   "\xC7\x9A" => "u",   "\xC7\x9B" => "U",
      "\xC7\x9C" => "u",
      "\xC7\xBA" => "A",   "\xC7\xBB" => "a",   "\xC7\xBC" => "AE",  "\xC7\xBD" => "ae",
      "\xC7\xBE" => "O",   "\xC7\xBF" => "o",
      "\xC9\x99" => "e",

      "\xC2\x82" => ",",        // High code comma
      "\xC2\x84" => ",,",       // High code double comma
      "\xC2\x85" => "...",      // Tripple dot
      "\xC2\x88" => "^",        // High carat
      "\xC2\x91" => "\x27",     // Forward single quote
      "\xC2\x92" => "\x27",     // Reverse single quote
      "\xC2\x93" => "\x22",     // Forward double quote
      "\xC2\x94" => "\x22",     // Reverse double quote
      "\xC2\x96" => "-",        // High hyphen
      "\xC2\x97" => "--",       // Double hyphen
      "\xC2\xA6" => "|",        // Split vertical bar
      "\xC2\xAB" => "<<",       // Double less than
      "\xC2\xBB" => ">>",       // Double greater than
      "\xC2\xBC" => "1/4",      // one quarter
      "\xC2\xBD" => "1/2",      // one half
      "\xC2\xBE" => "3/4",      // three quarters

      "\xCA\xBF" => "\x27",     // c-single quote
      "\xCC\xA8" => "",         // modifier - under curve
      "\xCC\xB1" => ""          // modifier - under line
   );

   return strtr($instr, $tranmap);
}

?>

bump Toungue
bump?
bump#2
get_thread_link will return the MyBB friendly URL, if friendly URLs are not disabled and your server can handle them. Make sure this is turned on in the settings.
Yes it is. I have got seo links like
http://www.site.eu/lalala-pl-t-9624.html#pid76884 ,

But I have got no httaccess file (I'm not apache Toungue )