Guest posting doesnt work?

Get help with installation and running phpBB 3.0.x here. Please do not post bug reports, feature requests, or MOD-related questions here.
Get Involved
Forum rules
END OF SUPPORT: 1 January 2017 (announcement)
AbbeyG
Registered User
Posts: 88
Joined: Fri Feb 08, 2013 7:14 pm

Guest posting doesnt work?

Post by AbbeyG »

I am not sure why, but in my forum, I have one forum that is ear marked for guests. While I was looking to make sure that every thing is fine (the board hasnt opened, so there is a lot of testing going on :D). I found out that guest posting doesnt work. When ever I try to post as a guest, it shows a blank white screen in Mozilla and a 'Server Not found' error in Chrome.

I am sure it isnt related to server because I can post just fine in my admin account as well as on the test account. Here is my forum: http://theriddlediary.empirehostings.ne ... /index.php

'Your first forum' is the guest friendly forum.

This is what Chrome returns
Server error
The website encountered an error while retrieving http://theriddlediary.empirehostings.ne ... e=post&f=2. It may be down for maintenance or configured incorrectly.
Here are some suggestions:
Reload this webpage later.
HTTP Error 500 (Internal Server Error): An unexpected condition was encountered while the server was attempting to fulfill the request.
AbbeyG
Registered User
Posts: 88
Joined: Fri Feb 08, 2013 7:14 pm

Re: Guest posting doesnt work?

Post by AbbeyG »

I checked on a test board on a local host which uses the same files as I do on my forum and here is the error I get:

Fatal error: Cannot redeclare user_get_id_name() (previously declared in E:\theriddlediary\xampp\htdocs\phpBB3\includes\functions_user.php:27) in E:\theriddlediary\xampp\htdocs\phpBB3\includes\functions_user.php on line 82
User avatar
Oyabun1
Former Team Member
Posts: 23162
Joined: Sun May 17, 2009 1:05 pm
Location: Australia
Name: Bill

Re: Guest posting doesnt work?

Post by Oyabun1 »

Please fill out the Support Request Template Generator and post it back here to enable us to assist you better.
                      Support Request Template
3.0.x: Knowledge Base Styles Support MOD Requests
3.1.x: Knowledge BaseStyles SupportExtension Requests
AbbeyG
Registered User
Posts: 88
Joined: Fri Feb 08, 2013 7:14 pm

Re: Guest posting doesnt work?

Post by AbbeyG »

I am terribly sorry that I missed it :(

Support Request Template
What version of phpBB are you using? phpBB 3.0.11
What is your board's URL? http://theriddlediary.empirehostings.net/phpBB33
Who do you host your board with? Empire Hostings
How did you install your board? I used the download package from phpBB.com
What is the most recent action performed on your board? Fresh Install
Is registration required to reproduce this issue? No
Do you have any MODs installed? Yes
What MODs do you have installed? I have quite a few mods installed, but I think I will add the mods that i think are relevant to the issue :D

1. Link Accounts - Helps a user to link their multiple accounts on the board

While this concerns only registered members, I just thought I would mention. Before you ask, the installation was successful.
What styles do you currently have installed? Prosilver modifed
What language(s) is your board currently using? English
Which database type/version are you using? MySQL 5
What is your level of experience? New to PHP but not phpBB
When did your problem begin? I am not sure why, but in my forum, I have one forum that is ear marked for guests. While I was looking to make sure that every thing is fine (the board hasnt opened, so there is a lot of testing going on ). I found out that guest posting doesnt work. When ever I try to post as a guest, it shows a blank white screen in Mozilla and a 'Server Not found' error in Chrome.
Please describe your problem. 'Your first forum' is the guest friendly forum.

This is what Chrome returns
Server error
The website encountered an error while retrieving http://theriddlediary.empirehostings.ne ... e=post&f=2. It may be down for maintenance or configured incorrectly.
Here are some suggestions:
Reload this webpage later.
HTTP Error 500 (Internal Server Error): An unexpected condition was encountered while the server was attempting to fulfill the request.
I checked on a test board on a local host which uses the same files as I do on my forum and here is the error I get:
Fatal error: Cannot redeclare user_get_id_name() (previously declared in E:\theriddlediary\xampp\htdocs\phpBB3\includes\functions_user.php:27) in E:\theriddlediary\xampp\htdocs\phpBB3\includes\functions_user.php on line 82
Generated by SRT Generator
User avatar
Oyabun1
Former Team Member
Posts: 23162
Joined: Sun May 17, 2009 1:05 pm
Location: Australia
Name: Bill

Re: Guest posting doesnt work?

Post by Oyabun1 »

AbbeyG wrote:What MODs do you have installed? I have quite a few mods installed, but I think I will add the mods that i think are relevant to the issue :D
How about you let us decide what is relevant?
                      Support Request Template
3.0.x: Knowledge Base Styles Support MOD Requests
3.1.x: Knowledge BaseStyles SupportExtension Requests
AbbeyG
Registered User
Posts: 88
Joined: Fri Feb 08, 2013 7:14 pm

Re: Guest posting doesnt work?

Post by AbbeyG »

ACP Announcement centre
AOS Notofications
Customizable forms
last post topic title
linked accounts
multiple ranks
NV who was here
topic multimoderation and prefixes
User avatar
stevemaury
Support Team Member
Support Team Member
Posts: 52768
Joined: Thu Nov 02, 2006 12:21 am
Location: The U.P.
Name: Steve
Contact:

Re: Guest posting doesnt work?

Post by stevemaury »

Please post a copy of your includes/functions_user.php file. You will have to rename it to a .txt file.
I can stop all your spam. I can upgrade or update your Board. PM or email me. (Paid support)
AbbeyG
Registered User
Posts: 88
Joined: Fri Feb 08, 2013 7:14 pm

Re: Guest posting doesnt work?

Post by AbbeyG »

here is my functions_user.php

Code: Select all

<?php
/**
*
* @package phpBB3
* @version $Id$
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
	exit;
}

/**
* Obtain user_ids from usernames or vice versa. Returns false on
* success else the error string
*
* @param array &$user_id_ary The user ids to check or empty if usernames used
* @param array &$username_ary The usernames to check or empty if user ids used
* @param mixed $user_type Array of user types to check, false if not restricting by user type
*/
function user_get_id_name(&$user_id_ary, &$username_ary, $user_type = false)
{
	global $db;

	// Are both arrays already filled? Yep, return else
	// are neither array filled?
	if ($user_id_ary && $username_ary)
	{
		return false;
	}
	else if (!$user_id_ary && !$username_ary)
	{
		return 'NO_USERS';
	}

	$which_ary = ($user_id_ary) ? 'user_id_ary' : 'username_ary';

	if ($$which_ary && !is_array($$which_ary))
	{
		$$which_ary = array($$which_ary);
	}

	$sql_in = ($which_ary == 'user_id_ary') ? array_map('intval', $$which_ary) : array_map('utf8_clean_string', $$which_ary);
	unset($$which_ary);

	$user_id_ary = $username_ary = array();

	// Grab the user id/username records
	$sql_where = ($which_ary == 'user_id_ary') ? 'user_id' : 'username_clean';
	$sql = 'SELECT user_id, username
		FROM ' . USERS_TABLE . '
		WHERE ' . $db->sql_in_set($sql_where, $sql_in);

	if ($user_type !== false && !empty($user_type))
	{
		$sql .= ' AND ' . $db->sql_in_set('user_type', $user_type);
	}

	$result = $db->sql_query($sql);

	if (!($row = $db->sql_fetchrow($result)))
	{
		$db->sql_freeresult($result);
		return 'NO_USERS';
	}

	do
	{
		$username_ary[$row['user_id']] = $row['username'];
		$user_id_ary[] = $row['user_id'];
	}
	while ($row = $db->sql_fetchrow($result));
	$db->sql_freeresult($result);

	return false;
}

/**
* Get latest registered username and update database to reflect it
*/
function update_last_username()
{
	global $db;

	// Get latest username
	$sql = 'SELECT user_id, username, user_colour
		FROM ' . USERS_TABLE . '
		WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')
		ORDER BY user_id DESC';
	$result = $db->sql_query_limit($sql, 1);
	$row = $db->sql_fetchrow($result);
	$db->sql_freeresult($result);

	if ($row)
	{
		set_config('newest_user_id', $row['user_id'], true);
		set_config('newest_username', $row['username'], true);
		set_config('newest_user_colour', $row['user_colour'], true);
	}
}

/**
* Updates a username across all relevant tables/fields
*
* @param string $old_name the old/current username
* @param string $new_name the new username
*/
function user_update_name($old_name, $new_name)
{
	global $config, $db, $cache;

	$update_ary = array(
		FORUMS_TABLE			=> array('forum_last_poster_name'),
		MODERATOR_CACHE_TABLE	=> array('username'),
		POSTS_TABLE				=> array('post_username'),
		TOPICS_TABLE			=> array('topic_first_poster_name', 'topic_last_poster_name'),
	);

	foreach ($update_ary as $table => $field_ary)
	{
		foreach ($field_ary as $field)
		{
			$sql = "UPDATE $table
				SET $field = '" . $db->sql_escape($new_name) . "'
				WHERE $field = '" . $db->sql_escape($old_name) . "'";
			$db->sql_query($sql);
		}
	}

	if ($config['newest_username'] == $old_name)
	{
		set_config('newest_username', $new_name, true);
	}

	// Because some tables/caches use username-specific data we need to purge this here.
	$cache->destroy('sql', MODERATOR_CACHE_TABLE);
}

/**
* Adds an user
*
* @param mixed $user_row An array containing the following keys (and the appropriate values): username, group_id (the group to place the user in), user_email and the user_type(usually 0). Additional entries not overridden by defaults will be forwarded.
* @param string $cp_data custom profile fields, see custom_profile::build_insert_sql_array
* @return the new user's ID.
*/
function user_add($user_row, $cp_data = false)
{
	global $db, $user, $auth, $config, $phpbb_root_path, $phpEx;

	if (empty($user_row['username']) || !isset($user_row['group_id']) || !isset($user_row['user_email']) || !isset($user_row['user_type']))
	{
		return false;
	}

	$username_clean = utf8_clean_string($user_row['username']);

	if (empty($username_clean))
	{
		return false;
	}

	$sql_ary = array(
		'username'			=> $user_row['username'],
		'username_clean'	=> $username_clean,
		'user_password'		=> (isset($user_row['user_password'])) ? $user_row['user_password'] : '',
		'user_pass_convert'	=> 0,
		'user_email'		=> strtolower($user_row['user_email']),
		'user_email_hash'	=> phpbb_email_hash($user_row['user_email']),
		'group_id'			=> $user_row['group_id'],
		'user_type'			=> $user_row['user_type'],
	);

	// These are the additional vars able to be specified
	$additional_vars = array(
		'user_permissions'	=> '',
		'user_timezone'		=> $config['board_timezone'],
		'user_dateformat'	=> $config['default_dateformat'],
		'user_lang'			=> $config['default_lang'],
		'user_style'		=> (int) $config['default_style'],
		'user_actkey'		=> '',
		'user_ip'			=> '',
		'user_regdate'		=> time(),
		'user_passchg'		=> time(),
		'user_options'		=> 230271,
		// We do not set the new flag here - registration scripts need to specify it
		'user_new'			=> 0,

		'user_inactive_reason'	=> 0,
		'user_inactive_time'	=> 0,
		'user_lastmark'			=> time(),
		'user_lastvisit'		=> 0,
		'user_lastpost_time'	=> 0,
		'user_lastpage'			=> '',
		'user_posts'			=> 0,
		'user_dst'				=> (int) $config['board_dst'],
		'user_colour'			=> '',
		'user_occ'				=> '',
		'user_interests'		=> '',
		'user_avatar'			=> '',
		'user_avatar_type'		=> 0,
		'user_avatar_width'		=> 0,
		'user_avatar_height'	=> 0,
		'user_new_privmsg'		=> 0,
		'user_unread_privmsg'	=> 0,
		'user_last_privmsg'		=> 0,
		'user_message_rules'	=> 0,
		'user_full_folder'		=> PRIVMSGS_NO_BOX,
		'user_emailtime'		=> 0,

		'user_notify'			=> 0,
		'user_notify_pm'		=> 1,
		'user_notify_type'		=> NOTIFY_EMAIL,
		'user_allow_pm'			=> 1,
		'user_allow_viewonline'	=> 1,
		'user_allow_viewemail'	=> 1,
		'user_allow_massemail'	=> 1,

		'user_sig'					=> '',
		'user_sig_bbcode_uid'		=> '',
		'user_sig_bbcode_bitfield'	=> '',

		'user_form_salt'			=> unique_id(),
	);

	// Now fill the sql array with not required variables
	foreach ($additional_vars as $key => $default_value)
	{
		$sql_ary[$key] = (isset($user_row[$key])) ? $user_row[$key] : $default_value;
	}

	// Any additional variables in $user_row not covered above?
	$remaining_vars = array_diff(array_keys($user_row), array_keys($sql_ary));

	// Now fill our sql array with the remaining vars
	if (sizeof($remaining_vars))
	{
		foreach ($remaining_vars as $key)
		{
			$sql_ary[$key] = $user_row[$key];
		}
	}

	$sql = 'INSERT INTO ' . USERS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
	$db->sql_query($sql);

	$user_id = $db->sql_nextid();

	// Insert Custom Profile Fields
	if ($cp_data !== false && sizeof($cp_data))
	{
		$cp_data['user_id'] = (int) $user_id;

		if (!class_exists('custom_profile'))
		{
			include_once($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx);
		}

		$sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' .
			$db->sql_build_array('INSERT', custom_profile::build_insert_sql_array($cp_data));
		$db->sql_query($sql);
	}

	// Place into appropriate group...
	$sql = 'INSERT INTO ' . USER_GROUP_TABLE . ' ' . $db->sql_build_array('INSERT', array(
		'user_id'		=> (int) $user_id,
		'group_id'		=> (int) $user_row['group_id'],
		'user_pending'	=> 0)
	);
	$db->sql_query($sql);

	// Now make it the users default group...
	group_set_user_default($user_row['group_id'], array($user_id), false);

	// Add to newly registered users group if user_new is 1
	if ($config['new_member_post_limit'] && $sql_ary['user_new'])
	{
		$sql = 'SELECT group_id
			FROM ' . GROUPS_TABLE . "
			WHERE group_name = 'NEWLY_REGISTERED'
				AND group_type = " . GROUP_SPECIAL;
		$result = $db->sql_query($sql);
		$add_group_id = (int) $db->sql_fetchfield('group_id');
		$db->sql_freeresult($result);

		if ($add_group_id)
		{
			// Because these actions only fill the log unneccessarily we skip the add_log() entry with a little hack. :/
			$GLOBALS['skip_add_log'] = true;

			// Add user to "newly registered users" group and set to default group if admin specified so.
			if ($config['new_member_group_default'])
			{
				group_user_add($add_group_id, $user_id, false, false, true);
				$user_row['group_id'] = $add_group_id;
			}
			else
			{
				group_user_add($add_group_id, $user_id);
			}

			unset($GLOBALS['skip_add_log']);
		}
	}

	// set the newest user and adjust the user count if the user is a normal user and no activation mail is sent
	if ($user_row['user_type'] == USER_NORMAL || $user_row['user_type'] == USER_FOUNDER)
	{
		set_config('newest_user_id', $user_id, true);
		set_config('newest_username', $user_row['username'], true);
		set_config_count('num_users', 1, true);

		$sql = 'SELECT group_colour
			FROM ' . GROUPS_TABLE . '
			WHERE group_id = ' . (int) $user_row['group_id'];
		$result = $db->sql_query_limit($sql, 1);
		$row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

		set_config('newest_user_colour', $row['group_colour'], true);
	}

	return $user_id;
}

/**
* Remove User
*/
function user_delete($mode, $user_id, $post_username = false)
{
	global $cache, $config, $db, $user, $auth;
	global $phpbb_root_path, $phpEx;

	$sql = 'SELECT *
		FROM ' . USERS_TABLE . '
		WHERE user_id = ' . $user_id;
	$result = $db->sql_query($sql);
	$user_row = $db->sql_fetchrow($result);
	$db->sql_freeresult($result);

	if (!$user_row)
	{
		return false;
	}

	// Before we begin, we will remove the reports the user issued.
	$sql = 'SELECT r.post_id, p.topic_id
		FROM ' . REPORTS_TABLE . ' r, ' . POSTS_TABLE . ' p
		WHERE r.user_id = ' . $user_id . '
			AND p.post_id = r.post_id';
	$result = $db->sql_query($sql);

	$report_posts = $report_topics = array();
	while ($row = $db->sql_fetchrow($result))
	{
		$report_posts[] = $row['post_id'];
		$report_topics[] = $row['topic_id'];
	}
	$db->sql_freeresult($result);

	if (sizeof($report_posts))
	{
		$report_posts = array_unique($report_posts);
		$report_topics = array_unique($report_topics);

		// Get a list of topics that still contain reported posts
		$sql = 'SELECT DISTINCT topic_id
			FROM ' . POSTS_TABLE . '
			WHERE ' . $db->sql_in_set('topic_id', $report_topics) . '
				AND post_reported = 1
				AND ' . $db->sql_in_set('post_id', $report_posts, true);
		$result = $db->sql_query($sql);

		$keep_report_topics = array();
		while ($row = $db->sql_fetchrow($result))
		{
			$keep_report_topics[] = $row['topic_id'];
		}
		$db->sql_freeresult($result);

		if (sizeof($keep_report_topics))
		{
			$report_topics = array_diff($report_topics, $keep_report_topics);
		}
		unset($keep_report_topics);

		// Now set the flags back
		$sql = 'UPDATE ' . POSTS_TABLE . '
			SET post_reported = 0
			WHERE ' . $db->sql_in_set('post_id', $report_posts);
		$db->sql_query($sql);

		if (sizeof($report_topics))
		{
			$sql = 'UPDATE ' . TOPICS_TABLE . '
				SET topic_reported = 0
				WHERE ' . $db->sql_in_set('topic_id', $report_topics);
			$db->sql_query($sql);
		}
	}

	// Remove reports
	$db->sql_query('DELETE FROM ' . REPORTS_TABLE . ' WHERE user_id = ' . $user_id);

	if ($user_row['user_avatar'] && $user_row['user_avatar_type'] == AVATAR_UPLOAD)
	{
		avatar_delete('user', $user_row);
	}

	switch ($mode)
	{
		case 'retain':

			$db->sql_transaction('begin');

			if ($post_username === false)
			{
				$post_username = $user->lang['GUEST'];
			}

			// If the user is inactive and newly registered we assume no posts from this user being there...
			if ($user_row['user_type'] == USER_INACTIVE && $user_row['user_inactive_reason'] == INACTIVE_REGISTER && !$user_row['user_posts'])
			{
			}
			else
			{
				$sql = 'UPDATE ' . FORUMS_TABLE . '
					SET forum_last_poster_id = ' . ANONYMOUS . ", forum_last_poster_name = '" . $db->sql_escape($post_username) . "', forum_last_poster_colour = ''
					WHERE forum_last_poster_id = $user_id";
				$db->sql_query($sql);

				$sql = 'UPDATE ' . POSTS_TABLE . '
					SET poster_id = ' . ANONYMOUS . ", post_username = '" . $db->sql_escape($post_username) . "'
					WHERE poster_id = $user_id";
				$db->sql_query($sql);

				$sql = 'UPDATE ' . POSTS_TABLE . '
					SET post_edit_user = ' . ANONYMOUS . "
					WHERE post_edit_user = $user_id";
				$db->sql_query($sql);

				$sql = 'UPDATE ' . TOPICS_TABLE . '
					SET topic_poster = ' . ANONYMOUS . ", topic_first_poster_name = '" . $db->sql_escape($post_username) . "', topic_first_poster_colour = ''
					WHERE topic_poster = $user_id";
				$db->sql_query($sql);

				$sql = 'UPDATE ' . TOPICS_TABLE . '
					SET topic_last_poster_id = ' . ANONYMOUS . ", topic_last_poster_name = '" . $db->sql_escape($post_username) . "', topic_last_poster_colour = ''
					WHERE topic_last_poster_id = $user_id";
				$db->sql_query($sql);

				$sql = 'UPDATE ' . ATTACHMENTS_TABLE . '
					SET poster_id = ' . ANONYMOUS . "
					WHERE poster_id = $user_id";
				$db->sql_query($sql);

				// Since we change every post by this author, we need to count this amount towards the anonymous user

				// Update the post count for the anonymous user
				if ($user_row['user_posts'])
				{
					$sql = 'UPDATE ' . USERS_TABLE . '
						SET user_posts = user_posts + ' . $user_row['user_posts'] . '
						WHERE user_id = ' . ANONYMOUS;
					$db->sql_query($sql);
				}
			}

			$db->sql_transaction('commit');

		break;

		case 'remove':

			if (!function_exists('delete_posts'))
			{
				include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
			}

			// Delete posts, attachments, etc.
			delete_posts('poster_id', $user_id);

		break;
	}

	$db->sql_transaction('begin');

	$table_ary = array(USERS_TABLE, USER_GROUP_TABLE, TOPICS_WATCH_TABLE, FORUMS_WATCH_TABLE, ACL_USERS_TABLE, TOPICS_TRACK_TABLE, TOPICS_POSTED_TABLE, FORUMS_TRACK_TABLE, PROFILE_FIELDS_DATA_TABLE, MODERATOR_CACHE_TABLE, DRAFTS_TABLE, BOOKMARKS_TABLE, SESSIONS_KEYS_TABLE, PRIVMSGS_FOLDER_TABLE, PRIVMSGS_RULES_TABLE);

	foreach ($table_ary as $table)
	{
		$sql = "DELETE FROM $table
			WHERE user_id = $user_id";
		$db->sql_query($sql);
	}

	$cache->destroy('sql', MODERATOR_CACHE_TABLE);

	// Delete user log entries about this user
	$sql = 'DELETE FROM ' . LOG_TABLE . '
		WHERE reportee_id = ' . $user_id;
	$db->sql_query($sql);

	// Change user_id to anonymous for this users triggered events
	$sql = 'UPDATE ' . LOG_TABLE . '
		SET user_id = ' . ANONYMOUS . '
		WHERE user_id = ' . $user_id;
	$db->sql_query($sql);

	// Delete the user_id from the zebra table
	$sql = 'DELETE FROM ' . ZEBRA_TABLE . '
		WHERE user_id = ' . $user_id . '
			OR zebra_id = ' . $user_id;
	$db->sql_query($sql);

	// Delete the user_id from the banlist
	$sql = 'DELETE FROM ' . BANLIST_TABLE . '
		WHERE ban_userid = ' . $user_id;
	$db->sql_query($sql);

	// Delete the user_id from the session table
	$sql = 'DELETE FROM ' . SESSIONS_TABLE . '
		WHERE session_user_id = ' . $user_id;
	$db->sql_query($sql);

	// Clean the private messages tables from the user
	if (!function_exists('phpbb_delete_user_pms'))
	{
		include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
	}
	phpbb_delete_user_pms($user_id);

	$db->sql_transaction('commit');

	// Reset newest user info if appropriate
	if ($config['newest_user_id'] == $user_id)
	{
		update_last_username();
	}

	// Decrement number of users if this user is active
	if ($user_row['user_type'] != USER_INACTIVE && $user_row['user_type'] != USER_IGNORE)
	{
		set_config_count('num_users', -1, true);
	}

	return false;
}

/**
* Flips user_type from active to inactive and vice versa, handles group membership updates
*
* @param string $mode can be flip for flipping from active/inactive, activate or deactivate
*/
function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL)
{
	global $config, $db, $user, $auth;

	$deactivated = $activated = 0;
	$sql_statements = array();

	if (!is_array($user_id_ary))
	{
		$user_id_ary = array($user_id_ary);
	}

	if (!sizeof($user_id_ary))
	{
		return;
	}

	$sql = 'SELECT user_id, group_id, user_type, user_inactive_reason
		FROM ' . USERS_TABLE . '
		WHERE ' . $db->sql_in_set('user_id', $user_id_ary);
	$result = $db->sql_query($sql);

	while ($row = $db->sql_fetchrow($result))
	{
		$sql_ary = array();

		if ($row['user_type'] == USER_IGNORE || $row['user_type'] == USER_FOUNDER ||
			($mode == 'activate' && $row['user_type'] != USER_INACTIVE) ||
			($mode == 'deactivate' && $row['user_type'] == USER_INACTIVE))
		{
			continue;
		}

		if ($row['user_type'] == USER_INACTIVE)
		{
			$activated++;
		}
		else
		{
			$deactivated++;

			// Remove the users session key...
			$user->reset_login_keys($row['user_id']);
		}

		$sql_ary += array(
			'user_type'				=> ($row['user_type'] == USER_NORMAL) ? USER_INACTIVE : USER_NORMAL,
			'user_inactive_time'	=> ($row['user_type'] == USER_NORMAL) ? time() : 0,
			'user_inactive_reason'	=> ($row['user_type'] == USER_NORMAL) ? $reason : 0,
		);

		$sql_statements[$row['user_id']] = $sql_ary;
	}
	$db->sql_freeresult($result);

	if (sizeof($sql_statements))
	{
		foreach ($sql_statements as $user_id => $sql_ary)
		{
			$sql = 'UPDATE ' . USERS_TABLE . '
				SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
				WHERE user_id = ' . $user_id;
			$db->sql_query($sql);
		}

		$auth->acl_clear_prefetch(array_keys($sql_statements));
	}

	if ($deactivated)
	{
		set_config_count('num_users', $deactivated * (-1), true);
	}

	if ($activated)
	{
		set_config_count('num_users', $activated, true);
	}

	// Update latest username
	update_last_username();
}

