<?php

// KNOWN ISSUE: won't work on all setups (based on PHP version) with some AJAX features


// comment out this line if you want to save a (possible) query being run at the end of the page
//  This will disable the retrieval of post times and profile links.
define('VBQUOTE_USE_COMPLEX_QUOTES', 1);

if(!defined("IN_MYBB"))
	die("This file cannot be accessed directly.");

$plugins->add_hook('newreply_end', 'vbquote_newreply');
$plugins->add_hook('xmlhttp', 'vbquote_xmlhttp');
$plugins->add_hook('parse_message', 'vbquote_parse');
$plugins->add_hook('text_parse_message', 'vbquote_parse_text');

function vbquote_info()
{
	return array(
		'name'			=> 'vB Style Quotes',
		'description'	=> 'Causes quotes to use the simpler vB style syntax, eg, [quote=USERNAME;PID].',
		'website'		=> 'http://mybbhacks.zingaburga.com/',
		'author'		=> 'ZiNgA BuRgA',
		'authorsite'	=> 'http://zingaburga.com/',
		'version'		=> '1.1',
		'compatibility'	=> '14*',
		'guid'			=> ''
	);
}


function vbquote_newreply()
{
	global $mybb, $quoted_posts, $message;
	if(count($quoted_posts) < 1) return;
	
	// if we have quoted posts, then we'll have to reconstruct the message
	vbquote_convert_quotes($message);
}

function vbquote_xmlhttp()
{
	if(!defined('IN_XMLHTTP'))
		define('IN_XMLHTTP', 1);
	
	global $mybb;
	if($mybb->input['action'] != 'get_multiquoted') return;
	ob_start();
	
	function vbquote_xmlhttp_parse()
	{
		global $message;
		if(!$message)
		{
			ob_end_flush();
			return;
		}
		
		ob_end_clean();
		vbquote_convert_quotes($message);
		echo $message;
	}
	register_shutdown_function('vbquote_xmlhttp_parse');
}


function vbquote_parse(&$message, $text_only=false)
{
	// TODO: push regex into parser cache
	global $parser, $lang;
	if(is_object($parser))
	{
		// check if MyCode is being parsed
		if($parser->options['allow_mycode'] == 0)
			return;
	}
	
	// parse our quotes
	//$pattern = '#\[quote=(&quot;|["\'])?(.*?);([0-9]+)\\1\](.*?)\[\/quote\](\r\n?|\n?)#si';
	
	if($text_only) // a little dodgey, but, well...
		$pattern = "#(\n)([^<\n]*?);([0-9]+) ".preg_quote($lang->wrote,'#')."(\n--\n)#s";
	else
		$pattern = '#(\<cite\>)([^<]*?);([0-9]+) '.preg_quote($lang->wrote,'#').'(\</cite\>)#s'; // no case insenstive flag cause I feel like it
	
	// can we do much for text-only parsing???
	do {
		$message = preg_replace($pattern.'e', '\'$1\'.vbquote_parse_quote(str_replace(\'\\"\', \'"\', \'$2\'), \'$3\', '.($text_only?'true':'false').').\'$4\'', $message);
	} while(preg_match($pattern, $message));
	
	return $message;
}

function vbquote_parse_text(&$msg) { return vbquote_parse($msg, true); }


function vbquote_parse_quote($user, $pid, $text_only=false)
{
	global $lang, $templates, $mybb, $theme;
	
	// if we're processing complex quotes
	if(defined('VBQUOTE_USE_COMPLEX_QUOTES') && !$text_only && !defined('IN_ARCHIVE'))
	{
		global $vbquote_quotedpids, $plugins;
		$vbquote_quotedpids[$pid] = $user;
		
		$plugins->add_hook('pre_output_page', 'vbquote_parse_complex');
		if(defined('IN_XMLHTTP') || $mybb->input['ajax']==1)
		{
			static $ajax_done;
			if(!$ajax_done)
			{
				ob_start();
				function vbquote_xmlhttp_preoutput()
				{
					run_shutdown();	// reconstruct objects if destroyed (urgh, won't fix $lang, $templates and $theme)
					$page = ob_get_clean();
					echo vbquote_parse_complex($page);
				}
				register_shutdown_function('vbquote_xmlhttp_preoutput');
				$ajax_done = true;
			}
		}
		
		return '<!-- VBQUOTE_COMPLEX_QUOTE_'.$pid.' -->';
	}
	
	return vbquote_parse_quote_user($user, $pid, $text_only);
}

function vbquote_parse_quote_user($user, $pid, $text_only=false)
{
	global $lang, $templates, $mybb, $theme;
	if($text_only)
		return $user.' '.$lang->wrote;
	
	$url = $mybb->settings['bburl'].'/'.get_post_link($pid).'#pid'.$pid;
	if(defined('IN_ARCHIVE'))
		$linkback = ' <a href="'.$url.'">[ -> ]</a>';
	else
		eval('$linkback = " '.$templates->get('postbit_gotopost', 1, 0).'";');
	
	//return "<p>\n<blockquote><cite>".htmlspecialchars_uni($user)." $lang->wrote{$linkback}</cite>{$msg}</blockquote></p>\n";
	return $user.' '.$lang->wrote.$linkback;
}



function vbquote_parse_complex(&$page)
{
	global $vbquote_quotedpids;
	if(empty($vbquote_quotedpids)) return $page;
	static $done;
	if($done) return $page;
	$done = true;
	
	global $db, $lang, $mybb, $templates, $theme;
	$posts = array();
	$query = $db->query('SELECT p.pid,u.uid,p.dateline,u.username,u.usergroup,u.displaygroup FROM '.TABLE_PREFIX.'posts p LEFT JOIN '.TABLE_PREFIX.'users u ON p.uid=u.uid WHERE p.pid IN ('.implode(',',array_keys($vbquote_quotedpids)).')');
	while($post = $db->fetch_array($query))
		$posts[$post['pid']] = $post;
	
	$replaces = array();
	foreach($vbquote_quotedpids as $pid => $uname)
	{
		$post = &$posts[$pid];
		// posts doesn't exist anymore...?
		if(!$post)
		{
			$r = vbquote_parse_quote_user(htmlspecialchars_uni($uname), $pid);
		}
		else
		{
			$url = $mybb->settings['bburl'].'/'.get_post_link($pid).'#pid'.$pid;
			eval('$linkback = " '.$templates->get('postbit_gotopost', 1, 0).'";');
			
			$date = my_date($mybb->settings['dateformat'], $post['dateline']).' '.my_date($mybb->settings['timeformat'], $post['dateline']);
			
			$r = '<span style="float: right; font-weight: normal;"> ('.$date.')</span>'
				.build_profile_link(format_name($post['username'], $post['usergroup'], $post['displaygroup']), $post['uid']).' '.$lang->wrote.$linkback;
		}
		$replaces['<!-- VBQUOTE_COMPLEX_QUOTE_'.$pid.' -->'] = $r;
	}
	
	return strtr($page, $replaces);
}


//  * has issues if quoted message already contains old MyBB 1.4 style quotes
function vbquote_convert_quotes(&$message)
{
	$pattern = '#\[quote=(["\'])?([^"]*?)\\1 (?:[^[\]]*?)?pid=(["\'])?([0-9]+)\\3(?:[^\]].*?)?\](.*?)\[/quote\]#sie';
	while($message != ($new_message = preg_replace($pattern, '\'[quote=\'.strtr(\'$2\', array(\'[\'=> \'(\', \']\'=>\')\')).\';$4]\'.str_replace(\'\\"\', \'"\', \'$5\').\'[/quote]\'', $message)))
		$message = $new_message;
}


?>