/**
* Add a ban or ban exclusion to the banlist. Bans either a user, an IP or an email address
*
* @param string $mode Type of ban. One of the following: user, ip, email
* @param mixed $ban Banned entity. Either string or array with usernames, ips or email addresses
* @param int $ban_len Ban length in minutes
* @param string $ban_len_other Ban length as a date (YYYY-MM-DD)
* @param boolean $ban_exclude Exclude these entities from banning?
* @param string $ban_reason String describing the reason for this ban
* @return boolean
*/
function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reason, $ban_give_reason = '')
{
	global $db, $user, $auth, $cache;

	// Delete stale bans
	$sql = 'DELETE FROM ' . BANLIST_TABLE . '
		WHERE ban_end < ' . time() . '
			AND ban_end <> 0';
	$db->sql_query($sql);

	$ban_list = (!is_array($ban)) ? array_unique(explode("\n", $ban)) : $ban;
	$ban_list_log = implode(', ', $ban_list);

	$current_time = time();

	// Set $ban_end to the unix time when the ban should end. 0 is a permanent ban.
	if ($ban_len)
	{
		if ($ban_len != -1 || !$ban_len_other)
		{
			$ban_end = max($current_time, $current_time + ($ban_len) * 60);
		}
		else
		{
			$ban_other = explode('-', $ban_len_other);
			if (sizeof($ban_other) == 3 && ((int)$ban_other[0] < 9999) &&
				(strlen($ban_other[0]) == 4) && (strlen($ban_other[1]) == 2) && (strlen($ban_other[2]) == 2))
			{
				$time_offset = (isset($user->timezone) && isset($user->dst)) ? (int) $user->timezone + (int) $user->dst : 0;
				$ban_end = max($current_time, gmmktime(0, 0, 0, (int)$ban_other[1], (int)$ban_other[2], (int)$ban_other[0]) - $time_offset);
			}
			else
			{
				trigger_error('LENGTH_BAN_INVALID', E_USER_WARNING);
			}
		}
	}
	else
	{
		$ban_end = 0;
	}

	$founder = $founder_names = array();

	if (!$ban_exclude)
	{
		// Create a list of founder...
		$sql = 'SELECT user_id, user_email, username_clean
			FROM ' . USERS_TABLE . '
			WHERE user_type = ' . USER_FOUNDER;
		$result = $db->sql_query($sql);

		while ($row = $db->sql_fetchrow($result))
		{
			$founder[$row['user_id']] = $row['user_email'];
			$founder_names[$row['user_id']] = $row['username_clean'];
		}
		$db->sql_freeresult($result);
	}

	$banlist_ary = array();

	switch ($mode)
	{
		case 'user':
			$type = 'ban_userid';

			// At the moment we do not support wildcard username banning

			// Select the relevant user_ids.
			$sql_usernames = array();

			foreach ($ban_list as $username)
			{
				$username = trim($username);
				if ($username != '')
				{
					$clean_name = utf8_clean_string($username);
					if ($clean_name == $user->data['username_clean'])
					{
						trigger_error('CANNOT_BAN_YOURSELF', E_USER_WARNING);
					}
					if (in_array($clean_name, $founder_names))
					{
						trigger_error('CANNOT_BAN_FOUNDER', E_USER_WARNING);
					}
					$sql_usernames[] = $clean_name;
				}
			}

			// Make sure we have been given someone to ban
			if (!sizeof($sql_usernames))
			{
				trigger_error('NO_USER_SPECIFIED', E_USER_WARNING);
			}

			$sql = 'SELECT user_id
				FROM ' . USERS_TABLE . '
				WHERE ' . $db->sql_in_set('username_clean', $sql_usernames);

			// Do not allow banning yourself, the guest account, or founders.
			$non_bannable = array($user->data['user_id'], ANONYMOUS);
			if (sizeof($founder))
			{
				$sql .= ' AND ' . $db->sql_in_set('user_id', array_merge(array_keys($founder), $non_bannable), true);
			}
			else
			{
				$sql .= ' AND ' . $db->sql_in_set('user_id', $non_bannable, true);
			}

			$result = $db->sql_query($sql);

			if ($row = $db->sql_fetchrow($result))
			{
				do
				{
					$banlist_ary[] = (int) $row['user_id'];
				}
				while ($row = $db->sql_fetchrow($result));
			}
			else
			{
				$db->sql_freeresult($result);
				trigger_error('NO_USERS', E_USER_WARNING);
			}
			$db->sql_freeresult($result);
		break;

		case 'ip':
			$type = 'ban_ip';

			foreach ($ban_list as $ban_item)
			{
				if (preg_match('#^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})[ ]*\-[ ]*([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$#', trim($ban_item), $ip_range_explode))
				{
					// This is an IP range
					// Don't ask about all this, just don't ask ... !
					$ip_1_counter = $ip_range_explode[1];
					$ip_1_end = $ip_range_explode[5];

					while ($ip_1_counter <= $ip_1_end)
					{
						$ip_2_counter = ($ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[2] : 0;
						$ip_2_end = ($ip_1_counter < $ip_1_end) ? 254 : $ip_range_explode[6];

						if ($ip_2_counter == 0 && $ip_2_end == 254)
						{
							$ip_2_counter = 256;
							$ip_2_fragment = 256;

							$banlist_ary[] = "$ip_1_counter.*";
						}

						while ($ip_2_counter <= $ip_2_end)
						{
							$ip_3_counter = ($ip_2_counter == $ip_range_explode[2] && $ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[3] : 0;
							$ip_3_end = ($ip_2_counter < $ip_2_end || $ip_1_counter < $ip_1_end) ? 254 : $ip_range_explode[7];

							if ($ip_3_counter == 0 && $ip_3_end == 254)
							{
								$ip_3_counter = 256;
								$ip_3_fragment = 256;

								$banlist_ary[] = "$ip_1_counter.$ip_2_counter.*";
							}

							while ($ip_3_counter <= $ip_3_end)
							{
								$ip_4_counter = ($ip_3_counter == $ip_range_explode[3] && $ip_2_counter == $ip_range_explode[2] && $ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[4] : 0;
								$ip_4_end = ($ip_3_counter < $ip_3_end || $ip_2_counter < $ip_2_end) ? 254 : $ip_range_explode[8];

								if ($ip_4_counter == 0 && $ip_4_end == 254)
								{
									$ip_4_counter = 256;
									$ip_4_fragment = 256;

									$banlist_ary[] = "$ip_1_counter.$ip_2_counter.$ip_3_counter.*";
								}

								while ($ip_4_counter <= $ip_4_end)
								{
									$banlist_ary[] = "$ip_1_counter.$ip_2_counter.$ip_3_counter.$ip_4_counter";
									$ip_4_counter++;
								}
								$ip_3_counter++;
							}
							$ip_2_counter++;
						}
						$ip_1_counter++;
					}
				}
				else if (preg_match('#^([0-9]{1,3})\.([0-9\*]{1,3})\.([0-9\*]{1,3})\.([0-9\*]{1,3})$#', trim($ban_item)) || preg_match('#^[a-f0-9:]+\*?$#i', trim($ban_item)))
				{
					// Normal IP address
					$banlist_ary[] = trim($ban_item);
				}
				else if (preg_match('#^\*$#', trim($ban_item)))
				{
					// Ban all IPs
					$banlist_ary[] = '*';
				}
				else if (preg_match('#^([\w\-_]\.?){2,}$#is', trim($ban_item)))
				{
					// hostname
					$ip_ary = gethostbynamel(trim($ban_item));

					if (!empty($ip_ary))
					{
						foreach ($ip_ary as $ip)
						{
							if ($ip)
							{
								if (strlen($ip) > 40)
								{
									continue;
								}

								$banlist_ary[] = $ip;
							}
						}
					}
				}

				if (empty($banlist_ary))
				{
					trigger_error('NO_IPS_DEFINED', E_USER_WARNING);
				}
			}
		break;

		case 'email':
			$type = 'ban_email';

			foreach ($ban_list as $ban_item)
			{
				$ban_item = trim($ban_item);

				if (preg_match('#^.*?@*|(([a-z0-9\-]+\.)+([a-z]{2,3}))$#i', $ban_item))
				{
					if (strlen($ban_item) > 100)
					{
						continue;
					}

					if (!sizeof($founder) || !in_array($ban_item, $founder))
					{
						$banlist_ary[] = $ban_item;
					}
				}
			}

			if (sizeof($ban_list) == 0)
			{
				trigger_error('NO_EMAILS_DEFINED', E_USER_WARNING);
			}
		break;

		default:
			trigger_error('NO_MODE', E_USER_WARNING);
		break;
	}

	// Fetch currently set bans of the specified type and exclude state. Prevent duplicate bans.
	$sql_where = ($type == 'ban_userid') ? 'ban_userid <> 0' : "$type <> ''";

	$sql = "SELECT $type
		FROM " . BANLIST_TABLE . "
		WHERE $sql_where
			AND ban_exclude = " . (int) $ban_exclude;
	$result = $db->sql_query($sql);

	// Reset $sql_where, because we use it later...
	$sql_where = '';

	if ($row = $db->sql_fetchrow($result))
	{
		$banlist_ary_tmp = array();
		do
		{
			switch ($mode)
			{
				case 'user':
					$banlist_ary_tmp[] = $row['ban_userid'];
				break;

				case 'ip':
					$banlist_ary_tmp[] = $row['ban_ip'];
				break;

				case 'email':
					$banlist_ary_tmp[] = $row['ban_email'];
				break;
			}
		}
		while ($row = $db->sql_fetchrow($result));

		$banlist_ary_tmp = array_intersect($banlist_ary, $banlist_ary_tmp);

		if (sizeof($banlist_ary_tmp))
		{
			// One or more entities are already banned/excluded, delete the existing bans, so they can be re-inserted with the given new length
			$sql = 'DELETE FROM ' . BANLIST_TABLE . '
				WHERE ' . $db->sql_in_set($type, $banlist_ary_tmp) . '
					AND ban_exclude = ' . (int) $ban_exclude;
			$db->sql_query($sql);
		}

		unset($banlist_ary_tmp);
	}
	$db->sql_freeresult($result);

	// We have some entities to ban
	if (sizeof($banlist_ary))
	{
		$sql_ary = array();

		foreach ($banlist_ary as $ban_entry)
		{
			$sql_ary[] = array(
				$type				=> $ban_entry,
				'ban_start'			=> (int) $current_time,
				'ban_end'			=> (int) $ban_end,
				'ban_exclude'		=> (int) $ban_exclude,
				'ban_reason'		=> (string) $ban_reason,
				'ban_give_reason'	=> (string) $ban_give_reason,
			);
		}

		$db->sql_multi_insert(BANLIST_TABLE, $sql_ary);

		// If we are banning we want to logout anyone matching the ban
		if (!$ban_exclude)
		{
			switch ($mode)
			{
				case 'user':
					$sql_where = 'WHERE ' . $db->sql_in_set('session_user_id', $banlist_ary);
				break;

				case 'ip':
					$sql_where = 'WHERE ' . $db->sql_in_set('session_ip', $banlist_ary);
				break;

				case 'email':
					$banlist_ary_sql = array();

					foreach ($banlist_ary as $ban_entry)
					{
						$banlist_ary_sql[] = (string) str_replace('*', '%', $ban_entry);
					}

					$sql = 'SELECT user_id
						FROM ' . USERS_TABLE . '
						WHERE ' . $db->sql_in_set('user_email', $banlist_ary_sql);
					$result = $db->sql_query($sql);

					$sql_in = array();

					if ($row = $db->sql_fetchrow($result))
					{
						do
						{
							$sql_in[] = $row['user_id'];
						}
						while ($row = $db->sql_fetchrow($result));

						$sql_where = 'WHERE ' . $db->sql_in_set('session_user_id', $sql_in);
					}
					$db->sql_freeresult($result);
				break;
			}

			if (isset($sql_where) && $sql_where)
			{
				$sql = 'DELETE FROM ' . SESSIONS_TABLE . "
					$sql_where";
				$db->sql_query($sql);

				if ($mode == 'user')
				{
					$sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . ' ' . ((in_array('*', $banlist_ary)) ? '' : 'WHERE ' . $db->sql_in_set('user_id', $banlist_ary));
					$db->sql_query($sql);
				}
			}
		}

		// Update log
		$log_entry = ($ban_exclude) ? 'LOG_BAN_EXCLUDE_' : 'LOG_BAN_';

		// Add to moderator log, admin log and user notes
		add_log('admin', $log_entry . strtoupper($mode), $ban_reason, $ban_list_log);
		add_log('mod', 0, 0, $log_entry . strtoupper($mode), $ban_reason, $ban_list_log);
		if ($mode == 'user')
		{
			foreach ($banlist_ary as $user_id)
			{
				add_log('user', $user_id, $log_entry . strtoupper($mode), $ban_reason, $ban_list_log);
			}
		}

		$cache->destroy('sql', BANLIST_TABLE);

		return true;
	}

	// There was nothing to ban/exclude. But destroying the cache because of the removal of stale bans.
	$cache->destroy('sql', BANLIST_TABLE);

	return false;
}

/**
* Unban User
*/
function user_unban($mode, $ban)
{
	global $db, $user, $auth, $cache;

	// Delete stale bans
	$sql = 'DELETE FROM ' . BANLIST_TABLE . '
		WHERE ban_end < ' . time() . '
			AND ban_end <> 0';
	$db->sql_query($sql);

	if (!is_array($ban))
	{
		$ban = array($ban);
	}

	$unban_sql = array_map('intval', $ban);

	if (sizeof($unban_sql))
	{
		// Grab details of bans for logging information later
		switch ($mode)
		{
			case 'user':
				$sql = 'SELECT u.username AS unban_info, u.user_id
					FROM ' . USERS_TABLE . ' u, ' . BANLIST_TABLE . ' b
					WHERE ' . $db->sql_in_set('b.ban_id', $unban_sql) . '
						AND u.user_id = b.ban_userid';
			break;

			case 'email':
				$sql = 'SELECT ban_email AS unban_info
					FROM ' . BANLIST_TABLE . '
					WHERE ' . $db->sql_in_set('ban_id', $unban_sql);
			break;

			case 'ip':
				$sql = 'SELECT ban_ip AS unban_info
					FROM ' . BANLIST_TABLE . '
					WHERE ' . $db->sql_in_set('ban_id', $unban_sql);
			break;
		}
		$result = $db->sql_query($sql);

		$l_unban_list = '';
		$user_ids_ary = array();
		while ($row = $db->sql_fetchrow($result))
		{
			$l_unban_list .= (($l_unban_list != '') ? ', ' : '') . $row['unban_info'];
			if ($mode == 'user')
			{
				$user_ids_ary[] = $row['user_id'];
			}
		}
		$db->sql_freeresult($result);

		$sql = 'DELETE FROM ' . BANLIST_TABLE . '
			WHERE ' . $db->sql_in_set('ban_id', $unban_sql);
		$db->sql_query($sql);

		// Add to moderator log, admin log and user notes
		add_log('admin', 'LOG_UNBAN_' . strtoupper($mode), $l_unban_list);
		add_log('mod', 0, 0, 'LOG_UNBAN_' . strtoupper($mode), $l_unban_list);
		if ($mode == 'user')
		{
			foreach ($user_ids_ary as $user_id)
			{
				add_log('user', $user_id, 'LOG_UNBAN_' . strtoupper($mode), $l_unban_list);
			}
		}
	}

	$cache->destroy('sql', BANLIST_TABLE);

	return false;
}

/**
* Internet Protocol Address Whois
* RFC3912: WHOIS Protocol Specification
*
* @param string $ip		Ip address, either IPv4 or IPv6.
*
* @return string		Empty string if not a valid ip address.
*						Otherwise make_clickable()'ed whois result.
*/
function user_ipwhois($ip)
{
	if (empty($ip))
	{
		return '';
	}

	if (preg_match(get_preg_expression('ipv4'), $ip))
	{
		// IPv4 address
		$whois_host = 'whois.arin.net.';
	}
	else if (preg_match(get_preg_expression('ipv6'), $ip))
	{
		// IPv6 address
		$whois_host = 'whois.sixxs.net.';
	}
	else
	{
		return '';
	}

	$ipwhois = '';

	if (($fsk = @fsockopen($whois_host, 43)))
	{
		// CRLF as per RFC3912
		fputs($fsk, "$ip\r\n");
		while (!feof($fsk))
		{
			$ipwhois .= fgets($fsk, 1024);
		}
		@fclose($fsk);
	}

	$match = array();

	// Test for referrals from $whois_host to other whois databases, roll on rwhois
	if (preg_match('#ReferralServer: whois://(.+)#im', $ipwhois, $match))
	{
		if (strpos($match[1], ':') !== false)
		{
			$pos	= strrpos($match[1], ':');
			$server	= substr($match[1], 0, $pos);
			$port	= (int) substr($match[1], $pos + 1);
			unset($pos);
		}
		else
		{
			$server	= $match[1];
			$port	= 43;
		}

		$buffer = '';

		if (($fsk = @fsockopen($server, $port)))
		{
			fputs($fsk, "$ip\r\n");
			while (!feof($fsk))
			{
				$buffer .= fgets($fsk, 1024);
			}
			@fclose($fsk);
		}

		// Use the result from $whois_host if we don't get any result here
		$ipwhois = (empty($buffer)) ? $ipwhois : $buffer;
	}

	$ipwhois = htmlspecialchars($ipwhois);

	// Magic URL ;)
	return trim(make_clickable($ipwhois, false, ''));
}

/**
* Data validation ... used primarily but not exclusively by ucp modules
*
* "Master" function for validating a range of data types
*/
function validate_data($data, $val_ary)
{
	global $user;

	$error = array();

	foreach ($val_ary as $var => $val_seq)
	{
		if (!is_array($val_seq[0]))
		{
			$val_seq = array($val_seq);
		}

		foreach ($val_seq as $validate)
		{
			$function = array_shift($validate);
			array_unshift($validate, $data[$var]);

			if ($result = call_user_func_array('validate_' . $function, $validate))
			{
				// Since errors are checked later for their language file existence, we need to make sure custom errors are not adjusted.
				$error[] = (empty($user->lang[$result . '_' . strtoupper($var)])) ? $result : $result . '_' . strtoupper($var);
			}
		}
	}

	return $error;
}

/**
* Validate String
*
* @return	boolean|string	Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
*/
function validate_string($string, $optional = false, $min = 0, $max = 0)
{
	if (empty($string) && $optional)
	{
		return false;
	}

	if ($min && utf8_strlen(htmlspecialchars_decode($string)) < $min)
	{
		return 'TOO_SHORT';
	}
	else if ($max && utf8_strlen(htmlspecialchars_decode($string)) > $max)
	{
		return 'TOO_LONG';
	}

	return false;
}

/**
* Validate Number
*
* @return	boolean|string	Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
*/
function validate_num($num, $optional = false, $min = 0, $max = 1E99)
{
	if (empty($num) && $optional)
	{
		return false;
	}

	if ($num < $min)
	{
		return 'TOO_SMALL';
	}
	else if ($num > $max)
	{
		return 'TOO_LARGE';
	}

	return false;
}

/**
* Validate Date
* @param String $string a date in the dd-mm-yyyy format
* @return	boolean
*/
function validate_date($date_string, $optional = false)
{
	$date = explode('-', $date_string);
	if ((empty($date) || sizeof($date) != 3) && $optional)
	{
		return false;
	}
	else if ($optional)
	{
		for ($field = 0; $field <= 1; $field++)
		{
			$date[$field] = (int) $date[$field];
			if (empty($date[$field]))
			{
				$date[$field] = 1;
			}
		}
		$date[2] = (int) $date[2];
		// assume an arbitrary leap year
		if (empty($date[2]))
		{
			$date[2] = 1980;
		}
	}

	if (sizeof($date) != 3 || !checkdate($date[1], $date[0], $date[2]))
	{
		return 'INVALID';
	}

	return false;
}


/**
* Validate Match
*
* @return	boolean|string	Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
*/
function validate_match($string, $optional = false, $match = '')
{
	if (empty($string) && $optional)
	{
		return false;
	}

	if (empty($match))
	{
		return false;
	}

	if (!preg_match($match, $string))
	{
		return 'WRONG_DATA';
	}

	return false;
}

/**
* Validate Language Pack ISO Name
*
* Tests whether a language name is valid and installed
*
* @param string $lang_iso	The language string to test
*
* @return bool|string		Either false if validation succeeded or
*							a string which will be used as the error message
*							(with the variable name appended)
*/
function validate_language_iso_name($lang_iso)
{
	global $db;

	$sql = 'SELECT lang_id
		FROM ' . LANG_TABLE . "
		WHERE lang_iso = '" . $db->sql_escape($lang_iso) . "'";
	$result = $db->sql_query($sql);
	$lang_id = (int) $db->sql_fetchfield('lang_id');
	$db->sql_freeresult($result);

	return ($lang_id) ? false : 'WRONG_DATA';
}

/**
* Check to see if the username has been taken, or if it is disallowed.
* Also checks if it includes the " character, which we don't allow in usernames.
* Used for registering, changing names, and posting anonymously with a username
*
* @param string $username The username to check
* @param string $allowed_username An allowed username, default being $user->data['username']
*
* @return	mixed	Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
*/
function validate_username($username, $allowed_username = false)
{
	global $config, $db, $user, $cache;

	$clean_username = utf8_clean_string($username);
	$allowed_username = ($allowed_username === false) ? $user->data['username_clean'] : utf8_clean_string($allowed_username);

	if ($allowed_username == $clean_username)
	{
		return false;
	}

	// ... fast checks first.
	if (strpos($username, '"') !== false || strpos($username, '"') !== false || empty($clean_username))
	{
		return 'INVALID_CHARS';
	}

	$mbstring = $pcre = false;

	// generic UTF-8 character types supported?
	if ((version_compare(PHP_VERSION, '5.1.0', '>=') || (version_compare(PHP_VERSION, '5.0.0-dev', '<=') && version_compare(PHP_VERSION, '4.4.0', '>='))) && @preg_match('/\p{L}/u', 'a') !== false)
	{
		$pcre = true;
	}
	else if (function_exists('mb_ereg_match'))
	{
		mb_regex_encoding('UTF-8');
		$mbstring = true;
	}

	switch ($config['allow_name_chars'])
	{
		case 'USERNAME_CHARS_ANY':
			$pcre = true;
			$regex = '.+';
		break;

		case 'USERNAME_ALPHA_ONLY':
			$pcre = true;
			$regex = '[A-Za-z0-9]+';
		break;

		case 'USERNAME_ALPHA_SPACERS':
			$pcre = true;
			$regex = '[A-Za-z0-9-[\]_+ ]+';
		break;

		case 'USERNAME_LETTER_NUM':
			if ($pcre)
			{
				$regex = '[\p{Lu}\p{Ll}\p{N}]+';
			}
			else if ($mbstring)
			{
				$regex = '[[:upper:][:lower:][:digit:]]+';
			}
			else
			{
				$pcre = true;
				$regex = '[a-zA-Z0-9]+';
			}
		break;

		case 'USERNAME_LETTER_NUM_SPACERS':
			if ($pcre)
			{
				$regex = '[-\]_+ [\p{Lu}\p{Ll}\p{N}]+';
			}
			else if ($mbstring)
			{
				$regex = '[-\]_+ \[[:upper:][:lower:][:digit:]]+';
			}
			else
			{
				$pcre = true;
				$regex = '[-\]_+ [a-zA-Z0-9]+';
			}
		break;

		case 'USERNAME_ASCII':
		default:
			$pcre = true;
			$regex = '[\x01-\x7F]+';
		break;
	}

	if ($pcre)
	{
		if (!preg_match('#^' . $regex . '$#u', $username))
		{
			return 'INVALID_CHARS';
		}
	}
	else if ($mbstring)
	{
		mb_ereg_search_init($username, '^' . $regex . '$');
		if (!mb_ereg_search())
		{
			return 'INVALID_CHARS';
		}
	}

	$sql = 'SELECT username
		FROM ' . USERS_TABLE . "
		WHERE username_clean = '" . $db->sql_escape($clean_username) . "'";
	$result = $db->sql_query($sql);
	$row = $db->sql_fetchrow($result);
	$db->sql_freeresult($result);

	if ($row)
	{
		return 'USERNAME_TAKEN';
	}

	$sql = 'SELECT group_name
		FROM ' . GROUPS_TABLE . "
		WHERE LOWER(group_name) = '" . $db->sql_escape(utf8_strtolower($username)) . "'";
	$result = $db->sql_query($sql);
	$row = $db->sql_fetchrow($result);
	$db->sql_freeresult($result);

	if ($row)
	{
		return 'USERNAME_TAKEN';
	}

	$bad_usernames = $cache->obtain_disallowed_usernames();

	foreach ($bad_usernames as $bad_username)
	{
		if (preg_match('#^' . $bad_username . '$#', $clean_username))
		{
			return 'USERNAME_DISALLOWED';
		}
	}

	return false;
}

/**
* Check to see if the password meets the complexity settings
*
* @return	boolean|string	Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
*/
function validate_password($password)
{
	global $config, $db, $user;

	if ($password === '' || $config['pass_complex'] === 'PASS_TYPE_ANY')
	{
		// Password empty or no password complexity required.
		return false;
	}

	$pcre = $mbstring = false;

	// generic UTF-8 character types supported?
	if ((version_compare(PHP_VERSION, '5.1.0', '>=') || (version_compare(PHP_VERSION, '5.0.0-dev', '<=') && version_compare(PHP_VERSION, '4.4.0', '>='))) && @preg_match('/\p{L}/u', 'a') !== false)
	{
		$upp = '\p{Lu}';
		$low = '\p{Ll}';
		$num = '\p{N}';
		$sym = '[^\p{Lu}\p{Ll}\p{N}]';
		$pcre = true;
	}
	else if (function_exists('mb_ereg_match'))
	{
		mb_regex_encoding('UTF-8');
		$upp = '[[:upper:]]';
		$low = '[[:lower:]]';
		$num = '[[:digit:]]';
		$sym = '[^[:upper:][:lower:][:digit:]]';
		$mbstring = true;
	}
	else
	{
		$upp = '[A-Z]';
		$low = '[a-z]';
		$num = '[0-9]';
		$sym = '[^A-Za-z0-9]';
		$pcre = true;
	}

	$chars = array();

	switch ($config['pass_complex'])
	{
		// No break statements below ...
		// We require strong passwords in case pass_complex is not set or is invalid
		default:

		// Require mixed case letters, numbers and symbols
		case 'PASS_TYPE_SYMBOL':
			$chars[] = $sym;

		// Require mixed case letters and numbers
		case 'PASS_TYPE_ALPHA':
			$chars[] = $num;

		// Require mixed case letters
		case 'PASS_TYPE_CASE':
			$chars[] = $low;
			$chars[] = $upp;
	}

	if ($pcre)
	{
		foreach ($chars as $char)
		{
			if (!preg_match('#' . $char . '#u', $password))
			{
				return 'INVALID_CHARS';
			}
		}
	}
	else if ($mbstring)
	{
		foreach ($chars as $char)
		{
			if (mb_ereg($char, $password) === false)
			{
				return 'INVALID_CHARS';
			}
		}
	}

	return false;
}

/**
* Check to see if email address is banned or already present in the DB
*
* @param string $email The email to check
* @param string $allowed_email An allowed email, default being $user->data['user_email']
*
* @return mixed Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
*/
function validate_email($email, $allowed_email = false)
{
	global $config, $db, $user;

	$email = strtolower($email);
	$allowed_email = ($allowed_email === false) ? strtolower($user->data['user_email']) : strtolower($allowed_email);

	if ($allowed_email == $email)
	{
		return false;
	}

	if (!preg_match('/^' . get_preg_expression('email') . '$/i', $email))
	{
		return 'EMAIL_INVALID';
	}

	// Check MX record.
	// The idea for this is from reading the UseBB blog/announcement. :)
	if ($config['email_check_mx'])
	{
		list(, $domain) = explode('@', $email);

		if (phpbb_checkdnsrr($domain, 'A') === false && phpbb_checkdnsrr($domain, 'MX') === false)
		{
			return 'DOMAIN_NO_MX_RECORD';
		}
	}

	if (($ban_reason = $user->check_ban(false, false, $email, true)) !== false)
	{
		return ($ban_reason === true) ? 'EMAIL_BANNED' : $ban_reason;
	}

	if (!$config['allow_emailreuse'])
	{
		$sql = 'SELECT user_email_hash
			FROM ' . USERS_TABLE . "
			WHERE user_email_hash = " . $db->sql_escape(phpbb_email_hash($email));
		$result = $db->sql_query($sql);
		$row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

		if ($row)
		{
			return 'EMAIL_TAKEN';
		}
	}

	return false;
}

/**
* Validate jabber address
* Taken from the jabber class within flyspray (see author notes)
*
* @author flyspray.org
*/
function validate_jabber($jid)
{
	if (!$jid)
	{
		return false;
	}

	$seperator_pos = strpos($jid, '@');

	if ($seperator_pos === false)
	{
		return 'WRONG_DATA';
	}

	$username = substr($jid, 0, $seperator_pos);
	$realm = substr($jid, $seperator_pos + 1);

	if (strlen($username) == 0 || strlen($realm) < 3)
	{
		return 'WRONG_DATA';
	}

	$arr = explode('.', $realm);

	if (sizeof($arr) == 0)
	{
		return 'WRONG_DATA';
	}

	foreach ($arr as $part)
	{
		if (substr($part, 0, 1) == '-' || substr($part, -1, 1) == '-')
		{
			return 'WRONG_DATA';
		}

		if (!preg_match("@^[a-zA-Z0-9-.]+$@", $part))
		{
			return 'WRONG_DATA';
		}
	}

	$boundary = array(array(0, 127), array(192, 223), array(224, 239), array(240, 247), array(248, 251), array(252, 253));

	// Prohibited Characters RFC3454 + RFC3920
	$prohibited = array(
		// Table C.1.1
		array(0x0020, 0x0020),		// SPACE
		// Table C.1.2
		array(0x00A0, 0x00A0),		// NO-BREAK SPACE
		array(0x1680, 0x1680),		// OGHAM SPACE MARK
		array(0x2000, 0x2001),		// EN QUAD
		array(0x2001, 0x2001),		// EM QUAD
		array(0x2002, 0x2002),		// EN SPACE
		array(0x2003, 0x2003),		// EM SPACE
		array(0x2004, 0x2004),		// THREE-PER-EM SPACE
		array(0x2005, 0x2005),		// FOUR-PER-EM SPACE
		array(0x2006, 0x2006),		// SIX-PER-EM SPACE
		array(0x2007, 0x2007),		// FIGURE SPACE
		array(0x2008, 0x2008),		// PUNCTUATION SPACE
		array(0x2009, 0x2009),		// THIN SPACE
		array(0x200A, 0x200A),		// HAIR SPACE
		array(0x200B, 0x200B),		// ZERO WIDTH SPACE
		array(0x202F, 0x202F),		// NARROW NO-BREAK SPACE
		array(0x205F, 0x205F),		// MEDIUM MATHEMATICAL SPACE
		array(0x3000, 0x3000),		// IDEOGRAPHIC SPACE
		// Table C.2.1
		array(0x0000, 0x001F),		// [CONTROL CHARACTERS]
		array(0x007F, 0x007F),		// DELETE
		// Table C.2.2
		array(0x0080, 0x009F),		// [CONTROL CHARACTERS]
		array(0x06DD, 0x06DD),		// ARABIC END OF AYAH
		array(0x070F, 0x070F),		// SYRIAC ABBREVIATION MARK
		array(0x180E, 0x180E),		// MONGOLIAN VOWEL SEPARATOR
		array(0x200C, 0x200C), 		// ZERO WIDTH NON-JOINER
		array(0x200D, 0x200D),		// ZERO WIDTH JOINER
		array(0x2028, 0x2028),		// LINE SEPARATOR
		array(0x2029, 0x2029),		// PARAGRAPH SEPARATOR
		array(0x2060, 0x2060),		// WORD JOINER
		array(0x2061, 0x2061),		// FUNCTION APPLICATION
		array(0x2062, 0x2062),		// INVISIBLE TIMES
		array(0x2063, 0x2063),		// INVISIBLE SEPARATOR
		array(0x206A, 0x206F),		// [CONTROL CHARACTERS]
		array(0xFEFF, 0xFEFF),		// ZERO WIDTH NO-BREAK SPACE
		array(0xFFF9, 0xFFFC),		// [CONTROL CHARACTERS]
		array(0x1D173, 0x1D17A),	// [MUSICAL CONTROL CHARACTERS]
		// Table C.3
		array(0xE000, 0xF8FF),		// [PRIVATE USE, PLANE 0]
		array(0xF0000, 0xFFFFD),	// [PRIVATE USE, PLANE 15]
		array(0x100000, 0x10FFFD),	// [PRIVATE USE, PLANE 16]
		// Table C.4
		array(0xFDD0, 0xFDEF),		// [NONCHARACTER CODE POINTS]
		array(0xFFFE, 0xFFFF),		// [NONCHARACTER CODE POINTS]
		array(0x1FFFE, 0x1FFFF),	// [NONCHARACTER CODE POINTS]
		array(0x2FFFE, 0x2FFFF),	// [NONCHARACTER CODE POINTS]
		array(0x3FFFE, 0x3FFFF),	// [NONCHARACTER CODE POINTS]
		array(0x4FFFE, 0x4FFFF),	// [NONCHARACTER CODE POINTS]
		array(0x5FFFE, 0x5FFFF),	// [NONCHARACTER CODE POINTS]
		array(0x6FFFE, 0x6FFFF),	// [NONCHARACTER CODE POINTS]
		array(0x7FFFE, 0x7FFFF),	// [NONCHARACTER CODE POINTS]
		array(0x8FFFE, 0x8FFFF),	// [NONCHARACTER CODE POINTS]
		array(0x9FFFE, 0x9FFFF),	// [NONCHARACTER CODE POINTS]
		array(0xAFFFE, 0xAFFFF),	// [NONCHARACTER CODE POINTS]
		array(0xBFFFE, 0xBFFFF),	// [NONCHARACTER CODE POINTS]
		array(0xCFFFE, 0xCFFFF),	// [NONCHARACTER CODE POINTS]
		array(0xDFFFE, 0xDFFFF),	// [NONCHARACTER CODE POINTS]
		array(0xEFFFE, 0xEFFFF),	// [NONCHARACTER CODE POINTS]
		array(0xFFFFE, 0xFFFFF),	// [NONCHARACTER CODE POINTS]
		array(0x10FFFE, 0x10FFFF),	// [NONCHARACTER CODE POINTS]
		// Table C.5
		array(0xD800, 0xDFFF),		// [SURROGATE CODES]
		// Table C.6
		array(0xFFF9, 0xFFF9),		// INTERLINEAR ANNOTATION ANCHOR
		array(0xFFFA, 0xFFFA),		// INTERLINEAR ANNOTATION SEPARATOR
		array(0xFFFB, 0xFFFB),		// INTERLINEAR ANNOTATION TERMINATOR
		array(0xFFFC, 0xFFFC),		// OBJECT REPLACEMENT CHARACTER
		array(0xFFFD, 0xFFFD),		// REPLACEMENT CHARACTER
		// Table C.7
		array(0x2FF0, 0x2FFB),		// [IDEOGRAPHIC DESCRIPTION CHARACTERS]
		// Table C.8
		array(0x0340, 0x0340),		// COMBINING GRAVE TONE MARK
		array(0x0341, 0x0341),		// COMBINING ACUTE TONE MARK
		array(0x200E, 0x200E),		// LEFT-TO-RIGHT MARK
		array(0x200F, 0x200F),		// RIGHT-TO-LEFT MARK
		array(0x202A, 0x202A),		// LEFT-TO-RIGHT EMBEDDING
		array(0x202B, 0x202B),		// RIGHT-TO-LEFT EMBEDDING
		array(0x202C, 0x202C),		// POP DIRECTIONAL FORMATTING
		array(0x202D, 0x202D),		// LEFT-TO-RIGHT OVERRIDE
		array(0x202E, 0x202E),		// RIGHT-TO-LEFT OVERRIDE
		array(0x206A, 0x206A),		// INHIBIT SYMMETRIC SWAPPING
		array(0x206B, 0x206B),		// ACTIVATE SYMMETRIC SWAPPING
		array(0x206C, 0x206C),		// INHIBIT ARABIC FORM SHAPING
		array(0x206D, 0x206D),		// ACTIVATE ARABIC FORM SHAPING
		array(0x206E, 0x206E),		// NATIONAL DIGIT SHAPES
		array(0x206F, 0x206F),		// NOMINAL DIGIT SHAPES
		// Table C.9
		array(0xE0001, 0xE0001),	// LANGUAGE TAG
		array(0xE0020, 0xE007F),	// [TAGGING CHARACTERS]
		// RFC3920
		array(0x22, 0x22),			// "
		array(0x26, 0x26),			// &
		array(0x27, 0x27),			// '
		array(0x2F, 0x2F),			// /
		array(0x3A, 0x3A),			// :
		array(0x3C, 0x3C),			// <
		array(0x3E, 0x3E),			// >
		array(0x40, 0x40)			// @
	);

	$pos = 0;
	$result = true;

	while ($pos < strlen($username))
	{
		$len = $uni = 0;
		for ($i = 0; $i <= 5; $i++)
		{
			if (ord($username[$pos]) >= $boundary[$i][0] && ord($username[$pos]) <= $boundary[$i][1])
			{
				$len = $i + 1;
				$uni = (ord($username[$pos]) - $boundary[$i][0]) * pow(2, $i * 6);

				for ($k = 1; $k < $len; $k++)
				{
					$uni += (ord($username[$pos + $k]) - 128) * pow(2, ($i - $k) * 6);
				}

				break;
			}
		}

		if ($len == 0)
		{
			return 'WRONG_DATA';
		}

		foreach ($prohibited as $pval)
		{
			if ($uni >= $pval[0] && $uni <= $pval[1])
			{
				$result = false;
				break 2;
			}
		}

		$pos = $pos + $len;
	}

	if (!$result)
	{
		return 'WRONG_DATA';
	}

	return false;
}

/**
* Verifies whether a style ID corresponds to an active style.
*
* @param int $style_id The style_id of a style which should be checked if activated or not.
* @return boolean
*/
function phpbb_style_is_active($style_id)
{
	global $db;

	$sql = 'SELECT style_active
		FROM ' . STYLES_TABLE . '
		WHERE style_id = '. (int) $style_id;
	$result = $db->sql_query($sql);

	$style_is_active = (bool) $db->sql_fetchfield('style_active');
	$db->sql_freeresult($result);

	return $style_is_active;
}

/**
* Remove avatar
*/
function avatar_delete($mode, $row, $clean_db = false)
{
	global $phpbb_root_path, $config, $db, $user;

	// Check if the users avatar is actually *not* a group avatar
	if ($mode == 'user')
	{
		if (strpos($row['user_avatar'], 'g') === 0 || (((int)$row['user_avatar'] !== 0) && ((int)$row['user_avatar'] !== (int)$row['user_id'])))
		{
			return false;
		}
	}

	if ($clean_db)
	{
		avatar_remove_db($row[$mode . '_avatar']);
	}
	$filename = get_avatar_filename($row[$mode . '_avatar']);
	if (file_exists($phpbb_root_path . $config['avatar_path'] . '/' . $filename))
	{
		@unlink($phpbb_root_path . $config['avatar_path'] . '/' . $filename);
		return true;
	}

	return false;
}

/**
* Remote avatar linkage
*/
function avatar_remote($data, &$error)
{
	global $config, $db, $user, $phpbb_root_path, $phpEx;

	if (!preg_match('#^(http|https|ftp)://#i', $data['remotelink']))
	{
		$data['remotelink'] = 'http://' . $data['remotelink'];
	}
	if (!preg_match('#^(http|https|ftp)://(?:(.*?\.)*?[a-z0-9\-]+?\.[a-z]{2,4}|(?:\d{1,3}\.){3,5}\d{1,3}):?([0-9]*?).*?\.(gif|jpg|jpeg|png)$#i', $data['remotelink']))
	{
		$error[] = $user->lang['AVATAR_URL_INVALID'];
		return false;
	}

	// Make sure getimagesize works...
	if (($image_data = @getimagesize($data['remotelink'])) === false && (empty($data['width']) || empty($data['height'])))
	{
		$error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
		return false;
	}

	if (!empty($image_data) && ($image_data[0] < 2 || $image_data[1] < 2))
	{
		$error[] = $user->lang['AVATAR_NO_SIZE'];
		return false;
	}

	$width = ($data['width'] && $data['height']) ? $data['width'] : $image_data[0];
	$height = ($data['width'] && $data['height']) ? $data['height'] : $image_data[1];

	if ($width < 2 || $height < 2)
	{
		$error[] = $user->lang['AVATAR_NO_SIZE'];
		return false;
	}

	// Check image type
	include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
	$types = fileupload::image_types();
	$extension = strtolower(filespec::get_extension($data['remotelink']));

	if (!empty($image_data) && (!isset($types[$image_data[2]]) || !in_array($extension, $types[$image_data[2]])))
	{
		if (!isset($types[$image_data[2]]))
		{
			$error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
		}
		else
		{
			$error[] = sprintf($user->lang['IMAGE_FILETYPE_MISMATCH'], $types[$image_data[2]][0], $extension);
		}
		return false;
	}

	if ($config['avatar_max_width'] || $config['avatar_max_height'])
	{
		if ($width > $config['avatar_max_width'] || $height > $config['avatar_max_height'])
		{
			$error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $width, $height);
			return false;
		}
	}

	if ($config['avatar_min_width'] || $config['avatar_min_height'])
	{
		if ($width < $config['avatar_min_width'] || $height < $config['avatar_min_height'])
		{
			$error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $width, $height);
			return false;
		}
	}

	return array(AVATAR_REMOTE, $data['remotelink'], $width, $height);
}

/**
* Avatar upload using the upload class
*/
function avatar_upload($data, &$error)
{
	global $phpbb_root_path, $config, $db, $user, $phpEx;

	// Init upload class
	include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
	$upload = new fileupload('AVATAR_', array('jpg', 'jpeg', 'gif', 'png'), $config['avatar_filesize'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], (isset($config['mime_triggers']) ? explode('|', $config['mime_triggers']) : false));

	if (!empty($_FILES['uploadfile']['name']))
	{
		$file = $upload->form_upload('uploadfile');
	}
	else
	{
		$file = $upload->remote_upload($data['uploadurl']);
	}

	$prefix = $config['avatar_salt'] . '_';
	$file->clean_filename('avatar', $prefix, $data['user_id']);

	$destination = $config['avatar_path'];

	// Adjust destination path (no trailing slash)
	if (substr($destination, -1, 1) == '/' || substr($destination, -1, 1) == '\\')
	{
		$destination = substr($destination, 0, -1);
	}

	$destination = str_replace(array('../', '..\\', './', '.\\'), '', $destination);
	if ($destination && ($destination[0] == '/' || $destination[0] == "\\"))
	{
		$destination = '';
	}

	// Move file and overwrite any existing image
	$file->move_file($destination, true);

	if (sizeof($file->error))
	{
		$file->remove();
		$error = array_merge($error, $file->error);
	}

	return array(AVATAR_UPLOAD, $data['user_id'] . '_' . time() . '.' . $file->get('extension'), $file->get('width'), $file->get('height'));
}

/**
* Generates avatar filename from the database entry
*/
function get_avatar_filename($avatar_entry)
{
	global $config;


	if ($avatar_entry[0] === 'g')
	{
		$avatar_group = true;
		$avatar_entry = substr($avatar_entry, 1);
	}
	else
	{
		$avatar_group = false;
	}
	$ext 			= substr(strrchr($avatar_entry, '.'), 1);
	$avatar_entry	= intval($avatar_entry);
	return $config['avatar_salt'] . '_' . (($avatar_group) ? 'g' : '') . $avatar_entry . '.' . $ext;
}

/**
* Avatar Gallery
*/
function avatar_gallery($category, $avatar_select, $items_per_column, $block_var = 'avatar_row')
{
	global $user, $cache, $template;
	global $config, $phpbb_root_path;

	$avatar_list = array();

	$path = $phpbb_root_path . $config['avatar_gallery_path'];

	if (!file_exists($path) || !is_dir($path))
	{
		$avatar_list = array($user->lang['NO_AVATAR_CATEGORY'] => array());
	}
	else
	{
		// Collect images
		$dp = @opendir($path);

		if (!$dp)
		{
			return array($user->lang['NO_AVATAR_CATEGORY'] => array());
		}

		while (($file = readdir($dp)) !== false)
		{
			if ($file[0] != '.' && preg_match('#^[^&"\'<>]+$#i', $file) && is_dir("$path/$file"))
			{
				$avatar_row_count = $avatar_col_count = 0;

				if ($dp2 = @opendir("$path/$file"))
				{
					while (($sub_file = readdir($dp2)) !== false)
					{
						if (preg_match('#^[^&\'"<>]+\.(?:gif|png|jpe?g)$#i', $sub_file))
						{
							$avatar_list[$file][$avatar_row_count][$avatar_col_count] = array(
								'file'		=> rawurlencode($file) . '/' . rawurlencode($sub_file),
								'filename'	=> rawurlencode($sub_file),
								'name'		=> ucfirst(str_replace('_', ' ', preg_replace('#^(.*)\..*$#', '\1', $sub_file))),
							);
							$avatar_col_count++;
							if ($avatar_col_count == $items_per_column)
							{
								$avatar_row_count++;
								$avatar_col_count = 0;
							}
						}
					}
					closedir($dp2);
				}
			}
		}
		closedir($dp);
	}

	if (!sizeof($avatar_list))
	{
		$avatar_list = array($user->lang['NO_AVATAR_CATEGORY'] => array());
	}

	@ksort($avatar_list);

	$category = (!$category) ? key($avatar_list) : $category;
	$avatar_categories = array_keys($avatar_list);

	$s_category_options = '';
	foreach ($avatar_categories as $cat)
	{
		$s_category_options .= '<option value="' . $cat . '"' . (($cat == $category) ? ' selected="selected"' : '') . '>' . $cat . '</option>';
	}

	$template->assign_vars(array(
		'S_AVATARS_ENABLED'		=> true,
		'S_IN_AVATAR_GALLERY'	=> true,
		'S_CAT_OPTIONS'			=> $s_category_options)
	);

	$avatar_list = (isset($avatar_list[$category])) ? $avatar_list[$category] : array();

	foreach ($avatar_list as $avatar_row_ary)
	{
		$template->assign_block_vars($block_var, array());

		foreach ($avatar_row_ary as $avatar_col_ary)
		{
			$template->assign_block_vars($block_var . '.avatar_column', array(
				'AVATAR_IMAGE'	=> $phpbb_root_path . $config['avatar_gallery_path'] . '/' . $avatar_col_ary['file'],
				'AVATAR_NAME'	=> $avatar_col_ary['name'],
				'AVATAR_FILE'	=> $avatar_col_ary['filename'])
			);

			$template->assign_block_vars($block_var . '.avatar_option_column', array(
				'AVATAR_IMAGE'	=> $phpbb_root_path . $config['avatar_gallery_path'] . '/' . $avatar_col_ary['file'],
				'S_OPTIONS_AVATAR'	=> $avatar_col_ary['filename'])
			);
		}
	}

	return $avatar_list;
}


/**
* Tries to (re-)establish avatar dimensions
*/
function avatar_get_dimensions($avatar, $avatar_type, &$error, $current_x = 0, $current_y = 0)
{
	global $config, $phpbb_root_path, $user;

	switch ($avatar_type)
	{
		case AVATAR_REMOTE :
			break;

		case AVATAR_UPLOAD :
			$avatar = $phpbb_root_path . $config['avatar_path'] . '/' . get_avatar_filename($avatar);
			break;

		case AVATAR_GALLERY :
			$avatar = $phpbb_root_path . $config['avatar_gallery_path'] . '/' . $avatar ;
			break;
	}

	// Make sure getimagesize works...
	if (($image_data = @getimagesize($avatar)) === false)
	{
		$error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
		return false;
	}

	if ($image_data[0] < 2 || $image_data[1] < 2)
	{
		$error[] = $user->lang['AVATAR_NO_SIZE'];
		return false;
	}

	// try to maintain ratio
	if (!(empty($current_x) && empty($current_y)))
	{
		if ($current_x != 0)
		{
			$image_data[1] = (int) floor(($current_x / $image_data[0]) * $image_data[1]);
			$image_data[1] = min($config['avatar_max_height'], $image_data[1]);
			$image_data[1] = max($config['avatar_min_height'], $image_data[1]);
		}
		if ($current_y != 0)
		{
			$image_data[0] = (int) floor(($current_y / $image_data[1]) * $image_data[0]);
			$image_data[0] = min($config['avatar_max_width'], $image_data[1]);
			$image_data[0] = max($config['avatar_min_width'], $image_data[1]);
		}
	}
	return array($image_data[0], $image_data[1]);
}

/**
* Uploading/Changing user avatar
*/
function avatar_process_user(&$error, $custom_userdata = false, $can_upload = null)
{
	global $config, $phpbb_root_path, $auth, $user, $db;

	$data = array(
		'uploadurl'		=> request_var('uploadurl', ''),
		'remotelink'	=> request_var('remotelink', ''),
		'width'			=> request_var('width', 0),
		'height'		=> request_var('height', 0),
	);

	$error = validate_data($data, array(
		'uploadurl'		=> array('string', true, 5, 255),
		'remotelink'	=> array('string', true, 5, 255),
		'width'			=> array('string', true, 1, 3),
		'height'		=> array('string', true, 1, 3),
	));

	if (sizeof($error))
	{
		return false;
	}

	$sql_ary = array();

	if ($custom_userdata === false)
	{
		$userdata = &$user->data;
	}
	else
	{
		$userdata = &$custom_userdata;
	}

	$data['user_id'] = $userdata['user_id'];
	$change_avatar = ($custom_userdata === false) ? $auth->acl_get('u_chgavatar') : true;
	$avatar_select = basename(request_var('avatar_select', ''));

	// Can we upload?
	if (is_null($can_upload))
	{
		$can_upload = ($config['allow_avatar_upload'] && file_exists($phpbb_root_path . $config['avatar_path']) && phpbb_is_writable($phpbb_root_path . $config['avatar_path']) && $change_avatar && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')) ? true : false;
	}

	if ((!empty($_FILES['uploadfile']['name']) || $data['uploadurl']) && $can_upload)
	{
		list($sql_ary['user_avatar_type'], $sql_ary['user_avatar'], $sql_ary['user_avatar_width'], $sql_ary['user_avatar_height']) = avatar_upload($data, $error);
	}
	else if ($data['remotelink'] && $change_avatar && $config['allow_avatar_remote'])
	{
		list($sql_ary['user_avatar_type'], $sql_ary['user_avatar'], $sql_ary['user_avatar_width'], $sql_ary['user_avatar_height']) = avatar_remote($data, $error);
	}
	else if ($avatar_select && $change_avatar && $config['allow_avatar_local'])
	{
		$category = basename(request_var('category', ''));

		$sql_ary['user_avatar_type'] = AVATAR_GALLERY;
		$sql_ary['user_avatar'] = $avatar_select;

		// check avatar gallery
		if (!is_dir($phpbb_root_path . $config['avatar_gallery_path'] . '/' . $category))
		{
			$sql_ary['user_avatar'] = '';
			$sql_ary['user_avatar_type'] = $sql_ary['user_avatar_width'] = $sql_ary['user_avatar_height'] = 0;
		}
		else
		{
			list($sql_ary['user_avatar_width'], $sql_ary['user_avatar_height']) = getimagesize($phpbb_root_path . $config['avatar_gallery_path'] . '/' . $category . '/' . urldecode($sql_ary['user_avatar']));
			$sql_ary['user_avatar'] = $category . '/' . $sql_ary['user_avatar'];
		}
	}
	else if (isset($_POST['delete']) && $change_avatar)
	{
		$sql_ary['user_avatar'] = '';
		$sql_ary['user_avatar_type'] = $sql_ary['user_avatar_width'] = $sql_ary['user_avatar_height'] = 0;
	}
	else if (!empty($userdata['user_avatar']))
	{
		// Only update the dimensions

		if (empty($data['width']) || empty($data['height']))
		{
			if ($dims = avatar_get_dimensions($userdata['user_avatar'], $userdata['user_avatar_type'], $error, $data['width'], $data['height']))
			{
				list($guessed_x, $guessed_y) = $dims;
				if (empty($data['width']))
				{
					$data['width'] = $guessed_x;
				}
				if (empty($data['height']))
				{
					$data['height'] = $guessed_y;
				}
			}
		}
		if (($config['avatar_max_width'] || $config['avatar_max_height']) &&
			(($data['width'] != $userdata['user_avatar_width']) || $data['height'] != $userdata['user_avatar_height']))
		{
			if ($data['width'] > $config['avatar_max_width'] || $data['height'] > $config['avatar_max_height'])
			{
				$error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $data['width'], $data['height']);
			}
		}

		if (!sizeof($error))
		{
			if ($config['avatar_min_width'] || $config['avatar_min_height'])
			{
				if ($data['width'] < $config['avatar_min_width'] || $data['height'] < $config['avatar_min_height'])
				{
					$error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $data['width'], $data['height']);
				}
			}
		}

		if (!sizeof($error))
		{
			$sql_ary['user_avatar_width'] = $data['width'];
			$sql_ary['user_avatar_height'] = $data['height'];
		}
	}

	if (!sizeof($error))
	{
		// Do we actually have any data to update?
		if (sizeof($sql_ary))
		{
			$ext_new = $ext_old = '';
			if (isset($sql_ary['user_avatar']))
			{
				$userdata = ($custom_userdata === false) ? $user->data : $custom_userdata;
				$ext_new = (empty($sql_ary['user_avatar'])) ? '' : substr(strrchr($sql_ary['user_avatar'], '.'), 1);
				$ext_old = (empty($userdata['user_avatar'])) ? '' : substr(strrchr($userdata['user_avatar'], '.'), 1);

				if ($userdata['user_avatar_type'] == AVATAR_UPLOAD)
				{
					// Delete old avatar if present
					if ((!empty($userdata['user_avatar']) && empty($sql_ary['user_avatar']))
					   || ( !empty($userdata['user_avatar']) && !empty($sql_ary['user_avatar']) && $ext_new !== $ext_old))
					{
						avatar_delete('user', $userdata);
					}
				}
			}

			$sql = 'UPDATE ' . USERS_TABLE . '
				SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
				WHERE user_id = ' . (($custom_userdata === false) ? $user->data['user_id'] : $custom_userdata['user_id']);
			$db->sql_query($sql);

		}
	}

	return (sizeof($error)) ? false : true;
}

//
// Usergroup functions
//

/**
* Add or edit a group. If we're editing a group we only update user
* parameters such as rank, etc. if they are changed
*/
function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow_desc_bbcode = false, $allow_desc_urls = false, $allow_desc_smilies = false)
{
	global $phpbb_root_path, $config, $db, $user, $file_upload;

	$error = array();

	// Attributes which also affect the users table
	$user_attribute_ary = array('group_colour', 'group_rank', 'group_avatar', 'group_avatar_type', 'group_avatar_width', 'group_avatar_height');

	// Check data. Limit group name length.
	if (!utf8_strlen($name) || utf8_strlen($name) > 60)
	{
		$error[] = (!utf8_strlen($name)) ? $user->lang['GROUP_ERR_USERNAME'] : $user->lang['GROUP_ERR_USER_LONG'];
	}

	$err = group_validate_groupname($group_id, $name);
	if (!empty($err))
	{
		$error[] = $user->lang[$err];
	}

	if (!in_array($type, array(GROUP_OPEN, GROUP_CLOSED, GROUP_HIDDEN, GROUP_SPECIAL, GROUP_FREE)))
	{
		$error[] = $user->lang['GROUP_ERR_TYPE'];
	}

	if (!sizeof($error))
	{
		$user_ary = array();
		$sql_ary = array(
			'group_name'			=> (string) $name,
			'group_desc'			=> (string) $desc,
			'group_desc_uid'		=> '',
			'group_desc_bitfield'	=> '',
			'group_type'			=> (int) $type,
		);

		// Parse description
		if ($desc)
		{
			generate_text_for_storage($sql_ary['group_desc'], $sql_ary['group_desc_uid'], $sql_ary['group_desc_bitfield'], $sql_ary['group_desc_options'], $allow_desc_bbcode, $allow_desc_urls, $allow_desc_smilies);
		}

		if (sizeof($group_attributes))
		{
			// Merge them with $sql_ary to properly update the group
			$sql_ary = array_merge($sql_ary, $group_attributes);
		}

		// Setting the log message before we set the group id (if group gets added)
		$log = ($group_id) ? 'LOG_GROUP_UPDATED' : 'LOG_GROUP_CREATED';

		$query = '';

		if ($group_id)
		{
			$sql = 'SELECT user_id
				FROM ' . USERS_TABLE . '
				WHERE group_id = ' . $group_id;
			$result = $db->sql_query($sql);

			while ($row = $db->sql_fetchrow($result))
			{
				$user_ary[] = $row['user_id'];
			}
			$db->sql_freeresult($result);

			if (isset($sql_ary['group_avatar']) && !$sql_ary['group_avatar'])
			{
				remove_default_avatar($group_id, $user_ary);
			}

			if (isset($sql_ary['group_rank']) && !$sql_ary['group_rank'])
			{
				remove_default_rank($group_id, $user_ary);
			}

			$sql = 'UPDATE ' . GROUPS_TABLE . '
				SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
				WHERE group_id = $group_id";
			$db->sql_query($sql);

			// Since we may update the name too, we need to do this on other tables too...
			$sql = 'UPDATE ' . MODERATOR_CACHE_TABLE . "
				SET group_name = '" . $db->sql_escape($sql_ary['group_name']) . "'
				WHERE group_id = $group_id";
			$db->sql_query($sql);

			// One special case is the group skip auth setting. If this was changed we need to purge permissions for this group
			if (isset($group_attributes['group_skip_auth']))
			{
				// Get users within this group...
				$sql = 'SELECT user_id
					FROM ' . USER_GROUP_TABLE . '
					WHERE group_id = ' . $group_id . '
						AND user_pending = 0';
				$result = $db->sql_query($sql);

				$user_id_ary = array();
				while ($row = $db->sql_fetchrow($result))
				{
					$user_id_ary[] = $row['user_id'];
				}
				$db->sql_freeresult($result);

				if (!empty($user_id_ary))
				{
					global $auth;

					// Clear permissions cache of relevant users
					$auth->acl_clear_prefetch($user_id_ary);
				}
			}
		}
		else
		{
			$sql = 'INSERT INTO ' . GROUPS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
			$db->sql_query($sql);
		}

		if (!$group_id)
		{
			$group_id = $db->sql_nextid();

			if (isset($sql_ary['group_avatar_type']) && $sql_ary['group_avatar_type'] == AVATAR_UPLOAD)
			{
				group_correct_avatar($group_id, $sql_ary['group_avatar']);
			}
		}

		// Set user attributes
		$sql_ary = array();
		if (sizeof($group_attributes))
		{
			// Go through the user attributes array, check if a group attribute matches it and then set it. ;)
			foreach ($user_attribute_ary as $attribute)
			{
				if (!isset($group_attributes[$attribute]))
				{
					continue;
				}

				// If we are about to set an avatar, we will not overwrite user avatars if no group avatar is set...
				if (strpos($attribute, 'group_avatar') === 0 && !$group_attributes[$attribute])
				{
					continue;
				}

				$sql_ary[$attribute] = $group_attributes[$attribute];
			}
		}

		if (sizeof($sql_ary) && sizeof($user_ary))
		{
			group_set_user_default($group_id, $user_ary, $sql_ary);
		}

		$name = ($type == GROUP_SPECIAL) ? $user->lang['G_' . $name] : $name;
		add_log('admin', $log, $name);

		group_update_listings($group_id);
	}

	return (sizeof($error)) ? $error : false;
}


/**
* Changes a group avatar's filename to conform to the naming scheme
*/
function group_correct_avatar($group_id, $old_entry)
{
	global $config, $db, $phpbb_root_path;

	$group_id		= (int)$group_id;
	$ext 			= substr(strrchr($old_entry, '.'), 1);
	$old_filename 	= get_avatar_filename($old_entry);
	$new_filename 	= $config['avatar_salt'] . "_g$group_id.$ext";
	$new_entry 		= 'g' . $group_id . '_' . substr(time(), -5) . ".$ext";

	$avatar_path = $phpbb_root_path . $config['avatar_path'];
	if (@rename($avatar_path . '/'. $old_filename, $avatar_path . '/' . $new_filename))
	{
		$sql = 'UPDATE ' . GROUPS_TABLE . '
			SET group_avatar = \'' . $db->sql_escape($new_entry) . "'
			WHERE group_id = $group_id";
		$db->sql_query($sql);
	}
}


/**
* Remove avatar also for users not having the group as default
*/
function avatar_remove_db($avatar_name)
{
	global $config, $db;

	$sql = 'UPDATE ' . USERS_TABLE . "
		SET user_avatar = '',
		user_avatar_type = 0
		WHERE user_avatar = '" . $db->sql_escape($avatar_name) . '\'';
	$db->sql_query($sql);
}


/**
* Group Delete
*/
function group_delete($group_id, $group_name = false)
{
	global $db, $phpbb_root_path, $phpEx;

	if (!$group_name)
	{
		$group_name = get_group_name($group_id);
	}

	$start = 0;

	do
	{
		$user_id_ary = $username_ary = array();

		// Batch query for group members, call group_user_del
		$sql = 'SELECT u.user_id, u.username
			FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . " u
			WHERE ug.group_id = $group_id
				AND u.user_id = ug.user_id";
		$result = $db->sql_query_limit($sql, 200, $start);

		if ($row = $db->sql_fetchrow($result))
		{
			do
			{
				$user_id_ary[] = $row['user_id'];
				$username_ary[] = $row['username'];

				$start++;
			}
			while ($row = $db->sql_fetchrow($result));

			group_user_del($group_id, $user_id_ary, $username_ary, $group_name);
		}
		else
		{
			$start = 0;
		}
		$db->sql_freeresult($result);
	}
	while ($start);

	// Delete group
	$sql = 'DELETE FROM ' . GROUPS_TABLE . "
		WHERE group_id = $group_id";
	$db->sql_query($sql);

	// Delete auth entries from the groups table
	$sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . "
		WHERE group_id = $group_id";
	$db->sql_query($sql);

	// Re-cache moderators
	if (!function_exists('cache_moderators'))
	{
		include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
	}

	cache_moderators();

	add_log('admin', 'LOG_GROUP_DELETE', $group_name);

	// Return false - no error
	return false;
}

/**
* Add user(s) to group
*
* @return mixed false if no errors occurred, else the user lang string for the relevant error, for example 'NO_USER'
*/
function group_user_add($group_id, $user_id_ary = false, $username_ary = false, $group_name = false, $default = false, $leader = 0, $pending = 0, $group_attributes = false)
{
	global $db, $auth;

	// We need both username and user_id info
	$result = user_get_id_name($user_id_ary, $username_ary);

	if (!sizeof($user_id_ary) || $result !== false)
	{
		return 'NO_USER';
	}

	// Remove users who are already members of this group
	$sql = 'SELECT user_id, group_leader
		FROM ' . USER_GROUP_TABLE . '
		WHERE ' . $db->sql_in_set('user_id', $user_id_ary) . "
			AND group_id = $group_id";
	$result = $db->sql_query($sql);

	$add_id_ary = $update_id_ary = array();
	while ($row = $db->sql_fetchrow($result))
	{
		$add_id_ary[] = (int) $row['user_id'];

		if ($leader && !$row['group_leader'])
		{
			$update_id_ary[] = (int) $row['user_id'];
		}
	}
	$db->sql_freeresult($result);

	// Do all the users exist in this group?
	$add_id_ary = array_diff($user_id_ary, $add_id_ary);

	// If we have no users
	if (!sizeof($add_id_ary) && !sizeof($update_id_ary))
	{
		return 'GROUP_USERS_EXIST';
	}

	$db->sql_transaction('begin');

	// Insert the new users
	if (sizeof($add_id_ary))
	{
		$sql_ary = array();

		foreach ($add_id_ary as $user_id)
		{
			$sql_ary[] = array(
				'user_id'		=> (int) $user_id,
				'group_id'		=> (int) $group_id,
				'group_leader'	=> (int) $leader,
				'user_pending'	=> (int) $pending,
			);
		}

		$db->sql_multi_insert(USER_GROUP_TABLE, $sql_ary);
	}

	if (sizeof($update_id_ary))
	{
		$sql = 'UPDATE ' . USER_GROUP_TABLE . '
			SET group_leader = 1
			WHERE ' . $db->sql_in_set('user_id', $update_id_ary) . "
				AND group_id = $group_id";
		$db->sql_query($sql);
	}

	if ($default)
	{
		group_user_attributes('default', $group_id, $user_id_ary, false, $group_name, $group_attributes);
	}

	$db->sql_transaction('commit');

	// Clear permissions cache of relevant users
	$auth->acl_clear_prefetch($user_id_ary);

	if (!$group_name)
	{
		$group_name = get_group_name($group_id);
	}

	$log = ($leader) ? 'LOG_MODS_ADDED' : (($pending) ? 'LOG_USERS_PENDING' : 'LOG_USERS_ADDED');

	add_log('admin', $log, $group_name, implode(', ', $username_ary));

	group_update_listings($group_id);

	// Return false - no error
	return false;
}

/**
* Remove a user/s from a given group. When we remove users we update their
* default group_id. We do this by examining which "special" groups they belong
* to. The selection is made based on a reasonable priority system
*
* @return false if no errors occurred, else the user lang string for the relevant error, for example 'NO_USER'
*/
function group_user_del($group_id, $user_id_ary = false, $username_ary = false, $group_name = false)
{
	global $db, $auth, $config;

	if ($config['coppa_enable'])
	{
		$group_order = array('ADMINISTRATORS', 'GLOBAL_MODERATORS', 'NEWLY_REGISTERED', 'REGISTERED_COPPA', 'REGISTERED', 'BOTS', 'GUESTS');
	}
	else
	{
		$group_order = array('ADMINISTRATORS', 'GLOBAL_MODERATORS', 'NEWLY_REGISTERED', 'REGISTERED', 'BOTS', 'GUESTS');
	}

	// We need both username and user_id info
	$result = user_get_id_name($user_id_ary, $username_ary);

	if (!sizeof($user_id_ary) || $result !== false)
	{
		return 'NO_USER';
	}

	$sql = 'SELECT *
		FROM ' . GROUPS_TABLE . '
		WHERE ' . $db->sql_in_set('group_name', $group_order);
	$result = $db->sql_query($sql);

	$group_order_id = $special_group_data = array();
	while ($row = $db->sql_fetchrow($result))
	{
		$group_order_id[$row['group_name']] = $row['group_id'];

		$special_group_data[$row['group_id']] = array(
			'group_colour'			=> $row['group_colour'],
			'group_rank'				=> $row['group_rank'],
		);

		// Only set the group avatar if one is defined...
		if ($row['group_avatar'])
		{
			$special_group_data[$row['group_id']] = array_merge($special_group_data[$row['group_id']], array(
				'group_avatar'			=> $row['group_avatar'],
				'group_avatar_type'		=> $row['group_avatar_type'],
				'group_avatar_width'		=> $row['group_avatar_width'],
				'group_avatar_height'	=> $row['group_avatar_height'])
			);
		}
	}
	$db->sql_freeresult($result);

	// Get users default groups - we only need to reset default group membership if the group from which the user gets removed is set as default
	$sql = 'SELECT user_id, group_id
		FROM ' . USERS_TABLE . '
		WHERE ' . $db->sql_in_set('user_id', $user_id_ary);
	$result = $db->sql_query($sql);

	$default_groups = array();
	while ($row = $db->sql_fetchrow($result))
	{
		$default_groups[$row['user_id']] = $row['group_id'];
	}
	$db->sql_freeresult($result);

	// What special group memberships exist for these users?
	$sql = 'SELECT g.group_id, g.group_name, ug.user_id
		FROM ' . USER_GROUP_TABLE . ' ug, ' . GROUPS_TABLE . ' g
		WHERE ' . $db->sql_in_set('ug.user_id', $user_id_ary) . "
			AND g.group_id = ug.group_id
			AND g.group_id <> $group_id
			AND g.group_type = " . GROUP_SPECIAL . '
		ORDER BY ug.user_id, g.group_id';
	$result = $db->sql_query($sql);

	$temp_ary = array();
	while ($row = $db->sql_fetchrow($result))
	{
		if ($default_groups[$row['user_id']] == $group_id && (!isset($temp_ary[$row['user_id']]) || $group_order_id[$row['group_name']] < $temp_ary[$row['user_id']]))
		{
			$temp_ary[$row['user_id']] = $row['group_id'];
		}
	}
	$db->sql_freeresult($result);

	// sql_where_ary holds the new default groups and their users
	$sql_where_ary = array();
	foreach ($temp_ary as $uid => $gid)
	{
		$sql_where_ary[$gid][] = $uid;
	}
	unset($temp_ary);

	foreach ($special_group_data as $gid => $default_data_ary)
	{
		if (isset($sql_where_ary[$gid]) && sizeof($sql_where_ary[$gid]))
		{
			remove_default_rank($group_id, $sql_where_ary[$gid]);
			remove_default_avatar($group_id, $sql_where_ary[$gid]);
			group_set_user_default($gid, $sql_where_ary[$gid], $default_data_ary);
		}
	}
	unset($special_group_data);

	$sql = 'DELETE FROM ' . USER_GROUP_TABLE . "
		WHERE group_id = $group_id
			AND " . $db->sql_in_set('user_id', $user_id_ary);
	$db->sql_query($sql);

	// Clear permissions cache of relevant users
	$auth->acl_clear_prefetch($user_id_ary);

	if (!$group_name)
	{
		$group_name = get_group_name($group_id);
	}

	$log = 'LOG_GROUP_REMOVE';

	if ($group_name)
	{
		add_log('admin', $log, $group_name, implode(', ', $username_ary));
	}

	group_update_listings($group_id);

	// Return false - no error
	return false;
}


/**
* Removes the group avatar of the default group from the users in user_ids who have that group as default.
*/
function remove_default_avatar($group_id, $user_ids)
{
	global $db;

	if (!is_array($user_ids))
	{
		$user_ids = array($user_ids);
	}
	if (empty($user_ids))
	{
		return false;
	}

	$user_ids = array_map('intval', $user_ids);

	$sql = 'SELECT *
		FROM ' . GROUPS_TABLE . '
		WHERE group_id = ' . (int)$group_id;
	$result = $db->sql_query($sql);
	if (!$row = $db->sql_fetchrow($result))
	{
		$db->sql_freeresult($result);
		return false;
	}
	$db->sql_freeresult($result);

	$sql = 'UPDATE ' . USERS_TABLE . "
		SET user_avatar = '',
			user_avatar_type = 0,
			user_avatar_width = 0,
			user_avatar_height = 0
		WHERE group_id = " . (int) $group_id . "
		AND user_avatar = '" . $db->sql_escape($row['group_avatar']) . "'
		AND " . $db->sql_in_set('user_id', $user_ids);

	$db->sql_query($sql);
}

/**
* Removes the group rank of the default group from the users in user_ids who have that group as default.
*/
function remove_default_rank($group_id, $user_ids)
{
	global $db;

	if (!is_array($user_ids))
	{
		$user_ids = array($user_ids);
	}
	if (empty($user_ids))
	{
		return false;
	}

	$user_ids = array_map('intval', $user_ids);

	$sql = 'SELECT *
		FROM ' . GROUPS_TABLE . '
		WHERE group_id = ' . (int)$group_id;
	$result = $db->sql_query($sql);
	if (!$row = $db->sql_fetchrow($result))
	{
		$db->sql_freeresult($result);
		return false;
	}
	$db->sql_freeresult($result);

	$sql = 'UPDATE ' . USERS_TABLE . '
		SET user_rank = 0
		WHERE group_id = ' . (int)$group_id . '
		AND user_rank <> 0
		AND user_rank = ' . (int)$row['group_rank'] . '
		AND ' . $db->sql_in_set('user_id', $user_ids);
	$db->sql_query($sql);
}

/**
* This is used to promote (to leader), demote or set as default a member/s
*/
function group_user_attributes($action, $group_id, $user_id_ary = false, $username_ary = false, $group_name = false, $group_attributes = false)
{
	global $db, $auth, $phpbb_root_path, $phpEx, $config;

	// We need both username and user_id info
	$result = user_get_id_name($user_id_ary, $username_ary);

	if (!sizeof($user_id_ary) || $result !== false)
	{
		return 'NO_USERS';
	}

	if (!$group_name)
	{
		$group_name = get_group_name($group_id);
	}

	switch ($action)
	{
		case 'demote':
		case 'promote':

			$sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . "
				WHERE group_id = $group_id
					AND user_pending = 1
					AND " . $db->sql_in_set('user_id', $user_id_ary);
			$result = $db->sql_query_limit($sql, 1);
			$not_empty = ($db->sql_fetchrow($result));
			$db->sql_freeresult($result);
			if ($not_empty)
			{
				return 'NO_VALID_USERS';
			}

			$sql = 'UPDATE ' . USER_GROUP_TABLE . '
				SET group_leader = ' . (($action == 'promote') ? 1 : 0) . "
				WHERE group_id = $group_id
					AND user_pending = 0
					AND " . $db->sql_in_set('user_id', $user_id_ary);
			$db->sql_query($sql);

			$log = ($action == 'promote') ? 'LOG_GROUP_PROMOTED' : 'LOG_GROUP_DEMOTED';
		break;

		case 'approve':
			// Make sure we only approve those which are pending ;)
			$sql = 'SELECT u.user_id, u.user_email, u.username, u.username_clean, u.user_notify_type, u.user_jabber, u.user_lang
				FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . ' ug
				WHERE ug.group_id = ' . $group_id . '
					AND ug.user_pending = 1
					AND ug.user_id = u.user_id
					AND ' . $db->sql_in_set('ug.user_id', $user_id_ary);
			$result = $db->sql_query($sql);

			$user_id_ary = $email_users = array();
			while ($row = $db->sql_fetchrow($result))
			{
				$user_id_ary[] = $row['user_id'];
				$email_users[] = $row;
			}
			$db->sql_freeresult($result);

			if (!sizeof($user_id_ary))
			{
				return false;
			}

			$sql = 'UPDATE ' . USER_GROUP_TABLE . "
				SET user_pending = 0
				WHERE group_id = $group_id
					AND " . $db->sql_in_set('user_id', $user_id_ary);
			$db->sql_query($sql);

			// Send approved email to users...
			include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
			$messenger = new messenger();

			foreach ($email_users as $row)
			{
				$messenger->template('group_approved', $row['user_lang']);

				$messenger->to($row['user_email'], $row['username']);
				$messenger->im($row['user_jabber'], $row['username']);

				$messenger->assign_vars(array(
					'USERNAME'		=> htmlspecialchars_decode($row['username']),
					'GROUP_NAME'	=> htmlspecialchars_decode($group_name),
					'U_GROUP'		=> generate_board_url() . "/ucp.$phpEx?i=groups&mode=membership")
				);

				$messenger->send($row['user_notify_type']);
			}

			$messenger->save_queue();

			$log = 'LOG_USERS_APPROVED';
		break;

		case 'default':
			// We only set default group for approved members of the group
			$sql = 'SELECT user_id
				FROM ' . USER_GROUP_TABLE . "
				WHERE group_id = $group_id
					AND user_pending = 0
					AND " . $db->sql_in_set('user_id', $user_id_ary);
			$result = $db->sql_query($sql);

			$user_id_ary = $username_ary = array();
			while ($row = $db->sql_fetchrow($result))
			{
				$user_id_ary[] = $row['user_id'];
			}
			$db->sql_freeresult($result);

			$result = user_get_id_name($user_id_ary, $username_ary);
			if (!sizeof($user_id_ary) || $result !== false)
			{
				return 'NO_USERS';
			}

			$sql = 'SELECT user_id, group_id FROM ' . USERS_TABLE . '
				WHERE ' . $db->sql_in_set('user_id', $user_id_ary, false, true);
			$result = $db->sql_query($sql);

			$groups = array();
			while ($row = $db->sql_fetchrow($result))
			{
				if (!isset($groups[$row['group_id']]))
				{
					$groups[$row['group_id']] = array();
				}
				$groups[$row['group_id']][] = $row['user_id'];
			}
			$db->sql_freeresult($result);

			foreach ($groups as $gid => $uids)
			{
				remove_default_rank($gid, $uids);
				remove_default_avatar($gid, $uids);
			}
			group_set_user_default($group_id, $user_id_ary, $group_attributes);
			$log = 'LOG_GROUP_DEFAULTS';
		break;
	}

	// Clear permissions cache of relevant users
	$auth->acl_clear_prefetch($user_id_ary);

	add_log('admin', $log, $group_name, implode(', ', $username_ary));

	group_update_listings($group_id);

	return false;
}

/**
* A small version of validate_username to check for a group name's existence. To be called directly.
*/
function group_validate_groupname($group_id, $group_name)
{
	global $config, $db;

	$group_name =  utf8_clean_string($group_name);

	if (!empty($group_id))
	{
		$sql = 'SELECT group_name
			FROM ' . GROUPS_TABLE . '
			WHERE group_id = ' . (int) $group_id;
		$result = $db->sql_query($sql);
		$row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

		if (!$row)
		{
			return false;
		}

		$allowed_groupname = utf8_clean_string($row['group_name']);

		if ($allowed_groupname == $group_name)
		{
			return false;
		}
	}

	$sql = 'SELECT group_name
		FROM ' . GROUPS_TABLE . "
		WHERE LOWER(group_name) = '" . $db->sql_escape(utf8_strtolower($group_name)) . "'";
	$result = $db->sql_query($sql);
	$row = $db->sql_fetchrow($result);
	$db->sql_freeresult($result);

	if ($row)
	{
		return 'GROUP_NAME_TAKEN';
	}

	return false;
}

/**
* Set users default group
*
* @access private
*/
function group_set_user_default($group_id, $user_id_ary, $group_attributes = false, $update_listing = false)
{
	global $cache, $db;

	if (empty($user_id_ary))
	{
		return;
	}

	$attribute_ary = array(
		'group_colour'			=> 'string',
		'group_rank'			=> 'int',
		'group_avatar'			=> 'string',
		'group_avatar_type'		=> 'int',
		'group_avatar_width'	=> 'int',
		'group_avatar_height'	=> 'int',
	);

	$sql_ary = array(
		'group_id'		=> $group_id
	);

	// Were group attributes passed to the function? If not we need to obtain them
	if ($group_attributes === false)
	{
		$sql = 'SELECT ' . implode(', ', array_keys($attribute_ary)) . '
			FROM ' . GROUPS_TABLE . "
			WHERE group_id = $group_id";
		$result = $db->sql_query($sql);
		$group_attributes = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);
	}

	foreach ($attribute_ary as $attribute => $type)
	{
		if (isset($group_attributes[$attribute]))
		{
			// If we are about to set an avatar or rank, we will not overwrite with empty, unless we are not actually changing the default group
			if ((strpos($attribute, 'group_avatar') === 0 || strpos($attribute, 'group_rank') === 0) && !$group_attributes[$attribute])
			{
				continue;
			}

			settype($group_attributes[$attribute], $type);
			$sql_ary[str_replace('group_', 'user_', $attribute)] = $group_attributes[$attribute];
		}
	}

	// Before we update the user attributes, we will make a list of those having now the group avatar assigned
	if (isset($sql_ary['user_avatar']))
	{
		// Ok, get the original avatar data from users having an uploaded one (we need to remove these from the filesystem)
		$sql = 'SELECT user_id, group_id, user_avatar
			FROM ' . USERS_TABLE . '
			WHERE ' . $db->sql_in_set('user_id', $user_id_ary) . '
				AND user_avatar_type = ' . AVATAR_UPLOAD;
		$result = $db->sql_query($sql);

		while ($row = $db->sql_fetchrow($result))
		{
			avatar_delete('user', $row);
		}
		$db->sql_freeresult($result);
	}
	else
	{
		unset($sql_ary['user_avatar_type']);
		unset($sql_ary['user_avatar_height']);
		unset($sql_ary['user_avatar_width']);
	}

	$sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
		WHERE ' . $db->sql_in_set('user_id', $user_id_ary);
	$db->sql_query($sql);

	if (isset($sql_ary['user_colour']))
	{
		// Update any cached colour information for these users
		$sql = 'UPDATE ' . FORUMS_TABLE . " SET forum_last_poster_colour = '" . $db->sql_escape($sql_ary['user_colour']) . "'
			WHERE " . $db->sql_in_set('forum_last_poster_id', $user_id_ary);
		$db->sql_query($sql);

		$sql = 'UPDATE ' . TOPICS_TABLE . " SET topic_first_poster_colour = '" . $db->sql_escape($sql_ary['user_colour']) . "'
			WHERE " . $db->sql_in_set('topic_poster', $user_id_ary);
		$db->sql_query($sql);

		$sql = 'UPDATE ' . TOPICS_TABLE . " SET topic_last_poster_colour = '" . $db->sql_escape($sql_ary['user_colour']) . "'
			WHERE " . $db->sql_in_set('topic_last_poster_id', $user_id_ary);
		$db->sql_query($sql);

		global $config;

		if (in_array($config['newest_user_id'], $user_id_ary))
		{
			set_config('newest_user_colour', $sql_ary['user_colour'], true);
		}
	}

	if ($update_listing)
	{
		group_update_listings($group_id);
	}

	// Because some tables/caches use usercolour-specific data we need to purge this here.
	$cache->destroy('sql', MODERATOR_CACHE_TABLE);
}

/**
* Get group name
*/
function get_group_name($group_id)
{
	global $db, $user;

	$sql = 'SELECT group_name, group_type
		FROM ' . GROUPS_TABLE . '
		WHERE group_id = ' . (int) $group_id;
	$result = $db->sql_query($sql);
	$row = $db->sql_fetchrow($result);
	$db->sql_freeresult($result);

	if (!$row || ($row['group_type'] == GROUP_SPECIAL && empty($user->lang)))
	{
		return '';
	}

	return ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
}

/**
* Obtain either the members of a specified group, the groups the specified user is subscribed to
* or checking if a specified user is in a specified group. This function does not return pending memberships.
*
* Note: Never use this more than once... first group your users/groups
*/
function group_memberships($group_id_ary = false, $user_id_ary = false, $return_bool = false)
{
	global $db;

	if (!$group_id_ary && !$user_id_ary)
	{
		return true;
	}

	if ($user_id_ary)
	{
		$user_id_ary = (!is_array($user_id_ary)) ? array($user_id_ary) : $user_id_ary;
	}

	if ($group_id_ary)
	{
		$group_id_ary = (!is_array($group_id_ary)) ? array($group_id_ary) : $group_id_ary;
	}

	$sql = 'SELECT ug.*, u.username, u.username_clean, u.user_email
		FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . ' u
		WHERE ug.user_id = u.user_id
			AND ug.user_pending = 0 AND ';

	if ($group_id_ary)
	{
		$sql .= ' ' . $db->sql_in_set('ug.group_id', $group_id_ary);
	}

	if ($user_id_ary)
	{
		$sql .= ($group_id_ary) ? ' AND ' : ' ';
		$sql .= $db->sql_in_set('ug.user_id', $user_id_ary);
	}

	$result = ($return_bool) ? $db->sql_query_limit($sql, 1) : $db->sql_query($sql);

	$row = $db->sql_fetchrow($result);

	if ($return_bool)
	{
		$db->sql_freeresult($result);
		return ($row) ? true : false;
	}

	if (!$row)
	{
		return false;
	}

	$return = array();

	do
	{
		$return[] = $row;
	}
	while ($row = $db->sql_fetchrow($result));

	$db->sql_freeresult($result);

	return $return;
}

/**
* Re-cache moderators and foes if group has a_ or m_ permissions
*/
function group_update_listings($group_id)
{
	global $auth;

	$hold_ary = $auth->acl_group_raw_data($group_id, array('a_', 'm_'));

	if (!sizeof($hold_ary))
	{
		return;
	}

	$mod_permissions = $admin_permissions = false;

	foreach ($hold_ary as $g_id => $forum_ary)
	{
		foreach ($forum_ary as $forum_id => $auth_ary)
		{
			foreach ($auth_ary as $auth_option => $setting)
			{
				if ($mod_permissions && $admin_permissions)
				{
					break 3;
				}

				if ($setting != ACL_YES)
				{
					continue;
				}

				if ($auth_option == 'm_')
				{
					$mod_permissions = true;
				}

				if ($auth_option == 'a_')
				{
					$admin_permissions = true;
				}
			}
		}
	}

	if ($mod_permissions)
	{
		if (!function_exists('cache_moderators'))
		{
			global $phpbb_root_path, $phpEx;
			include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
		}
		cache_moderators();
	}

	if ($mod_permissions || $admin_permissions)
	{
		if (!function_exists('update_foes'))
		{
			global $phpbb_root_path, $phpEx;
			include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
		}
		update_foes(array($group_id));
	}
}



/**
* Funtion to make a user leave the NEWLY_REGISTERED system group.
* @access public
* @param $user_id The id of the user to remove from the group
*/
function remove_newly_registered($user_id, $user_data = false)
{
	global $db;

	if ($user_data === false)
	{
		$sql = 'SELECT *
			FROM ' . USERS_TABLE . '
			WHERE user_id = ' . $user_id;
		$result = $db->sql_query($sql);
		$user_row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

		if (!$user_row)
		{
			return false;
		}
		else
		{
			$user_data  = $user_row;
		}
	}

	if (empty($user_data['user_new']))
	{
		return false;
	}

	$sql = 'SELECT group_id
		FROM ' . GROUPS_TABLE . "
		WHERE group_name = 'NEWLY_REGISTERED'
			AND group_type = " . GROUP_SPECIAL;
	$result = $db->sql_query($sql);
	$group_id = (int) $db->sql_fetchfield('group_id');
	$db->sql_freeresult($result);

	if (!$group_id)
	{
		return false;
	}

	// We need to call group_user_del here, because this function makes sure everything is correctly changed.
	// A downside for a call within the session handler is that the language is not set up yet - so no log entry
	group_user_del($group_id, $user_id);

	// Set user_new to 0 to let this not be triggered again
	$sql = 'UPDATE ' . USERS_TABLE . '
		SET user_new = 0
		WHERE user_id = ' . $user_id;
	$db->sql_query($sql);

	// The new users group was the users default group?
	if ($user_data['group_id'] == $group_id)
	{
		// Which group is now the users default one?
		$sql = 'SELECT group_id
			FROM ' . USERS_TABLE . '
			WHERE user_id = ' . $user_id;
		$result = $db->sql_query($sql);
		$user_data['group_id'] = $db->sql_fetchfield('group_id');
		$db->sql_freeresult($result);
	}

	return $user_data['group_id'];
}

/**
* Gets user ids of currently banned registered users.
*
* @param array $user_ids Array of users' ids to check for banning,
*						leave empty to get complete list of banned ids
* @return array	Array of banned users' ids if any, empty array otherwise
*/
function phpbb_get_banned_user_ids($user_ids = array())
{
	global $db;

	$sql_user_ids = (!empty($user_ids)) ? $db->sql_in_set('ban_userid', $user_ids) : 'ban_userid <> 0';

	// Get banned User ID's
	// Ignore stale bans which were not wiped yet
	$banned_ids_list = array();
	$sql = 'SELECT ban_userid
		FROM ' . BANLIST_TABLE . "
		WHERE $sql_user_ids
			AND ban_exclude <> 1
			AND (ban_end > " . time() . '
				OR ban_end = 0)';
	$result = $db->sql_query($sql);
	while ($row = $db->sql_fetchrow($result))
	{
		$user_id = (int) $row['ban_userid'];
		$banned_ids_list[$user_id] = $user_id;
	}
	$db->sql_freeresult($result);

	return $banned_ids_list;
}

?>
Attachments
functions_user.txt
(108.06 KiB) Downloaded 9 times
User avatar
stevemaury
Support Team Member
Support Team Member
Posts: 52768
Joined: Thu Nov 02, 2006 12:21 am
Location: The U.P.
Name: Steve
Contact:

Re: Guest posting doesnt work?

Post by stevemaury »

OK, now posting.php, please.
I can stop all your spam. I can upgrade or update your Board. PM or email me. (Paid support)
AbbeyG
Registered User
Posts: 88
Joined: Fri Feb 08, 2013 7:14 pm

Re: Guest posting doesnt work?

Post by AbbeyG »

Posting.php

Code: Select all

<?php
/**
*
* @package phpBB3
* @version $Id$
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

/**
* @ignore
*/
define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
include($phpbb_root_path . 'includes/message_parser.' . $phpEx);


// Start session management
$user->session_begin();
$auth->acl($user->data);


// Grab only parameters needed here
$post_id	= request_var('p', 0);
$topic_id	= request_var('t', 0);
$forum_id	= request_var('f', 0);
$draft_id	= request_var('d', 0);
$lastclick	= request_var('lastclick', 0);

$submit		= (isset($_POST['post'])) ? true : false;
$preview	= (isset($_POST['preview'])) ? true : false;
$save		= (isset($_POST['save'])) ? true : false;
$load		= (isset($_POST['load'])) ? true : false;
$delete		= (isset($_POST['delete'])) ? true : false;
$cancel		= (isset($_POST['cancel']) && !isset($_POST['save'])) ? true : false;

$refresh	= (isset($_POST['add_file']) || isset($_POST['delete_file']) || isset($_POST['full_editor']) || isset($_POST['cancel_unglobalise'])|| isset($_POST['prefix_add']) || isset($_POST['prefix_remove']) || isset($_POST['prefix_clear']) || $save || $load) ? true : false;
$mode		= ($delete && !$preview && !$refresh && $submit) ? 'delete' : request_var('mode', '');

$error = $post_data = array();
$current_time = time();

// Was cancel pressed? If so then redirect to the appropriate page
if ($cancel || ($current_time - $lastclick < 2 && $submit))
{
	$f = ($forum_id) ? 'f=' . $forum_id . '&' : '';
	$redirect = ($post_id) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", $f . 'p=' . $post_id) . '#p' . $post_id : (($topic_id) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", $f . 't=' . $topic_id) : (($forum_id) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) : append_sid("{$phpbb_root_path}index.$phpEx")));
	redirect($redirect);
}

if (in_array($mode, array('post', 'reply', 'quote', 'edit', 'delete')) && !$forum_id)
{
	trigger_error('NO_FORUM');
}

// We need to know some basic information in all cases before we do anything.
switch ($mode)
{
	case 'post':
		$sql = 'SELECT *
			FROM ' . FORUMS_TABLE . "
			WHERE forum_id = $forum_id";
	break;

	case 'bump':
	case 'reply':
		if (!$topic_id)
		{
			trigger_error('NO_TOPIC');
		}

		// Force forum id
		$sql = 'SELECT forum_id
			FROM ' . TOPICS_TABLE . '
			WHERE topic_id = ' . $topic_id;
		$result = $db->sql_query($sql);
		$f_id = (int) $db->sql_fetchfield('forum_id');
		$db->sql_freeresult($result);

		$forum_id = (!$f_id) ? $forum_id : $f_id;

		$sql = 'SELECT f.*, t.*
			FROM ' . TOPICS_TABLE . ' t, ' . FORUMS_TABLE . " f
			WHERE t.topic_id = $topic_id
				AND (f.forum_id = t.forum_id
					OR f.forum_id = $forum_id)" .
			(($auth->acl_get('m_approve', $forum_id)) ? '' : 'AND t.topic_approved = 1');
	break;

	case 'quote':
	case 'edit':
	case 'delete':
		if (!$post_id)
		{
			$user->setup('posting');
			trigger_error('NO_POST');
		}

		// Force forum id
		$sql = 'SELECT forum_id
			FROM ' . POSTS_TABLE . '
			WHERE post_id = ' . $post_id;
		$result = $db->sql_query($sql);
		$f_id = (int) $db->sql_fetchfield('forum_id');
		$db->sql_freeresult($result);

		$forum_id = (!$f_id) ? $forum_id : $f_id;

		$sql = 'SELECT f.*, t.*, p.*, u.username, u.username_clean, u.user_sig, u.user_sig_bbcode_uid, u.user_sig_bbcode_bitfield
			FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t, ' . FORUMS_TABLE . ' f, ' . USERS_TABLE . " u
			WHERE p.post_id = $post_id
				AND t.topic_id = p.topic_id
				AND u.user_id = p.poster_id
				AND (f.forum_id = t.forum_id
					OR f.forum_id = $forum_id)" .
				(($auth->acl_get('m_approve', $forum_id)) ? '' : 'AND p.post_approved = 1');
	break;

	case 'smilies':
		$sql = '';
		if ( request_var('announce', 0) == ACP_ANNOUNCE_TRUE )
		{
			generate_smilies('window', 0, ACP_ANNOUNCE_TRUE);
		}
		else
		{
			generate_smilies('window', $forum_id);
		}
	break;

	case 'popup':
		if ($forum_id)
		{
			$sql = 'SELECT forum_style
				FROM ' . FORUMS_TABLE . '
				WHERE forum_id = ' . $forum_id;
		}
		else
		{
			upload_popup();
			return;
		}
	break;

	default:
		$sql = '';
	break;
}

if (!$sql)
{
	$user->setup('posting');
	trigger_error('NO_POST_MODE');
}

$result = $db->sql_query($sql);
$post_data = $db->sql_fetchrow($result);
$db->sql_freeresult($result);

if (!$post_data)
{
	if (!($mode == 'post' || $mode == 'bump' || $mode == 'reply'))
	{
		$user->setup('posting');
	}
	trigger_error(($mode == 'post' || $mode == 'bump' || $mode == 'reply') ? 'NO_TOPIC' : 'NO_POST');
}

// Not able to reply to unapproved posts/topics
// TODO: add more descriptive language key
if ($auth->acl_get('m_approve', $forum_id) && ((($mode == 'reply' || $mode == 'bump') && !$post_data['topic_approved']) || ($mode == 'quote' && !$post_data['post_approved'])))
{
	trigger_error(($mode == 'reply' || $mode == 'bump') ? 'TOPIC_UNAPPROVED' : 'POST_UNAPPROVED');
}

if ($mode == 'popup')
{
	upload_popup($post_data['forum_style']);
	return;
}

$user->setup(array('posting', 'mcp', 'viewtopic'), $post_data['forum_style']);

if ($config['enable_post_confirm'] && !$user->data['is_registered'])
{
	include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
	$captcha =& phpbb_captcha_factory::get_instance($config['captcha_plugin']);
	$captcha->init(CONFIRM_POST);
}

// Use post_row values in favor of submitted ones...
$forum_id	= (!empty($post_data['forum_id'])) ? (int) $post_data['forum_id'] : (int) $forum_id;
$topic_id	= (!empty($post_data['topic_id'])) ? (int) $post_data['topic_id'] : (int) $topic_id;
$post_id	= (!empty($post_data['post_id'])) ? (int) $post_data['post_id'] : (int) $post_id;

// Need to login to passworded forum first?
if ($post_data['forum_password'])
{
	login_forum_box(array(
		'forum_id'			=> $forum_id,
		'forum_password'	=> $post_data['forum_password'])
	);
}

// Check permissions
if ($user->data['is_bot'])
{
	redirect(append_sid("{$phpbb_root_path}index.$phpEx"));
}

// Is the user able to read within this forum?
if (!$auth->acl_get('f_read', $forum_id))
{
	if ($user->data['user_id'] != ANONYMOUS)
	{
		trigger_error('USER_CANNOT_READ');
	}

	login_box('', $user->lang['LOGIN_EXPLAIN_POST']);
}

// Permission to do the action asked?
$is_authed = false;

switch ($mode)
{
	case 'post':
		if ($auth->acl_get('f_post', $forum_id))
		{
			$is_authed = true;
		}
	break;

	case 'bump':
		if ($auth->acl_get('f_bump', $forum_id))
		{
			$is_authed = true;
		}
	break;

	case 'quote':

		$post_data['post_edit_locked'] = 0;

	// no break;

	case 'reply':
		if ($auth->acl_get('f_reply', $forum_id))
		{
			$is_authed = true;
		}
	break;

	case 'edit':
		if ($user->data['is_registered'] && $auth->acl_gets('f_edit', 'm_edit', $forum_id))
		{
			$is_authed = true;
		}
	break;

	case 'delete':
		if ($user->data['is_registered'] && $auth->acl_gets('f_delete', 'm_delete', $forum_id))
		{
			$is_authed = true;
		}
	break;
}

if (!$is_authed)
{
	$check_auth = ($mode == 'quote') ? 'reply' : $mode;

	if ($user->data['is_registered'])
	{
		trigger_error('USER_CANNOT_' . strtoupper($check_auth));
	}

	login_box('', $user->lang['LOGIN_EXPLAIN_' . strtoupper($mode)]);
}

// Is the user able to post within this forum?
if ($post_data['forum_type'] != FORUM_POST && in_array($mode, array('post', 'bump', 'quote', 'reply')))
{
	trigger_error('USER_CANNOT_FORUM_POST');
}

// Forum/Topic locked?
if (($post_data['forum_status'] == ITEM_LOCKED || (isset($post_data['topic_status']) && $post_data['topic_status'] == ITEM_LOCKED)) && !$auth->acl_get('m_edit', $forum_id))
{
	trigger_error(($post_data['forum_status'] == ITEM_LOCKED) ? 'FORUM_LOCKED' : 'TOPIC_LOCKED');
}

// Can we edit this post ... if we're a moderator with rights then always yes
// else it depends on editing times, lock status and if we're the correct user
if ($mode == 'edit' && !$auth->acl_get('m_edit', $forum_id))
{
	if ($user->data['user_id'] != $post_data['poster_id'])
	{
		trigger_error('USER_CANNOT_EDIT');
	}

	if (!($post_data['post_time'] > time() - ($config['edit_time'] * 60) || !$config['edit_time']))
	{
		trigger_error('CANNOT_EDIT_TIME');
	}

	if ($post_data['post_edit_locked'])
	{
		trigger_error('CANNOT_EDIT_POST_LOCKED');
	}
}

// Handle delete mode...
if ($mode == 'delete')
{
	handle_post_delete($forum_id, $topic_id, $post_id, $post_data);
	return;
}

// Handle bump mode...
if ($mode == 'bump')
{
	if ($bump_time = bump_topic_allowed($forum_id, $post_data['topic_bumped'], $post_data['topic_last_post_time'], $post_data['topic_poster'], $post_data['topic_last_poster_id'])
	   && check_link_hash(request_var('hash', ''), "topic_{$post_data['topic_id']}"))
	{
		$meta_url = phpbb_bump_topic($forum_id, $topic_id, $post_data, $current_time);
		meta_refresh(3, $meta_url);

		$message = $user->lang['TOPIC_BUMPED'] . '<br /><br />' . sprintf($user->lang['VIEW_MESSAGE'], '<a href="' . $meta_url . '">', '</a>');
		$message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>');

		trigger_error($message);
	}

	trigger_error('BUMP_ERROR');
}

// Subject length limiting to 60 characters if first post...
if ($mode == 'post' || ($mode == 'edit' && $post_data['topic_first_post_id'] == $post_data['post_id']))
{
	$template->assign_var('S_NEW_MESSAGE', true);
}

// Determine some vars
if (isset($post_data['poster_id']) && $post_data['poster_id'] == ANONYMOUS)
{
	$post_data['quote_username'] = (!empty($post_data['post_username'])) ? $post_data['post_username'] : $user->lang['GUEST'];
}
else
{
	$post_data['quote_username'] = isset($post_data['username']) ? $post_data['username'] : '';
}

$post_data['post_edit_locked']	= (isset($post_data['post_edit_locked'])) ? (int) $post_data['post_edit_locked'] : 0;
$post_data['post_subject_md5']	= (isset($post_data['post_subject']) && $mode == 'edit') ? md5($post_data['post_subject']) : '';
$post_data['post_subject']		= (in_array($mode, array('quote', 'edit'))) ? $post_data['post_subject'] : ((isset($post_data['topic_title'])) ? $post_data['topic_title'] : '');
$post_data['topic_time_limit']	= (isset($post_data['topic_time_limit'])) ? (($post_data['topic_time_limit']) ? (int) $post_data['topic_time_limit'] / 86400 : (int) $post_data['topic_time_limit']) : 0;
$post_data['poll_length']		= (!empty($post_data['poll_length'])) ? (int) $post_data['poll_length'] / 86400 : 0;
$post_data['poll_start']		= (!empty($post_data['poll_start'])) ? (int) $post_data['poll_start'] : 0;
$post_data['icon_id']			= (!isset($post_data['icon_id']) || in_array($mode, array('quote', 'reply'))) ? 0 : (int) $post_data['icon_id'];
$post_data['poll_options']		= array();

// Get Poll Data
if ($post_data['poll_start'])
{
	$sql = 'SELECT poll_option_text
		FROM ' . POLL_OPTIONS_TABLE . "
		WHERE topic_id = $topic_id
		ORDER BY poll_option_id";
	$result = $db->sql_query($sql);

	while ($row = $db->sql_fetchrow($result))
	{
		$post_data['poll_options'][] = trim($row['poll_option_text']);
	}
	$db->sql_freeresult($result);
}

if ($mode == 'edit')
{
	$original_poll_data = array(
		'poll_title'		=> $post_data['poll_title'],
		'poll_length'		=> $post_data['poll_length'],
		'poll_max_options'	=> $post_data['poll_max_options'],
		'poll_option_text'	=> implode("\n", $post_data['poll_options']),
		'poll_start'		=> $post_data['poll_start'],
		'poll_last_vote'	=> $post_data['poll_last_vote'],
		'poll_vote_change'	=> $post_data['poll_vote_change'],
	);
}

$orig_poll_options_size = sizeof($post_data['poll_options']);

$message_parser = new parse_message();

if (isset($post_data['post_text']))
{
	$message_parser->message = &$post_data['post_text'];
	unset($post_data['post_text']);
}

// Set some default variables
$uninit = array('post_attachment' => 0, 'poster_id' => $user->data['user_id'], 'enable_magic_url' => 0, 'topic_status' => 0, 'topic_type' => POST_NORMAL, 'post_subject' => '', 'topic_title' => '', 'post_time' => 0, 'post_edit_reason' => '', 'notify_set' => 0);

foreach ($uninit as $var_name => $default_value)
{
	if (!isset($post_data[$var_name]))
	{
		$post_data[$var_name] = $default_value;
	}
}
unset($uninit);

// Always check if the submitted attachment data is valid and belongs to the user.
// Further down (especially in submit_post()) we do not check this again.
$message_parser->get_submitted_attachment_data($post_data['poster_id']);

if ($post_data['post_attachment'] && !$submit && !$refresh && !$preview && $mode == 'edit')
{
	// Do not change to SELECT *
	$sql = 'SELECT attach_id, is_orphan, attach_comment, real_filename
		FROM ' . ATTACHMENTS_TABLE . "
		WHERE post_msg_id = $post_id
			AND in_message = 0
			AND is_orphan = 0
		ORDER BY filetime DESC";
	$result = $db->sql_query($sql);
	$message_parser->attachment_data = array_merge($message_parser->attachment_data, $db->sql_fetchrowset($result));
	$db->sql_freeresult($result);
}

if ($post_data['poster_id'] == ANONYMOUS)
{
	$post_data['username'] = ($mode == 'quote' || $mode == 'edit') ? trim($post_data['post_username']) : '';
}
else
{
	$post_data['username'] = ($mode == 'quote' || $mode == 'edit') ? trim($post_data['username']) : '';
}

$post_data['enable_urls'] = $post_data['enable_magic_url'];

if ($mode != 'edit')
{
	$post_data['enable_sig']		= ($config['allow_sig'] && $user->optionget('attachsig')) ? true: false;
	$post_data['enable_smilies']	= ($config['allow_smilies'] && $user->optionget('smilies')) ? true : false;
	$post_data['enable_bbcode']		= ($config['allow_bbcode'] && $user->optionget('bbcode')) ? true : false;
	$post_data['enable_urls']		= true;
}

$post_data['enable_magic_url'] = $post_data['drafts'] = false;

// User own some drafts?
if ($user->data['is_registered'] && $auth->acl_get('u_savedrafts') && ($mode == 'reply' || $mode == 'post' || $mode == 'quote'))
{
	$sql = 'SELECT draft_id
		FROM ' . DRAFTS_TABLE . '
		WHERE user_id = ' . $user->data['user_id'] .
			(($forum_id) ? ' AND forum_id = ' . (int) $forum_id : '') .
			(($topic_id) ? ' AND topic_id = ' . (int) $topic_id : '') .
			(($draft_id) ? " AND draft_id <> $draft_id" : '');
	$result = $db->sql_query_limit($sql, 1);

	if ($db->sql_fetchrow($result))
	{
		$post_data['drafts'] = true;
	}
	$db->sql_freeresult($result);
}

$check_value = (($post_data['enable_bbcode']+1) << 8) + (($post_data['enable_smilies']+1) << 4) + (($post_data['enable_urls']+1) << 2) + (($post_data['enable_sig']+1) << 1);

// Check if user is watching this topic
if ($mode != 'post' && $config['allow_topic_notify'] && $user->data['is_registered'])
{
	$sql = 'SELECT topic_id
		FROM ' . TOPICS_WATCH_TABLE . '
		WHERE topic_id = ' . $topic_id . '
			AND user_id = ' . $user->data['user_id'];
	$result = $db->sql_query($sql);
	$post_data['notify_set'] = (int) $db->sql_fetchfield('topic_id');
	$db->sql_freeresult($result);
}

// Do we want to edit our post ?
if ($mode == 'edit' && $post_data['bbcode_uid'])
{
	$message_parser->bbcode_uid = $post_data['bbcode_uid'];
}

// HTML, BBCode, Smilies, Images and Flash status
$bbcode_status	= ($config['allow_bbcode'] && $auth->acl_get('f_bbcode', $forum_id)) ? true : false;
$smilies_status	= ($config['allow_smilies'] && $auth->acl_get('f_smilies', $forum_id)) ? true : false;
$img_status		= ($bbcode_status && $auth->acl_get('f_img', $forum_id)) ? true : false;
$url_status		= ($config['allow_post_links']) ? true : false;
$flash_status	= ($bbcode_status && $auth->acl_get('f_flash', $forum_id) && $config['allow_post_flash']) ? true : false;
$quote_status	= true;

// Save Draft
if ($save && $user->data['is_registered'] && $auth->acl_get('u_savedrafts') && ($mode == 'reply' || $mode == 'post' || $mode == 'quote'))
{
	$subject = utf8_normalize_nfc(request_var('subject', '', true));
	$subject = (!$subject && $mode != 'post') ? $post_data['topic_title'] : $subject;
	$message = utf8_normalize_nfc(request_var('message', '', true));

	if ($subject && $message)
	{
		if (confirm_box(true))
		{
			$sql = 'INSERT INTO ' . DRAFTS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
				'user_id'		=> (int) $user->data['user_id'],
				'topic_id'		=> (int) $topic_id,
				'forum_id'		=> (int) $forum_id,
				'save_time'		=> (int) $current_time,
				'draft_subject'	=> (string) $subject,
				'draft_message'	=> (string) $message)
			);
			$db->sql_query($sql);

			$meta_info = ($mode == 'post') ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) : append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id");

			meta_refresh(3, $meta_info);

			$message = $user->lang['DRAFT_SAVED'] . '<br /><br />';
			$message .= ($mode != 'post') ? sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $meta_info . '">', '</a>') . '<br /><br />' : '';
			$message .= sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>');

			trigger_error($message);
		}
		else
		{
			$s_hidden_fields = build_hidden_fields(array(
				'mode'		=> $mode,
				'save'		=> true,
				'f'			=> $forum_id,
				't'			=> $topic_id,
				'subject'	=> $subject,
				'message'	=> $message,
				'attachment_data' => $message_parser->attachment_data,
				)
			);

			$hidden_fields = array(
				'icon_id'			=> 0,

				'disable_bbcode'	=> false,
				'disable_smilies'	=> false,
				'disable_magic_url'	=> false,
				'attach_sig'		=> true,
				'lock_topic'		=> false,

				'topic_type'		=> POST_NORMAL,
				'topic_time_limit'	=> 0,

				'poll_title'		=> '',
				'poll_option_text'	=> '',
				'poll_max_options'	=> 1,
				'poll_length'		=> 0,
				'poll_vote_change'	=> false,
			);

			foreach ($hidden_fields as $name => $default)
			{
				if (!isset($_POST[$name]))
				{
					// Don't include it, if its not available
					unset($hidden_fields[$name]);
					continue;
				}

				if (is_bool($default))
				{
					// Use the string representation
					$hidden_fields[$name] = request_var($name, '');
				}
				else
				{
					$hidden_fields[$name] = request_var($name, $default);
				}
			}

			$s_hidden_fields .= build_hidden_fields($hidden_fields);

			confirm_box(false, 'SAVE_DRAFT', $s_hidden_fields);
		}
	}
	else
	{
		if (utf8_clean_string($subject) === '')
		{
			$error[] = $user->lang['EMPTY_SUBJECT'];
		}

		if (utf8_clean_string($message) === '')
		{
			$error[] = $user->lang['TOO_FEW_CHARS'];
		}
	}
	unset($subject, $message);
}

// Load requested Draft
if ($draft_id && ($mode == 'reply' || $mode == 'quote' || $mode == 'post') && $user->data['is_registered'] && $auth->acl_get('u_savedrafts'))
{
	$sql = 'SELECT draft_subject, draft_message
		FROM ' . DRAFTS_TABLE . "
		WHERE draft_id = $draft_id
			AND user_id = " . $user->data['user_id'];
	$result = $db->sql_query_limit($sql, 1);
	$row = $db->sql_fetchrow($result);
	$db->sql_freeresult($result);

	if ($row)
	{
		$post_data['post_subject'] = $row['draft_subject'];
		$message_parser->message = $row['draft_message'];

		$template->assign_var('S_DRAFT_LOADED', true);
	}
	else
	{
		$draft_id = 0;
	}
}

// Load draft overview
if ($load && ($mode == 'reply' || $mode == 'quote' || $mode == 'post') && $post_data['drafts'])
{
	load_drafts($topic_id, $forum_id);
}
//! Begin TMM
$prefix_id	= request_var('prefix_dropdown', 0);
$prefix_instance_id = request_var('prefix', array(0));
$prefix_cache = request_var('prefix_temp_cache', '');
$action = (isset($_POST['prefix_add'])) ? 0 : false;
$action = (isset($_POST['prefix_remove'])) ? 1 : $action;
$action = (isset($_POST['prefix_clear'])) ? 2 : $action;
$use_tmm = (($mode == 'edit' && $post_data['topic_first_post_id'] == $post_id) || $mode == 'post') ? true : false;
if($use_tmm)
{
	$ids = (!$prefix_id) ? $prefix_instance_id : $prefix_id;
	$temp_cache = tmm::do_posting_action($mode, $topic_id, $action, $ids, $prefix_cache);
	$input = ($mode == 'edit') ? 'sql' : explode(',', $temp_cache);
	$prefixes = tmm::load_topic_prefixes($topic_id, 'array', $input);
	$prefix_select = tmm::get_prefixes_for_posting($topic_id, $forum_id, $temp_cache);
	$prefixed = '';
	if(!empty($prefixes))
	{
		foreach($prefixes AS $prefix)
		{
			$parsed = ($mode == 'edit') ? tmm::parse_prefix_instance($prefix) : tmm::parse_prefix($prefix);
			$prefixed .= $parsed . ' <input type="checkbox" name="prefix[]" value="' . $prefix . '" /><br />';
		}
	}
	$template->assign_vars(array(
		'PREFIX_SELECT'		=> $prefix_select,
		'ON_NEW_POST'		=> ($mode == 'post') ? true : false,
		'APPLIED_PREFIXES'	=> $prefixed,
		'PREFIX_TEMP_CACHE'	=> $temp_cache,
	));	
}
$template->assign_var('TOPIC_PREFIX', tmm::load_topic_prefixes($topic_id));
//! End TMM

if ($submit || $preview || $refresh)
{
	$post_data['topic_cur_post_id']	= request_var('topic_cur_post_id', 0);
	$post_data['post_subject']		= utf8_normalize_nfc(request_var('subject', '', true));
	$message_parser->message		= utf8_normalize_nfc(request_var('message', '', true));

	$post_data['username']			= utf8_normalize_nfc(request_var('username', $post_data['username'], true));
	$post_data['post_edit_reason']	= (!empty($_POST['edit_reason']) && $mode == 'edit' && $auth->acl_get('m_edit', $forum_id)) ? utf8_normalize_nfc(request_var('edit_reason', '', true)) : '';

	$post_data['orig_topic_type']	= $post_data['topic_type'];
	$post_data['topic_type']		= request_var('topic_type', (($mode != 'post') ? (int) $post_data['topic_type'] : POST_NORMAL));
	$post_data['topic_time_limit']	= request_var('topic_time_limit', (($mode != 'post') ? (int) $post_data['topic_time_limit'] : 0));

	if ($post_data['enable_icons'] && $auth->acl_get('f_icons', $forum_id))
	{
		$post_data['icon_id'] = request_var('icon', (int) $post_data['icon_id']);
	}

	$post_data['enable_bbcode']		= (!$bbcode_status || isset($_POST['disable_bbcode'])) ? false : true;
	$post_data['enable_smilies']	= (!$smilies_status || isset($_POST['disable_smilies'])) ? false : true;
	$post_data['enable_urls']		= (isset($_POST['disable_magic_url'])) ? 0 : 1;
	$post_data['enable_sig']		= (!$config['allow_sig'] || !$auth->acl_get('f_sigs', $forum_id) || !$auth->acl_get('u_sig')) ? false : ((isset($_POST['attach_sig']) && $user->data['is_registered']) ? true : false);

	if ($config['allow_topic_notify'] && $user->data['is_registered'])
	{
		$notify = (isset($_POST['notify'])) ? true : false;
	}
	else
	{
		$notify = false;
	}

	$topic_lock			= (isset($_POST['lock_topic'])) ? true : false;
	$post_lock			= (isset($_POST['lock_post'])) ? true : false;
	$poll_delete		= (isset($_POST['poll_delete'])) ? true : false;

	if ($submit)
	{
		$status_switch = (($post_data['enable_bbcode']+1) << 8) + (($post_data['enable_smilies']+1) << 4) + (($post_data['enable_urls']+1) << 2) + (($post_data['enable_sig']+1) << 1);
		$status_switch = ($status_switch != $check_value);
	}
	else
	{
		$status_switch = 1;
	}

	// Delete Poll
	if ($poll_delete && $mode == 'edit' && sizeof($post_data['poll_options']) &&
		((!$post_data['poll_last_vote'] && $post_data['poster_id'] == $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id)) || $auth->acl_get('m_delete', $forum_id)))
	{
		if ($submit && check_form_key('posting'))
		{
			$sql = 'DELETE FROM ' . POLL_OPTIONS_TABLE . "
				WHERE topic_id = $topic_id";
			$db->sql_query($sql);

			$sql = 'DELETE FROM ' . POLL_VOTES_TABLE . "
				WHERE topic_id = $topic_id";
			$db->sql_query($sql);

			$topic_sql = array(
				'poll_title'		=> '',
				'poll_start' 		=> 0,
				'poll_length'		=> 0,
				'poll_last_vote'	=> 0,
				'poll_max_options'	=> 0,
				'poll_vote_change'	=> 0
			);

			$sql = 'UPDATE ' . TOPICS_TABLE . '
				SET ' . $db->sql_build_array('UPDATE', $topic_sql) . "
				WHERE topic_id = $topic_id";
			$db->sql_query($sql);
		}

		$post_data['poll_title'] = $post_data['poll_option_text'] = '';
		$post_data['poll_vote_change'] = $post_data['poll_max_options'] = $post_data['poll_length'] = 0;
	}
	else
	{
		$post_data['poll_title']		= utf8_normalize_nfc(request_var('poll_title', '', true));
		$post_data['poll_length']		= request_var('poll_length', 0);
		$post_data['poll_option_text']	= utf8_normalize_nfc(request_var('poll_option_text', '', true));
		$post_data['poll_max_options']	= request_var('poll_max_options', 1);
		$post_data['poll_vote_change']	= ($auth->acl_get('f_votechg', $forum_id) && $auth->acl_get('f_vote', $forum_id) && isset($_POST['poll_vote_change'])) ? 1 : 0;
	}

	// If replying/quoting and last post id has changed
	// give user option to continue submit or return to post
	// notify and show user the post made between his request and the final submit
	if (($mode == 'reply' || $mode == 'quote') && $post_data['topic_cur_post_id'] && $post_data['topic_cur_post_id'] != $post_data['topic_last_post_id'])
	{
		// Only do so if it is allowed forum-wide
		if ($post_data['forum_flags'] & FORUM_FLAG_POST_REVIEW)
		{
			if (topic_review($topic_id, $forum_id, 'post_review', $post_data['topic_cur_post_id']))
			{
				$template->assign_var('S_POST_REVIEW', true);
			}

			$submit = false;
			$refresh = true;
		}
	}

	// Parse Attachments - before checksum is calculated
	$message_parser->parse_attachments('fileupload', $mode, $forum_id, $submit, $preview, $refresh);

	// Grab md5 'checksum' of new message
	$message_md5 = md5($message_parser->message);

	// If editing and checksum has changed we know the post was edited while we're editing
	// Notify and show user the changed post
	if ($mode == 'edit' && $post_data['forum_flags'] & FORUM_FLAG_POST_REVIEW)
	{
		$edit_post_message_checksum = request_var('edit_post_message_checksum', '');
		$edit_post_subject_checksum = request_var('edit_post_subject_checksum', '');

		// $post_data['post_checksum'] is the checksum of the post submitted in the meantime
		// $message_md5 is the checksum of the post we're about to submit
		// $edit_post_message_checksum is the checksum of the post we're editing
		// ...

		// We make sure nobody else made exactly the same change
		// we're about to submit by also checking $message_md5 != $post_data['post_checksum']
		if (($edit_post_message_checksum !== '' && $edit_post_message_checksum != $post_data['post_checksum'] && $message_md5 != $post_data['post_checksum'])
		 || ($edit_post_subject_checksum !== '' && $edit_post_subject_checksum != $post_data['post_subject_md5'] && md5($post_data['post_subject']) != $post_data['post_subject_md5']))
		{
			if (topic_review($topic_id, $forum_id, 'post_review_edit', $post_id))
			{
				$template->assign_vars(array(
					'S_POST_REVIEW'			=> true,

					'L_POST_REVIEW'			=> $user->lang['POST_REVIEW_EDIT'],
					'L_POST_REVIEW_EXPLAIN'	=> $user->lang['POST_REVIEW_EDIT_EXPLAIN'],
				));
			}

			$submit = false;
			$refresh = true;
		}
	}

	// Check checksum ... don't re-parse message if the same
	$update_message = ($mode != 'edit' || $message_md5 != $post_data['post_checksum'] || $status_switch || strlen($post_data['bbcode_uid']) < BBCODE_UID_LEN) ? true : false;

	// Also check if subject got updated...
	$update_subject = $mode != 'edit' || ($post_data['post_subject_md5'] && $post_data['post_subject_md5'] != md5($post_data['post_subject']));

	// Parse message
	if ($update_message)
	{
		if (sizeof($message_parser->warn_msg))
		{
			$error[] = implode('<br />', $message_parser->warn_msg);
			$message_parser->warn_msg = array();
		}

		$message_parser->parse($post_data['enable_bbcode'], ($config['allow_post_links']) ? $post_data['enable_urls'] : false, $post_data['enable_smilies'], $img_status, $flash_status, $quote_status, $config['allow_post_links']);

		// On a refresh we do not care about message parsing errors
		if (sizeof($message_parser->warn_msg) && $refresh)
		{
			$message_parser->warn_msg = array();
		}
	}
	else
	{
		$message_parser->bbcode_bitfield = $post_data['bbcode_bitfield'];
	}

	if ($mode != 'edit' && !$preview && !$refresh && $config['flood_interval'] && !$auth->acl_get('f_ignoreflood', $forum_id))
	{
		// Flood check
		$last_post_time = 0;

		if ($user->data['is_registered'])
		{
			$last_post_time = $user->data['user_lastpost_time'];
		}
		else
		{
			$sql = 'SELECT post_time AS last_post_time
				FROM ' . POSTS_TABLE . "
				WHERE poster_ip = '" . $user->ip . "'
					AND post_time > " . ($current_time - $config['flood_interval']);
			$result = $db->sql_query_limit($sql, 1);
			if ($row = $db->sql_fetchrow($result))
			{
				$last_post_time = $row['last_post_time'];
			}
			$db->sql_freeresult($result);
		}

		if ($last_post_time && ($current_time - $last_post_time) < intval($config['flood_interval']))
		{
			$error[] = $user->lang['FLOOD_ERROR'];
		}
	}

	// Validate username
	if (($post_data['username'] && !$user->data['is_registered']) || ($mode == 'edit' && $post_data['poster_id'] == ANONYMOUS && $post_data['username'] && $post_data['post_username'] && $post_data['post_username'] != $post_data['username']))
	{
		include($phpbb_root_path . 'includes/functions_user.' . $phpEx);

		$user->add_lang('ucp');

		if (($result = validate_username($post_data['username'], (!empty($post_data['post_username'])) ? $post_data['post_username'] : '')) !== false)
		{
			$error[] = $user->lang[$result . '_USERNAME'];
		}

		if (($result = validate_string($post_data['username'], false, $config['min_name_chars'], $config['max_name_chars'])) !== false)
		{
			$min_max_amount = ($result == 'TOO_SHORT') ? $config['min_name_chars'] : $config['max_name_chars'];
			$error[] = sprintf($user->lang['FIELD_' . $result], $user->lang['USERNAME'], $min_max_amount);
		}
	}

	if ($config['enable_post_confirm'] && !$user->data['is_registered'] && in_array($mode, array('quote', 'post', 'reply')))
	{
		$captcha_data = array(
			'message'	=> utf8_normalize_nfc(request_var('message', '', true)),
			'subject'	=> utf8_normalize_nfc(request_var('subject', '', true)),
			'username'	=> utf8_normalize_nfc(request_var('username', '', true)),
		);
		$vc_response = $captcha->validate($captcha_data);
		if ($vc_response)
		{
			$error[] = $vc_response;
		}
	}

	// check form
	if (($submit || $preview) && !check_form_key('posting'))
	{
		$error[] = $user->lang['FORM_INVALID'];
	}

	// Parse subject
	if (!$preview && !$refresh && utf8_clean_string($post_data['post_subject']) === '' && ($mode == 'post' || ($mode == 'edit' && $post_data['topic_first_post_id'] == $post_id)))
	{
		$error[] = $user->lang['EMPTY_SUBJECT'];
	}

	$post_data['poll_last_vote'] = (isset($post_data['poll_last_vote'])) ? $post_data['poll_last_vote'] : 0;

	if ($post_data['poll_option_text'] &&
		($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_post_id']/* && (!$post_data['poll_last_vote'] || $auth->acl_get('m_edit', $forum_id))*/))
		&& $auth->acl_get('f_poll', $forum_id))
	{
		$poll = array(
			'poll_title'		=> $post_data['poll_title'],
			'poll_length'		=> $post_data['poll_length'],
			'poll_max_options'	=> $post_data['poll_max_options'],
			'poll_option_text'	=> $post_data['poll_option_text'],
			'poll_start'		=> $post_data['poll_start'],
			'poll_last_vote'	=> $post_data['poll_last_vote'],
			'poll_vote_change'	=> $post_data['poll_vote_change'],
			'enable_bbcode'		=> $post_data['enable_bbcode'],
			'enable_urls'		=> $post_data['enable_urls'],
			'enable_smilies'	=> $post_data['enable_smilies'],
			'img_status'		=> $img_status
		);

		$message_parser->parse_poll($poll);

		$post_data['poll_options'] = (isset($poll['poll_options'])) ? $poll['poll_options'] : array();
		$post_data['poll_title'] = (isset($poll['poll_title'])) ? $poll['poll_title'] : '';

		/* We reset votes, therefore also allow removing options
		if ($post_data['poll_last_vote'] && ($poll['poll_options_size'] < $orig_poll_options_size))
		{
			$message_parser->warn_msg[] = $user->lang['NO_DELETE_POLL_OPTIONS'];
		}*/
	}
	else if ($mode == 'edit' && $post_id == $post_data['topic_first_post_id'] && $auth->acl_get('f_poll', $forum_id))
	{
		// The user removed all poll options, this is equal to deleting the poll.
		$poll = array(
			'poll_title'		=> '',
			'poll_length'		=> 0,
			'poll_max_options'	=> 0,
			'poll_option_text'	=> '',
			'poll_start'		=> 0,
			'poll_last_vote'	=> 0,
			'poll_vote_change'	=> 0,
			'poll_options'		=> array(),
		);

		$post_data['poll_options'] = array();
		$post_data['poll_title'] = '';
		$post_data['poll_start'] = $post_data['poll_length'] = $post_data['poll_max_options'] = $post_data['poll_last_vote'] = $post_data['poll_vote_change'] = 0;
	}
	else if (!$auth->acl_get('f_poll', $forum_id) && ($mode == 'edit') && ($post_id == $post_data['topic_first_post_id']) && ($original_poll_data['poll_title'] != ''))
	{
		// We have a poll but the editing user is not permitted to create/edit it.
		// So we just keep the original poll-data.
		$poll = array_merge($original_poll_data, array(
			'enable_bbcode'		=> $post_data['enable_bbcode'],
			'enable_urls'		=> $post_data['enable_urls'],
			'enable_smilies'	=> $post_data['enable_smilies'],
			'img_status'		=> $img_status,
		));

		$message_parser->parse_poll($poll);

		$post_data['poll_options'] = (isset($poll['poll_options'])) ? $poll['poll_options'] : array();
		$post_data['poll_title'] = (isset($poll['poll_title'])) ? $poll['poll_title'] : '';
	}
	else
	{
		$poll = array();
	}

	// Check topic type
	if ($post_data['topic_type'] != POST_NORMAL && ($mode == 'post' || ($mode == 'edit' && $post_data['topic_first_post_id'] == $post_id)))
	{
		switch ($post_data['topic_type'])
		{
			case POST_GLOBAL:
			case POST_ANNOUNCE:
				$auth_option = 'f_announce';
			break;

			case POST_STICKY:
				$auth_option = 'f_sticky';
			break;

			default:
				$auth_option = '';
			break;
		}

		if (!$auth->acl_get($auth_option, $forum_id))
		{
			// There is a special case where a user edits his post whereby the topic type got changed by an admin/mod.
			// Another case would be a mod not having sticky permissions for example but edit permissions.
			if ($mode == 'edit')
			{
				// To prevent non-authed users messing around with the topic type we reset it to the original one.
				$post_data['topic_type'] = $post_data['orig_topic_type'];
			}
			else
			{
				$error[] = $user->lang['CANNOT_POST_' . str_replace('F_', '', strtoupper($auth_option))];
			}
		}
	}

	if (sizeof($message_parser->warn_msg))
	{
		$error[] = implode('<br />', $message_parser->warn_msg);
	}

	// DNSBL check
	if ($config['check_dnsbl'] && !$refresh)
	{
		if (($dnsbl = $user->check_dnsbl('post')) !== false)
		{
			$error[] = sprintf($user->lang['IP_BLACKLISTED'], $user->ip, $dnsbl[1]);
		}
	}

	// Store message, sync counters
	if (!sizeof($error) && $submit)
	{
		// Check if we want to de-globalize the topic... and ask for new forum
		if ($post_data['topic_type'] != POST_GLOBAL)
		{
			$sql = 'SELECT topic_type, forum_id
				FROM ' . TOPICS_TABLE . "
				WHERE topic_id = $topic_id";
			$result = $db->sql_query($sql);
			$row = $db->sql_fetchrow($result);
			$db->sql_freeresult($result);

			if ($row && !$row['forum_id'] && $row['topic_type'] == POST_GLOBAL)
			{
				$to_forum_id = request_var('to_forum_id', 0);

				if ($to_forum_id)
				{
					$sql = 'SELECT forum_type
						FROM ' . FORUMS_TABLE . '
						WHERE forum_id = ' . $to_forum_id;
					$result = $db->sql_query($sql);
					$forum_type = (int) $db->sql_fetchfield('forum_type');
					$db->sql_freeresult($result);

					if ($forum_type != FORUM_POST || !$auth->acl_get('f_post', $to_forum_id) || (!$auth->acl_get('m_approve', $to_forum_id) && !$auth->acl_get('f_noapprove', $to_forum_id)))
					{
						$to_forum_id = 0;
					}
				}

				if (!$to_forum_id)
				{
					include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx);

					$template->assign_vars(array(
						'S_FORUM_SELECT'	=> make_forum_select(false, false, false, true, true, true),
						'S_UNGLOBALISE'		=> true)
					);

					$submit = false;
					$refresh = true;
				}
				else
				{
					if (!$auth->acl_get('f_post', $to_forum_id))
					{
						// This will only be triggered if the user tried to trick the forum.
						trigger_error('NOT_AUTHORISED');
					}

					$forum_id = $to_forum_id;
				}
			}
		}

		if ($submit)
		{
			// Lock/Unlock Topic
			$change_topic_status = $post_data['topic_status'];
			$perm_lock_unlock = ($auth->acl_get('m_lock', $forum_id) || ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && !empty($post_data['topic_poster']) && $user->data['user_id'] == $post_data['topic_poster'] && $post_data['topic_status'] == ITEM_UNLOCKED)) ? true : false;

			if ($post_data['topic_status'] == ITEM_LOCKED && !$topic_lock && $perm_lock_unlock)
			{
				$change_topic_status = ITEM_UNLOCKED;
			}
			else if ($post_data['topic_status'] == ITEM_UNLOCKED && $topic_lock && $perm_lock_unlock)
			{
				$change_topic_status = ITEM_LOCKED;
			}

			if ($change_topic_status != $post_data['topic_status'])
			{
				$sql = 'UPDATE ' . TOPICS_TABLE . "
					SET topic_status = $change_topic_status
					WHERE topic_id = $topic_id
						AND topic_moved_id = 0";
				$db->sql_query($sql);

				$user_lock = ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && $user->data['user_id'] == $post_data['topic_poster']) ? 'USER_' : '';

				add_log('mod', $forum_id, $topic_id, 'LOG_' . $user_lock . (($change_topic_status == ITEM_LOCKED) ? 'LOCK' : 'UNLOCK'), $post_data['topic_title']);
			}

			// Lock/Unlock Post Edit
			if ($mode == 'edit' && $post_data['post_edit_locked'] == ITEM_LOCKED && !$post_lock && $auth->acl_get('m_edit', $forum_id))
			{
				$post_data['post_edit_locked'] = ITEM_UNLOCKED;
			}
			else if ($mode == 'edit' && $post_data['post_edit_locked'] == ITEM_UNLOCKED && $post_lock && $auth->acl_get('m_edit', $forum_id))
			{
				$post_data['post_edit_locked'] = ITEM_LOCKED;
			}
$add_points = 0;
      if ( $config['points_enable'] && ( $mode == 'post' || $mode == 'reply' || 'quote' ) && $mode != 'edit' && $mode != 'delete')
      {
				$user->add_lang('mods/points');
        include_once($phpbb_root_path . 'includes/functions_points.' . $phpEx);
			  
        if ( forum_points_enabled($forum_id) )
        {
          if ($mode == 'post')
          {
            $add_points = $config['pertopic'];     
          }
          elseif ($mode == 'reply' || 'quote')
          {
            $add_points = $config['perpost'];       
          }              

					if ($config['perword'] > 0)
					{
						$text = $message_parser->message;
						$uid = $message_parser->bbcode_uid;
						strip_bbcode($text, $uid);
						$text = preg_replace("#\[\/?[a-z0-9\*\+\-]+(?:=(?:".*"|[^\]]*))?(?::[a-z])?\]#", ' ', $text);

						$words_count = str_word_count($text);
						$add_points += $config['perword'] * $words_count;
					}
        }  
      }
	  
			$data = array(
				'topic_title'			=> (empty($post_data['topic_title'])) ? $post_data['post_subject'] : $post_data['topic_title'],
				'topic_first_post_id'	=> (isset($post_data['topic_first_post_id'])) ? (int) $post_data['topic_first_post_id'] : 0,
				'topic_last_post_id'	=> (isset($post_data['topic_last_post_id'])) ? (int) $post_data['topic_last_post_id'] : 0,
				'topic_time_limit'		=> (int) $post_data['topic_time_limit'],
				'topic_attachment'		=> (isset($post_data['topic_attachment'])) ? (int) $post_data['topic_attachment'] : 0,
				'post_id'				=> (int) $post_id,
				'topic_id'				=> (int) $topic_id,
				'forum_id'				=> (int) $forum_id,
				'icon_id'				=> (int) $post_data['icon_id'],
				'poster_id'				=> (int) $post_data['poster_id'],
				'enable_sig'			=> (bool) $post_data['enable_sig'],
				'enable_bbcode'			=> (bool) $post_data['enable_bbcode'],
				'enable_smilies'		=> (bool) $post_data['enable_smilies'],
				'enable_urls'			=> (bool) $post_data['enable_urls'],
				'enable_indexing'		=> (bool) $post_data['enable_indexing'],
				'message_md5'			=> (string) $message_md5,
				'post_time'				=> (isset($post_data['post_time'])) ? (int) $post_data['post_time'] : $current_time,
				'post_checksum'			=> (isset($post_data['post_checksum'])) ? (string) $post_data['post_checksum'] : '',
				'post_edit_reason'		=> $post_data['post_edit_reason'],
				'post_edit_user'		=> ($mode == 'edit') ? $user->data['user_id'] : ((isset($post_data['post_edit_user'])) ? (int) $post_data['post_edit_user'] : 0),
				'forum_parents'			=> $post_data['forum_parents'],
				'forum_name'			=> $post_data['forum_name'],
				'notify'				=> $notify,
				'notify_set'			=> $post_data['notify_set'],
				'poster_ip'				=> (isset($post_data['poster_ip'])) ? $post_data['poster_ip'] : $user->ip,
				'post_edit_locked'		=> (int) $post_data['post_edit_locked'],
				'bbcode_bitfield'		=> $message_parser->bbcode_bitfield,
				'bbcode_uid'			=> $message_parser->bbcode_uid,
				'message'				=> $message_parser->message,
				'attachment_data'		=> $message_parser->attachment_data,
				'filename_data'			=> $message_parser->filename_data,

				'topic_approved'		=> (isset($post_data['topic_approved'])) ? $post_data['topic_approved'] : false,
				'post_approved'			=> (isset($post_data['post_approved'])) ? $post_data['post_approved'] : false,
			);

			if ($mode == 'edit')
			{
				$data['topic_replies_real'] = $post_data['topic_replies_real'];
				$data['topic_replies'] = $post_data['topic_replies'];
			}

			// The last parameter tells submit_post if search indexer has to be run
			$redirect_url = submit_post($mode, $post_data['post_subject'], $post_data['username'], $post_data['topic_type'], $poll, $data, $update_message, ($update_message || $update_subject) ? true : false);
			//! Begin TMM
			if($mode == 'post' && !empty($prefixes) && is_array($prefixes))
			{
				$sql = 'SELECT topic_id
					FROM ' . TOPICS_TABLE . '
					ORDER BY topic_id DESC';
				$result = $db->sql_query($sql);
				$new_topic_id = $db->sql_fetchfield('topic_id');
				$db->sql_freeresult($result);
				foreach($prefixes AS $prefix)
				{
					tmm::apply_prefix($prefix, $new_topic_id);
				}
			}
			//! End TMM

			if ($config['enable_post_confirm'] && !$user->data['is_registered'] && (isset($captcha) && $captcha->is_solved() === true) && ($mode == 'post' || $mode == 'reply' || $mode == 'quote'))
			{
				$captcha->reset();
			}

			// Check the permissions for post approval. Moderators are not affected.
			if ((!$auth->acl_get('f_noapprove', $data['forum_id']) && !$auth->acl_get('m_approve', $data['forum_id']) && empty($data['force_approved_state'])) || (isset($data['force_approved_state']) && !$data['force_approved_state']))
			{
if ( $add_points && $user->data['user_id'] != ANONYMOUS && $mode != 'edit')
				{
					set_points_received($data['post_id'], $add_points);

					meta_refresh(10, $redirect_url);

					if ($mode == 'post')
					{
						$points_received = sprintf($user->lang['POINTS_RECEIVED_POST_MOD_MESSAGE'], $add_points, $config['points_name']);
					}
					else
					{
						$points_received = sprintf($user->lang['POINTS_RECEIVED_REPLY_MOD_MESSAGE'], $add_points, $config['points_name']);
					}

					$message = $user->lang['POST_STORED_MOD'] . ' ' . $user->lang['POST_APPROVAL_NOTIFY'] . '<br /><br />' . $points_received . '<br /><br />' . sprintf($user->lang['VIEW_MESSAGE'], '<a href="' . $redirect_url . '">', '</a>');
				}
				else
				{
					meta_refresh(10, $redirect_url);
					$message = ($mode == 'edit') ? $user->lang['POST_EDITED_MOD'] : $user->lang['POST_STORED_MOD'];
					$message .= (($user->data['user_id'] == ANONYMOUS) ? '' : ' '. $user->lang['POST_APPROVAL_NOTIFY']);
				}
			}
			else
			{
if ( $add_points )
				{
					add_points($user->data['user_id'], $add_points);

					set_points_received($data['post_id'], $add_points);

					meta_refresh(3, $redirect_url);

					if ($mode == 'post')
					{
						$points_received = sprintf($user->lang['POINTS_RECEIVED_POST_MESSAGE'], $add_points, $config['points_name']);
					}
					else
					{
						$points_received = sprintf($user->lang['POINTS_RECEIVED_REPLY_MESSAGE'], $add_points, $config['points_name']);
					}

					$message = $user->lang['POST_STORED'] . '<br /><br />' . $points_received . '<br /><br />' . sprintf($user->lang['VIEW_MESSAGE'], '<a href="' . $redirect_url . '">', '</a>');
				}
				else
				{
					meta_refresh(3, $redirect_url);

					$message = ($mode == 'edit') ? 'POST_EDITED' : 'POST_STORED';
					$message = $user->lang[$message] . '<br /><br />' . sprintf($user->lang['VIEW_MESSAGE'], '<a href="' . $redirect_url . '">', '</a>');
				}
			}

			$message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $data['forum_id']) . '">', '</a>');
			trigger_error($message);
		}
	}
}

// Preview
if (!sizeof($error) && $preview)
{
	$post_data['post_time'] = ($mode == 'edit') ? $post_data['post_time'] : $current_time;

	$preview_message = $message_parser->format_display($post_data['enable_bbcode'], $post_data['enable_urls'], $post_data['enable_smilies'], false);

	$preview_signature = ($mode == 'edit') ? $post_data['user_sig'] : $user->data['user_sig'];
	$preview_signature_uid = ($mode == 'edit') ? $post_data['user_sig_bbcode_uid'] : $user->data['user_sig_bbcode_uid'];
	$preview_signature_bitfield = ($mode == 'edit') ? $post_data['user_sig_bbcode_bitfield'] : $user->data['user_sig_bbcode_bitfield'];

	// Signature
	if ($post_data['enable_sig'] && $config['allow_sig'] && $preview_signature && $auth->acl_get('f_sigs', $forum_id))
	{
		$parse_sig = new parse_message($preview_signature);
		$parse_sig->bbcode_uid = $preview_signature_uid;
		$parse_sig->bbcode_bitfield = $preview_signature_bitfield;

		// Not sure about parameters for bbcode/smilies/urls... in signatures
		$parse_sig->format_display($config['allow_sig_bbcode'], $config['allow_sig_links'], $config['allow_sig_smilies']);
		$preview_signature = $parse_sig->message;
		unset($parse_sig);
	}
	else
	{
		$preview_signature = '';
	}

	$preview_subject = censor_text($post_data['post_subject']);

	// Poll Preview
	if (!$poll_delete && ($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_post_id']/* && (!$post_data['poll_last_vote'] || $auth->acl_get('m_edit', $forum_id))*/))
	&& $auth->acl_get('f_poll', $forum_id))
	{
		$parse_poll = new parse_message($post_data['poll_title']);
		$parse_poll->bbcode_uid = $message_parser->bbcode_uid;
		$parse_poll->bbcode_bitfield = $message_parser->bbcode_bitfield;

		$parse_poll->format_display($post_data['enable_bbcode'], $post_data['enable_urls'], $post_data['enable_smilies']);

		if ($post_data['poll_length'])
		{
			$poll_end = ($post_data['poll_length'] * 86400) + (($post_data['poll_start']) ? $post_data['poll_start'] : time());
		}

		$template->assign_vars(array(
			'S_HAS_POLL_OPTIONS'	=> (sizeof($post_data['poll_options'])),
			'S_IS_MULTI_CHOICE'		=> ($post_data['poll_max_options'] > 1) ? true : false,

			'POLL_QUESTION'		=> $parse_poll->message,

			'L_POLL_LENGTH'		=> ($post_data['poll_length']) ? sprintf($user->lang['POLL_RUN_TILL'], $user->format_date($poll_end)) : '',
			'L_MAX_VOTES'		=> ($post_data['poll_max_options'] == 1) ? $user->lang['MAX_OPTION_SELECT'] : sprintf($user->lang['MAX_OPTIONS_SELECT'], $post_data['poll_max_options']))
		);

		$parse_poll->message = implode("\n", $post_data['poll_options']);
		$parse_poll->format_display($post_data['enable_bbcode'], $post_data['enable_urls'], $post_data['enable_smilies']);
		$preview_poll_options = explode('<br />', $parse_poll->message);
		unset($parse_poll);

		foreach ($preview_poll_options as $key => $option)
		{
			$template->assign_block_vars('poll_option', array(
				'POLL_OPTION_CAPTION'	=> $option,
				'POLL_OPTION_ID'		=> $key + 1)
			);
		}
		unset($preview_poll_options);
	}

	// Attachment Preview
	if (sizeof($message_parser->attachment_data))
	{
		$template->assign_var('S_HAS_ATTACHMENTS', true);

		$update_count = array();
		$attachment_data = $message_parser->attachment_data;

		parse_attachments($forum_id, $preview_message, $attachment_data, $update_count, true);

		foreach ($attachment_data as $i => $attachment)
		{
			$template->assign_block_vars('attachment', array(
				'DISPLAY_ATTACHMENT'	=> $attachment)
			);
		}
		unset($attachment_data);
	}

	if (!sizeof($error))
	{
		$template->assign_vars(array(
			'PREVIEW_SUBJECT'		=> $preview_subject,
			'PREVIEW_MESSAGE'		=> $preview_message,
			'PREVIEW_SIGNATURE'		=> $preview_signature,

			'S_DISPLAY_PREVIEW'		=> true)
		);
	}
}

// Decode text for message display
$post_data['bbcode_uid'] = ($mode == 'quote' && !$preview && !$refresh && !sizeof($error)) ? $post_data['bbcode_uid'] : $message_parser->bbcode_uid;
$message_parser->decode_message($post_data['bbcode_uid']);

if ($mode == 'quote' && !$submit && !$preview && !$refresh)
{
	if ($config['allow_bbcode'])
	{
		$message_parser->message = '[quote="' . $post_data['quote_username'] . '"]' . censor_text(trim($message_parser->message)) . "[/quote]\n";
	}
	else
	{
		$offset = 0;
		$quote_string = "> ";
		$message = censor_text(trim($message_parser->message));
		// see if we are nesting. It's easily tricked but should work for one level of nesting
		if (strpos($message, ">") !== false)
		{
			$offset = 10;
		}
		$message = utf8_wordwrap($message, 75 + $offset, "\n");

		$message = $quote_string . $message;
		$message = str_replace("\n", "\n" . $quote_string, $message);
		$message_parser->message =  $post_data['quote_username'] . " " . $user->lang['WROTE'] . ":\n" . $message . "\n";
	}
}

if (($mode == 'reply' || $mode == 'quote') && !$submit && !$preview && !$refresh)
{
	$post_data['post_subject'] = ((strpos($post_data['post_subject'], 'Re: ') !== 0) ? 'Re: ' : '') . censor_text($post_data['post_subject']);
}

$attachment_data = $message_parser->attachment_data;
$filename_data = $message_parser->filename_data;
$post_data['post_text'] = $message_parser->message;

if (sizeof($post_data['poll_options']) || !empty($post_data['poll_title']))
{
	$message_parser->message = $post_data['poll_title'];
	$message_parser->bbcode_uid = $post_data['bbcode_uid'];

	$message_parser->decode_message();
	$post_data['poll_title'] = $message_parser->message;

	$message_parser->message = implode("\n", $post_data['poll_options']);
	$message_parser->decode_message();
	$post_data['poll_options'] = explode("\n", $message_parser->message);
}

// MAIN POSTING PAGE BEGINS HERE

// Forum moderators?
$moderators = array();
if ($config['load_moderators'])
{
	get_moderators($moderators, $forum_id);
}

// Generate smiley listing
generate_smilies('inline', $forum_id);

// Generate inline attachment select box
posting_gen_inline_attachments($attachment_data);

// Do show topic type selection only in first post.
$topic_type_toggle = false;

if ($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_post_id']))
{
	$topic_type_toggle = posting_gen_topic_types($forum_id, $post_data['topic_type']);
}

$s_topic_icons = false;
if ($post_data['enable_icons'] && $auth->acl_get('f_icons', $forum_id))
{
	$s_topic_icons = posting_gen_topic_icons($mode, $post_data['icon_id']);
}

$bbcode_checked		= (isset($post_data['enable_bbcode'])) ? !$post_data['enable_bbcode'] : (($config['allow_bbcode']) ? !$user->optionget('bbcode') : 1);
$smilies_checked	= (isset($post_data['enable_smilies'])) ? !$post_data['enable_smilies'] : (($config['allow_smilies']) ? !$user->optionget('smilies') : 1);
$urls_checked		= (isset($post_data['enable_urls'])) ? !$post_data['enable_urls'] : 0;
$sig_checked		= $post_data['enable_sig'];
$lock_topic_checked	= (isset($topic_lock) && $topic_lock) ? $topic_lock : (($post_data['topic_status'] == ITEM_LOCKED) ? 1 : 0);
$lock_post_checked	= (isset($post_lock)) ? $post_lock : $post_data['post_edit_locked'];

// If the user is replying or posting and not already watching this topic but set to always being notified we need to overwrite this setting
$notify_set			= ($mode != 'edit' && $config['allow_topic_notify'] && $user->data['is_registered'] && !$post_data['notify_set']) ? $user->data['user_notify'] : $post_data['notify_set'];
$notify_checked		= (isset($notify)) ? $notify : (($mode == 'post') ? $user->data['user_notify'] : $notify_set);

// Page title & action URL
$s_action = append_sid("{$phpbb_root_path}posting.$phpEx", "mode=$mode&f=$forum_id");
$s_action .= ($topic_id) ? "&t=$topic_id" : '';
$s_action .= ($post_id) ? "&p=$post_id" : '';

switch ($mode)
{
	case 'post':
		$page_title = $user->lang['POST_TOPIC'];
	break;

	case 'quote':
	case 'reply':
		$page_title = $user->lang['POST_REPLY'];
	break;

	case 'delete':
	case 'edit':
		$page_title = $user->lang['EDIT_POST'];
	break;
}

// Build Navigation Links
generate_forum_nav($post_data);

// Build Forum Rules
generate_forum_rules($post_data);

// Posting uses is_solved for legacy reasons. Plugins have to use is_solved to force themselves to be displayed.
if ($config['enable_post_confirm'] && !$user->data['is_registered'] && (isset($captcha) && $captcha->is_solved() === false) && ($mode == 'post' || $mode == 'reply' || $mode == 'quote'))
{

	$template->assign_vars(array(
		'S_CONFIRM_CODE'			=> true,
		'CAPTCHA_TEMPLATE'			=> $captcha->get_template(),
	));
}

$s_hidden_fields = ($mode == 'reply' || $mode == 'quote') ? '<input type="hidden" name="topic_cur_post_id" value="' . $post_data['topic_last_post_id'] . '" />' : '';
$s_hidden_fields .= '<input type="hidden" name="lastclick" value="' . $current_time . '" />';
$s_hidden_fields .= ($draft_id || isset($_REQUEST['draft_loaded'])) ? '<input type="hidden" name="draft_loaded" value="' . request_var('draft_loaded', $draft_id) . '" />' : '';

if ($mode == 'edit')
{
	$s_hidden_fields .= build_hidden_fields(array(
		'edit_post_message_checksum'	=> $post_data['post_checksum'],
		'edit_post_subject_checksum'	=> $post_data['post_subject_md5'],
	));
}

// Add the confirm id/code pair to the hidden fields, else an error is displayed on next submit/preview
if (isset($captcha) && $captcha->is_solved() !== false)
{
	$s_hidden_fields .= build_hidden_fields($captcha->get_hidden_fields());
}

$form_enctype = (@ini_get('file_uploads') == '0' || strtolower(@ini_get('file_uploads')) == 'off' || !$config['allow_attachments'] || !$auth->acl_get('u_attach') || !$auth->acl_get('f_attach', $forum_id)) ? '' : ' enctype="multipart/form-data"';
add_form_key('posting');


// Start assigning vars for main posting page ...
$template->assign_vars(array(
	'L_POST_A'					=> $page_title,
	'L_ICON'					=> ($mode == 'reply' || $mode == 'quote' || ($mode == 'edit' && $post_id != $post_data['topic_first_post_id'])) ? $user->lang['POST_ICON'] : $user->lang['TOPIC_ICON'],
	'L_MESSAGE_BODY_EXPLAIN'	=> (intval($config['max_post_chars'])) ? sprintf($user->lang['MESSAGE_BODY_EXPLAIN'], intval($config['max_post_chars'])) : '',

	'FORUM_NAME'			=> $post_data['forum_name'],
	'FORUM_DESC'			=> ($post_data['forum_desc']) ? generate_text_for_display($post_data['forum_desc'], $post_data['forum_desc_uid'], $post_data['forum_desc_bitfield'], $post_data['forum_desc_options']) : '',
	'TOPIC_TITLE'			=> censor_text($post_data['topic_title']),
	'MODERATORS'			=> (sizeof($moderators)) ? implode(', ', $moderators[$forum_id]) : '',
	'USERNAME'				=> ((!$preview && $mode != 'quote') || $preview) ? $post_data['username'] : '',
	'SUBJECT'				=> $post_data['post_subject'],
	'MESSAGE'				=> $post_data['post_text'],
	'BBCODE_STATUS'			=> ($bbcode_status) ? sprintf($user->lang['BBCODE_IS_ON'], '<a href="' . append_sid("{$phpbb_root_path}faq.$phpEx", 'mode=bbcode') . '">', '</a>') : sprintf($user->lang['BBCODE_IS_OFF'], '<a href="' . append_sid("{$phpbb_root_path}faq.$phpEx", 'mode=bbcode') . '">', '</a>'),
	'IMG_STATUS'			=> ($img_status) ? $user->lang['IMAGES_ARE_ON'] : $user->lang['IMAGES_ARE_OFF'],
	'FLASH_STATUS'			=> ($flash_status) ? $user->lang['FLASH_IS_ON'] : $user->lang['FLASH_IS_OFF'],
	'SMILIES_STATUS'		=> ($smilies_status) ? $user->lang['SMILIES_ARE_ON'] : $user->lang['SMILIES_ARE_OFF'],
	'URL_STATUS'			=> ($bbcode_status && $url_status) ? $user->lang['URL_IS_ON'] : $user->lang['URL_IS_OFF'],
	'MAX_FONT_SIZE'			=> (int) $config['max_post_font_size'],
	'MINI_POST_IMG'			=> $user->img('icon_post_target', $user->lang['POST']),
	'POST_DATE'				=> ($post_data['post_time']) ? $user->format_date($post_data['post_time']) : '',
	'ERROR'					=> (sizeof($error)) ? implode('<br />', $error) : '',
	'TOPIC_TIME_LIMIT'		=> (int) $post_data['topic_time_limit'],
	'EDIT_REASON'			=> $post_data['post_edit_reason'],
	'U_VIEW_FORUM'			=> append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id"),
	'U_VIEW_TOPIC'			=> ($mode != 'post') ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id") : '',
	'U_PROGRESS_BAR'		=> append_sid("{$phpbb_root_path}posting.$phpEx", "f=$forum_id&mode=popup"),
	'UA_PROGRESS_BAR'		=> addslashes(append_sid("{$phpbb_root_path}posting.$phpEx", "f=$forum_id&mode=popup")),

	'S_PRIVMSGS'				=> false,
	'S_CLOSE_PROGRESS_WINDOW'	=> (isset($_POST['add_file'])) ? true : false,
	'S_EDIT_POST'				=> ($mode == 'edit') ? true : false,
	'S_EDIT_REASON'				=> ($mode == 'edit' && $auth->acl_get('m_edit', $forum_id)) ? true : false,
	'S_DISPLAY_USERNAME'		=> (!$user->data['is_registered'] || ($mode == 'edit' && $post_data['poster_id'] == ANONYMOUS)) ? true : false,
	'S_SHOW_TOPIC_ICONS'		=> $s_topic_icons,
	'S_DELETE_ALLOWED'			=> ($mode == 'edit' && (($post_id == $post_data['topic_last_post_id'] && $post_data['poster_id'] == $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id) && !$post_data['post_edit_locked'] && ($post_data['post_time'] > time() - ($config['delete_time'] * 60) || !$config['delete_time'])) || $auth->acl_get('m_delete', $forum_id))) ? true : false,
	'S_BBCODE_ALLOWED'			=> ($bbcode_status) ? 1 : 0,
	'S_BBCODE_CHECKED'			=> ($bbcode_checked) ? ' checked="checked"' : '',
	'S_SMILIES_ALLOWED'			=> $smilies_status,
	'S_SMILIES_CHECKED'			=> ($smilies_checked) ? ' checked="checked"' : '',
	'S_SIG_ALLOWED'				=> ($auth->acl_get('f_sigs', $forum_id) && $config['allow_sig'] && $user->data['is_registered']) ? true : false,
	'S_SIGNATURE_CHECKED'		=> ($sig_checked) ? ' checked="checked"' : '',
	'S_NOTIFY_ALLOWED'			=> (!$user->data['is_registered'] || ($mode == 'edit' && $user->data['user_id'] != $post_data['poster_id']) || !$config['allow_topic_notify'] || !$config['email_enable']) ? false : true,
	'S_NOTIFY_CHECKED'			=> ($notify_checked) ? ' checked="checked"' : '',
	'S_LOCK_TOPIC_ALLOWED'		=> (($mode == 'edit' || $mode == 'reply' || $mode == 'quote') && ($auth->acl_get('m_lock', $forum_id) || ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && !empty($post_data['topic_poster']) && $user->data['user_id'] == $post_data['topic_poster'] && $post_data['topic_status'] == ITEM_UNLOCKED))) ? true : false,
	'S_LOCK_TOPIC_CHECKED'		=> ($lock_topic_checked) ? ' checked="checked"' : '',
	'S_LOCK_POST_ALLOWED'		=> ($mode == 'edit' && $auth->acl_get('m_edit', $forum_id)) ? true : false,
	'S_LOCK_POST_CHECKED'		=> ($lock_post_checked) ? ' checked="checked"' : '',
	'S_LINKS_ALLOWED'			=> $url_status,
	'S_MAGIC_URL_CHECKED'		=> ($urls_checked) ? ' checked="checked"' : '',
	'S_TYPE_TOGGLE'				=> $topic_type_toggle,
	'S_SAVE_ALLOWED'			=> ($auth->acl_get('u_savedrafts') && $user->data['is_registered'] && $mode != 'edit') ? true : false,
	'S_HAS_DRAFTS'				=> ($auth->acl_get('u_savedrafts') && $user->data['is_registered'] && $post_data['drafts']) ? true : false,
	'S_FORM_ENCTYPE'			=> $form_enctype,

	'S_BBCODE_IMG'			=> $img_status,
	'S_BBCODE_URL'			=> $url_status,
	'S_BBCODE_FLASH'		=> $flash_status,
	'S_BBCODE_QUOTE'		=> $quote_status,

	'S_POST_ACTION'			=> $s_action,
	'S_HIDDEN_FIELDS'		=> $s_hidden_fields)
);

// Build custom bbcodes array
display_custom_bbcodes();

// Poll entry
if (($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_post_id']/* && (!$post_data['poll_last_vote'] || $auth->acl_get('m_edit', $forum_id))*/))
	&& $auth->acl_get('f_poll', $forum_id))
{
	$template->assign_vars(array(
		'S_SHOW_POLL_BOX'		=> true,
		'S_POLL_VOTE_CHANGE'	=> ($auth->acl_get('f_votechg', $forum_id) && $auth->acl_get('f_vote', $forum_id)),
		'S_POLL_DELETE'			=> ($mode == 'edit' && sizeof($post_data['poll_options']) && ((!$post_data['poll_last_vote'] && $post_data['poster_id'] == $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id)) || $auth->acl_get('m_delete', $forum_id))),
		'S_POLL_DELETE_CHECKED'	=> (!empty($poll_delete)) ? true : false,

		'L_POLL_OPTIONS_EXPLAIN'	=> sprintf($user->lang['POLL_OPTIONS_' . (($mode == 'edit') ? 'EDIT_' : '') . 'EXPLAIN'], $config['max_poll_options']),

		'VOTE_CHANGE_CHECKED'	=> (!empty($post_data['poll_vote_change'])) ? ' checked="checked"' : '',
		'POLL_TITLE'			=> (isset($post_data['poll_title'])) ? $post_data['poll_title'] : '',
		'POLL_OPTIONS'			=> (!empty($post_data['poll_options'])) ? implode("\n", $post_data['poll_options']) : '',
		'POLL_MAX_OPTIONS'		=> (isset($post_data['poll_max_options'])) ? (int) $post_data['poll_max_options'] : 1,
		'POLL_LENGTH'			=> $post_data['poll_length'])
	);
}

// Show attachment box for adding attachments if true
$allowed = ($auth->acl_get('f_attach', $forum_id) && $auth->acl_get('u_attach') && $config['allow_attachments'] && $form_enctype);

// Attachment entry
posting_gen_attachment_entry($attachment_data, $filename_data, $allowed);

// Output page ...
page_header($page_title, false);

$template->set_filenames(array(
	'body' => 'posting_body.html')
);

make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"));

// Topic review
if ($mode == 'reply' || $mode == 'quote')
{
	if (topic_review($topic_id, $forum_id))
	{
		$template->assign_var('S_DISPLAY_REVIEW', true);
	}
}

page_footer();

/**
* Show upload popup (progress bar)
*/
function upload_popup($forum_style = 0)
{
	global $template, $user;

	($forum_style) ? $user->setup('posting', $forum_style) : $user->setup('posting');

	page_header($user->lang['PROGRESS_BAR'], false);

	$template->set_filenames(array(
		'popup'	=> 'posting_progress_bar.html')
	);

	$template->assign_vars(array(
		'PROGRESS_BAR'	=> $user->img('upload_bar', $user->lang['UPLOAD_IN_PROGRESS']))
	);

	$template->display('popup');

	garbage_collection();
	exit_handler();
}

/**
* Do the various checks required for removing posts as well as removing it
*/
function handle_post_delete($forum_id, $topic_id, $post_id, &$post_data)
{
	global $user, $db, $auth, $config;
	global $phpbb_root_path, $phpEx;

	// If moderator removing post or user itself removing post, present a confirmation screen
	if ($auth->acl_get('m_delete', $forum_id) || ($post_data['poster_id'] == $user->data['user_id'] && $user->data['is_registered'] && $auth->acl_get('f_delete', $forum_id) && $post_id == $post_data['topic_last_post_id'] && !$post_data['post_edit_locked'] && ($post_data['post_time'] > time() - ($config['delete_time'] * 60) || !$config['delete_time'])))
	{
		$s_hidden_fields = build_hidden_fields(array(
			'p'		=> $post_id,
			'f'		=> $forum_id,
			'mode'	=> 'delete')
		);

		if (confirm_box(true))
		{
			$data = array(
				'topic_first_post_id'	=> $post_data['topic_first_post_id'],
				'topic_last_post_id'	=> $post_data['topic_last_post_id'],
				'topic_replies_real'	=> $post_data['topic_replies_real'],
				'topic_approved'		=> $post_data['topic_approved'],
				'topic_type'			=> $post_data['topic_type'],
				'post_approved'			=> $post_data['post_approved'],
				'post_reported'			=> $post_data['post_reported'],
				'post_time'				=> $post_data['post_time'],
				'poster_id'				=> $post_data['poster_id'],
				'post_postcount'		=> $post_data['post_postcount']
			);

			$next_post_id = delete_post($forum_id, $topic_id, $post_id, $data);
			$post_username = ($post_data['poster_id'] == ANONYMOUS && !empty($post_data['post_username'])) ? $post_data['post_username'] : $post_data['username'];

			if ($next_post_id === false)
			{
				add_log('mod', $forum_id, $topic_id, 'LOG_DELETE_TOPIC', $post_data['topic_title'], $post_username);

				$meta_info = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id");
				$message = $user->lang['POST_DELETED'];
			}
			else
			if ($config['points_enable'])
			{
				include_once($phpbb_root_path . 'includes/functions_points.' . $phpEx);

				if ( forum_points_enabled($forum_id) )
				{
					remove_points($post_data['poster_id'], $post_data['points_received']);
          
					if ($post_data['poster_id'] == $user->data['user_id'])
					{
						$user->add_lang('mods/points');
						$message .= '<br /><br />'.sprintf($user->lang['POINTS_POST_REMOVED'], $post_data['points_received'], $config['points_name']);
					}
				}
			}

			meta_refresh(3, $meta_info);
			$message .= '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id) . '">', '</a>');
			trigger_error($message);
		}
		else
		{
			confirm_box(false, 'DELETE_POST', $s_hidden_fields);
		}
	}

	// If we are here the user is not able to delete - present the correct error message
	if ($post_data['poster_id'] != $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id))
	{
		trigger_error('DELETE_OWN_POSTS');
	}

	if ($post_data['poster_id'] == $user->data['user_id'] && $auth->acl_get('f_delete', $forum_id) && $post_id != $post_data['topic_last_post_id'])
	{
		trigger_error('CANNOT_DELETE_REPLIED');
	}

	trigger_error('USER_CANNOT_DELETE');
}

?>

Thankyou so much in advance!
Attachments
posting.txt
(63.9 KiB) Downloaded 7 times
User avatar
stevemaury
Support Team Member
Support Team Member
Posts: 52768
Joined: Thu Nov 02, 2006 12:21 am
Location: The U.P.
Name: Steve
Contact:

Re: Guest posting doesnt work?

Post by stevemaury »

Use Crimson Editor or some other appropriate editor to search across all the .php files (the root folder and the includes folder and children) for the string:

Code: Select all

function user_get_id_name
I can stop all your spam. I can upgrade or update your Board. PM or email me. (Paid support)
AbbeyG
Registered User
Posts: 88
Joined: Fri Feb 08, 2013 7:14 pm

Re: Guest posting doesnt work?

Post by AbbeyG »

Children?
AbbeyG
Registered User
Posts: 88
Joined: Fri Feb 08, 2013 7:14 pm

Re: Guest posting doesnt work?

Post by AbbeyG »

I dont know what children means, but I have searched for the function in all files in my root and inlcudes folder [well not the subfolders in includes folder, like hooks, search, db, diff (is that what you mean)].

I didnt find that function in any of the files I searched except in the functions-user.php file.
User avatar
stevemaury
Support Team Member
Support Team Member
Posts: 52768
Joined: Thu Nov 02, 2006 12:21 am
Location: The U.P.
Name: Steve
Contact:

Re: Guest posting doesnt work?

Post by stevemaury »

Children = subfolders
I can stop all your spam. I can upgrade or update your Board. PM or email me. (Paid support)
AbbeyG
Registered User
Posts: 88
Joined: Fri Feb 08, 2013 7:14 pm

Re: Guest posting doesnt work?

Post by AbbeyG »

I cross checked with all folders. None of it had that function except for the function_user.php file.
Locked

Return to “[3.0.x] Support Forum”