diff options
Diffstat (limited to 'phpBB/includes/functions_user.php')
| -rw-r--r-- | phpBB/includes/functions_user.php | 1090 | 
1 files changed, 477 insertions, 613 deletions
| diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index ea8b0a4640..dba6d3d6c2 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -2,9 +2,8 @@  /**  *  * @package phpBB3 -* @version $Id$  * @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2  *  */ @@ -113,7 +112,7 @@ function update_last_username()  */  function user_update_name($old_name, $new_name)  { -	global $config, $db, $cache; +	global $config, $db, $cache, $phpbb_dispatcher;  	$update_ary = array(  		FORUMS_TABLE			=> array('forum_last_poster_name'), @@ -138,6 +137,17 @@ function user_update_name($old_name, $new_name)  		set_config('newest_username', $new_name, true);  	} +	/** +	* Update a username when it is changed +	* +	* @event core.update_username +	* @var	string	old_name	The old username that is replaced +	* @var	string	new_name	The new username +	* @since 3.1-A1 +	*/ +	$vars = array('old_name', 'new_name'); +	extract($phpbb_dispatcher->trigger_event('core.update_username', compact($vars))); +  	// Because some tables/caches use username-specific data we need to purge this here.  	$cache->destroy('sql', MODERATOR_CACHE_TABLE);  } @@ -152,6 +162,7 @@ function user_update_name($old_name, $new_name)  function user_add($user_row, $cp_data = false)  {  	global $db, $user, $auth, $config, $phpbb_root_path, $phpEx; +	global $phpbb_dispatcher;  	if (empty($user_row['username']) || !isset($user_row['group_id']) || !isset($user_row['user_email']) || !isset($user_row['user_type']))  	{ @@ -198,12 +209,11 @@ function user_add($user_row, $cp_data = false)  		'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_type'		=> '',  		'user_avatar_width'		=> 0,  		'user_avatar_height'	=> 0,  		'user_new_privmsg'		=> 0, @@ -246,6 +256,16 @@ function user_add($user_row, $cp_data = false)  		}  	} +	/** +	* Use this event to modify the values to be inserted when a user is added +	* +	* @event core.user_add_modify_data +	* @var array	sql_ary		Array of data to be inserted when a user is added +	* @since 3.1-A1 +	*/ +	$vars = array('sql_ary'); +	extract($phpbb_dispatcher->trigger_event('core.user_add_modify_data', compact($vars))); +  	$sql = 'INSERT INTO ' . USERS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);  	$db->sql_query($sql); @@ -261,8 +281,9 @@ function user_add($user_row, $cp_data = false)  			include_once($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx);  		} +		$cp = new custom_profile();  		$sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' . -			$db->sql_build_array('INSERT', custom_profile::build_insert_sql_array($cp_data)); +			$db->sql_build_array('INSERT', $cp->build_insert_sql_array($cp_data));  		$db->sql_query($sql);  	} @@ -290,8 +311,10 @@ function user_add($user_row, $cp_data = false)  		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; +			global $phpbb_log; + +			// Because these actions only fill the log unneccessarily we skip the add_log() entry. +			$phpbb_log->disable('admin');  			// Add user to "newly registered users" group and set to default group if admin specified so.  			if ($config['new_member_group_default']) @@ -304,7 +327,7 @@ function user_add($user_row, $cp_data = false)  				group_user_add($add_group_id, $user_id);  			} -			unset($GLOBALS['skip_add_log']); +			$phpbb_log->enable('admin');  		}  	} @@ -330,28 +353,55 @@ function user_add($user_row, $cp_data = false)  /**  * Remove User +* @param $mode Either 'retain' or 'remove'  */ -function user_delete($mode, $user_id, $post_username = false) +function user_delete($mode, $user_ids, $retain_username = true)  { -	global $cache, $config, $db, $user, $auth; +	global $cache, $config, $db, $user, $auth, $phpbb_dispatcher;  	global $phpbb_root_path, $phpEx; +	$db->sql_transaction('begin'); + +	$user_rows = array(); +	if (!is_array($user_ids)) +	{ +		$user_ids = array($user_ids); +	} + +	$user_id_sql = $db->sql_in_set('user_id', $user_ids); +  	$sql = 'SELECT *  		FROM ' . USERS_TABLE . ' -		WHERE user_id = ' . $user_id; +		WHERE ' . $user_id_sql;  	$result = $db->sql_query($sql); -	$user_row = $db->sql_fetchrow($result); +	while ($row = $db->sql_fetchrow($result)) +	{ +		$user_rows[(int) $row['user_id']] = $row; +	}  	$db->sql_freeresult($result); -	if (!$user_row) +	if (empty($user_rows))  	{  		return false;  	} +	/** +	* Event before a user is deleted +	* +	* @event core.delete_user_before +	* @var	string	mode		Mode of deletion (retain/delete posts) +	* @var	array	user_ids	IDs of the deleted user +	* @var	mixed	retain_username	True if username should be retained +	*				or false if not +	* @since 3.1-A1 +	*/ +	$vars = array('mode', 'user_ids', 'retain_username'); +	extract($phpbb_dispatcher->trigger_event('core.delete_user_before', compact($vars))); +  	// 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 . ' +		WHERE ' . $db->sql_in_set('r.user_id', $user_ids) . '  			AND p.post_id = r.post_id';  	$result = $db->sql_query($sql); @@ -405,97 +455,124 @@ function user_delete($mode, $user_id, $post_username = false)  	}  	// Remove reports -	$db->sql_query('DELETE FROM ' . REPORTS_TABLE . ' WHERE user_id = ' . $user_id); +	$db->sql_query('DELETE FROM ' . REPORTS_TABLE . ' WHERE ' . $user_id_sql); -	if ($user_row['user_avatar'] && $user_row['user_avatar_type'] == AVATAR_UPLOAD) -	{ -		avatar_delete('user', $user_row); -	} +	$num_users_delta = 0; -	switch ($mode) +	// Some things need to be done in the loop (if the query changes based +	// on which user is currently being deleted) +	$added_guest_posts = 0; +	foreach ($user_rows as $user_id => $user_row)  	{ -		case 'retain': - -			$db->sql_transaction('begin'); - -			if ($post_username === false) -			{ -				$post_username = $user->lang['GUEST']; -			} +		if ($user_row['user_avatar'] && $user_row['user_avatar_type'] == 'avatar.driver.upload') +		{ +			avatar_delete('user', $user_row); +		} -			// 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); +		// Decrement number of users if this user is active +		if ($user_row['user_type'] != USER_INACTIVE && $user_row['user_type'] != USER_IGNORE) +		{ +			--$num_users_delta; +		} -				$sql = 'UPDATE ' . POSTS_TABLE . ' -					SET poster_id = ' . ANONYMOUS . ", post_username = '" . $db->sql_escape($post_username) . "' -					WHERE poster_id = $user_id"; -				$db->sql_query($sql); +		switch ($mode) +		{ +			case 'retain': +				if ($retain_username === false) +				{ +					$post_username = $user->lang['GUEST']; +				} +				else +				{ +					$post_username = $user_row['username']; +				} -				$sql = 'UPDATE ' . POSTS_TABLE . ' -					SET post_edit_user = ' . ANONYMOUS . " -					WHERE post_edit_user = $user_id"; -				$db->sql_query($sql); +				// If the user is inactive and newly registered +				// we assume no posts from the user, and save +				// the queries +				if ($user_row['user_type'] != USER_INACTIVE || $user_row['user_inactive_reason'] != INACTIVE_REGISTER || $user_row['user_posts']) +				{ +					// When we delete these users and retain the posts, we must assign all the data to the guest user +					$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 ' . 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 ' . POSTS_TABLE . ' +						SET poster_id = ' . ANONYMOUS . ", post_username = '" . $db->sql_escape($post_username) . "' +						WHERE poster_id = $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 ' . 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 ' . ATTACHMENTS_TABLE . ' -					SET poster_id = ' . ANONYMOUS . " -					WHERE poster_id = $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); -				// Since we change every post by this author, we need to count this amount towards the anonymous user +					// 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); +					if ($user_row['user_posts']) +					{ +						$added_guest_posts += $user_row['user_posts']; +					}  				} -			} - -			$db->sql_transaction('commit'); +			break; -		break; +			case 'remove': +				// there is nothing variant specific to deleting posts +			break; +		} +	} -		case 'remove': +	if ($num_users_delta != 0) +	{ +		set_config_count('num_users', $num_users_delta, true); +	} -			if (!function_exists('delete_posts')) -			{ -				include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); -			} +	// Now do the invariant tasks +	// all queries performed in one call of this function are in a single transaction +	// so this is kosher +	if ($mode == 'retain') +	{ +		// Assign more data to the Anonymous user +		$sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' +			SET poster_id = ' . ANONYMOUS . ' +			WHERE ' . $db->sql_in_set('poster_id', $user_ids); +		$db->sql_query($sql); -			// Delete posts, attachments, etc. -			delete_posts('poster_id', $user_id); +		$sql = 'UPDATE ' . POSTS_TABLE . ' +			SET post_edit_user = ' . ANONYMOUS . ' +			WHERE ' . $db->sql_in_set('post_edit_user', $user_ids); +		$db->sql_query($sql); -		break; +		$sql = 'UPDATE ' . USERS_TABLE . ' +			SET user_posts = user_posts + ' . $added_guest_posts . ' +			WHERE user_id = ' . ANONYMOUS; +		$db->sql_query($sql);  	} +	else if ($mode == 'remove') +	{ +		if (!function_exists('delete_posts')) +		{ +			include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); +		} -	$db->sql_transaction('begin'); +		// Delete posts, attachments, etc. +		// delete_posts can handle any number of IDs in its second argument +		delete_posts('poster_id', $user_ids); +	}  	$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); +	// Delete the miscellaneous (non-post) data for the user  	foreach ($table_ary as $table)  	{  		$sql = "DELETE FROM $table -			WHERE user_id = $user_id"; +			WHERE " . $user_id_sql;  		$db->sql_query($sql);  	} @@ -503,29 +580,29 @@ function user_delete($mode, $user_id, $post_username = false)  	// Delete user log entries about this user  	$sql = 'DELETE FROM ' . LOG_TABLE . ' -		WHERE reportee_id = ' . $user_id; +		WHERE ' . $db->sql_in_set('reportee_id', $user_ids);  	$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; +		WHERE ' . $user_id_sql;  	$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; +		WHERE ' . $user_id_sql . ' +			OR ' . $db->sql_in_set('zebra_id', $user_ids);  	$db->sql_query($sql);  	// Delete the user_id from the banlist  	$sql = 'DELETE FROM ' . BANLIST_TABLE . ' -		WHERE ban_userid = ' . $user_id; +		WHERE ' . $db->sql_in_set('ban_userid', $user_ids);  	$db->sql_query($sql);  	// Delete the user_id from the session table  	$sql = 'DELETE FROM ' . SESSIONS_TABLE . ' -		WHERE session_user_id = ' . $user_id; +		WHERE ' . $db->sql_in_set('session_user_id', $user_ids);  	$db->sql_query($sql);  	// Clean the private messages tables from the user @@ -533,22 +610,29 @@ function user_delete($mode, $user_id, $post_username = false)  	{  		include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);  	} -	phpbb_delete_user_pms($user_id); +	phpbb_delete_users_pms($user_ids);  	$db->sql_transaction('commit'); +	/** +	* Event after a user is deleted +	* +	* @event core.delete_user_after +	* @var	string	mode		Mode of deletion (retain/delete posts) +	* @var	array	user_ids	IDs of the deleted user +	* @var	mixed	retain_username	True if username should be retained +	*				or false if not +	* @since 3.1-A1 +	*/ +	$vars = array('mode', 'user_ids', 'retain_username'); +	extract($phpbb_dispatcher->trigger_event('core.delete_user_after', compact($vars))); +  	// Reset newest user info if appropriate -	if ($config['newest_user_id'] == $user_id) +	if (in_array($config['newest_user_id'], $user_ids))  	{  		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;  } @@ -678,8 +762,10 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas  			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); +				$ban_end = max($current_time, $user->create_datetime() +					->setDate((int) $ban_other[0], (int) $ban_other[1], (int) $ban_other[2]) +					->setTime(0, 0, 0) +					->getTimestamp() + $user->timezone->getOffset(new DateTime('UTC')));  			}  			else  			{ @@ -1398,6 +1484,22 @@ function validate_language_iso_name($lang_iso)  }  /** +* Validate Timezone Name +* +* Tests whether a timezone name is valid +* +* @param string $timezone	The timezone 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 phpbb_validate_timezone($timezone) +{ +	return (in_array($timezone, phpbb_get_timezone_identifiers($timezone))) ? false : 'TIMEZONE_INVALID'; +} + +/**  * 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 @@ -1428,7 +1530,7 @@ function validate_username($username, $allowed_username = false)  	$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) +	if (phpbb_pcre_utf8_support())  	{  		$pcre = true;  	} @@ -1565,7 +1667,7 @@ function validate_password($password)  	$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) +	if (phpbb_pcre_utf8_support())  	{  		$upp = '\p{Lu}';  		$low = '\p{Ll}'; @@ -1710,15 +1812,15 @@ function validate_jabber($jid)  		return false;  	} -	$seperator_pos = strpos($jid, '@'); +	$separator_pos = strpos($jid, '@'); -	if ($seperator_pos === false) +	if ($separator_pos === false)  	{  		return 'WRONG_DATA';  	} -	$username = substr($jid, 0, $seperator_pos); -	$realm = substr($jid, $seperator_pos + 1); +	$username = substr($jid, 0, $separator_pos); +	$realm = substr($jid, $separator_pos + 1);  	if (strlen($username) == 0 || strlen($realm) < 3)  	{ @@ -1965,6 +2067,7 @@ function avatar_delete($mode, $row, $clean_db = false)  		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); @@ -1975,133 +2078,6 @@ function avatar_delete($mode, $row, $clean_db = 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) @@ -2124,358 +2100,111 @@ function get_avatar_filename($avatar_entry)  }  /** -* Avatar Gallery +* Returns an explanation string with maximum avatar settings +* +* @return string  */ -function avatar_gallery($category, $avatar_select, $items_per_column, $block_var = 'avatar_row') +function phpbb_avatar_explanation_string()  { -	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()); -		} +	global $config, $user; -		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; +	return $user->lang('AVATAR_EXPLAIN', +		$user->lang('PIXELS', (int) $config['avatar_max_width']), +		$user->lang('PIXELS', (int) $config['avatar_max_height']), +		round($config['avatar_filesize'] / 1024));  } +// +// Usergroup functions +//  /** -* 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 +* 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 avatar_process_user(&$error, $custom_userdata = false, $can_upload = null) +function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow_desc_bbcode = false, $allow_desc_urls = false, $allow_desc_smilies = false)  { -	global $config, $phpbb_root_path, $auth, $user, $db; +	global $phpbb_root_path, $config, $db, $user, $file_upload, $phpbb_container; -	$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; -	} +	$error = array(); -	$sql_ary = 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'); -	if ($custom_userdata === false) -	{ -		$userdata = &$user->data; -	} -	else +	// Check data. Limit group name length. +	if (!utf8_strlen($name) || utf8_strlen($name) > 60)  	{ -		$userdata = &$custom_userdata; +		$error[] = (!utf8_strlen($name)) ? $user->lang['GROUP_ERR_USERNAME'] : $user->lang['GROUP_ERR_USER_LONG'];  	} -	$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)) +	$err = group_validate_groupname($group_id, $name); +	if (!empty($err))  	{ -		$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; +		$error[] = $user->lang[$err];  	} -	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']) +	if (!in_array($type, array(GROUP_OPEN, GROUP_CLOSED, GROUP_HIDDEN, GROUP_SPECIAL, GROUP_FREE)))  	{ -		list($sql_ary['user_avatar_type'], $sql_ary['user_avatar'], $sql_ary['user_avatar_width'], $sql_ary['user_avatar_height']) = avatar_remote($data, $error); +		$error[] = $user->lang['GROUP_ERR_TYPE'];  	} -	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; +	$group_teampage = !empty($group_attributes['group_teampage']); +	unset($group_attributes['group_teampage']); -		// 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'])) +	if (!sizeof($error))  	{ -		// Only update the dimensions +		$current_legend = \phpbb\groupposition\legend::GROUP_DISABLED; +		$current_teampage = \phpbb\groupposition\teampage::GROUP_DISABLED; -		if (empty($data['width']) || empty($data['height'])) +		$legend = $phpbb_container->get('groupposition.legend'); +		$teampage = $phpbb_container->get('groupposition.teampage'); +		if ($group_id)  		{ -			if ($dims = avatar_get_dimensions($userdata['user_avatar'], $userdata['user_avatar_type'], $error, $data['width'], $data['height'])) +			try  			{ -				list($guessed_x, $guessed_y) = $dims; -				if (empty($data['width'])) -				{ -					$data['width'] = $guessed_x; -				} -				if (empty($data['height'])) -				{ -					$data['height'] = $guessed_y; -				} +				$current_legend = $legend->get_group_value($group_id); +				$current_teampage = $teampage->get_group_value($group_id);  			} -		} -		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']) +			catch (\phpbb\groupposition\exception $exception)  			{ -				$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']); +				trigger_error($user->lang($exception->getMessage()));  			}  		} -		if (!sizeof($error)) +		if (!empty($group_attributes['group_legend']))  		{ -			if ($config['avatar_min_width'] || $config['avatar_min_height']) +			if (($group_id && ($current_legend == \phpbb\groupposition\legend::GROUP_DISABLED)) || !$group_id)  			{ -				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']); -				} +				// Old group currently not in the legend or new group, add at the end. +				$group_attributes['group_legend'] = 1 + $legend->get_group_count(); +			} +			else +			{ +				// Group stayes in the legend +				$group_attributes['group_legend'] = $current_legend;  			}  		} - -		if (!sizeof($error)) +		else if ($group_id && ($current_legend != \phpbb\groupposition\legend::GROUP_DISABLED))  		{ -			$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'])) +			// Group is removed from the legend +			try  			{ -				$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); -					} -				} +				$legend->delete_group($group_id, true);  			} - -			$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); - +			catch (\phpbb\groupposition\exception $exception) +			{ +				trigger_error($user->lang($exception->getMessage())); +			} +			$group_attributes['group_legend'] = \phpbb\groupposition\legend::GROUP_DISABLED; +		} +		else +		{ +			$group_attributes['group_legend'] = \phpbb\groupposition\legend::GROUP_DISABLED;  		} -	} - -	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']; -	} +		// Unset the objects, we don't need them anymore. +		unset($legend); -	if (!sizeof($error)) -	{  		$user_ary = array();  		$sql_ary = array(  			'group_name'			=> (string) $name, @@ -2515,12 +2244,12 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow  			}  			$db->sql_freeresult($result); -			if (isset($sql_ary['group_avatar']) && !$sql_ary['group_avatar']) +			if (isset($sql_ary['group_avatar']))  			{  				remove_default_avatar($group_id, $user_ary);  			} -			if (isset($sql_ary['group_rank']) && !$sql_ary['group_rank']) +			if (isset($sql_ary['group_rank']))  			{  				remove_default_rank($group_id, $user_ary);  			} @@ -2568,16 +2297,55 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow  			$db->sql_query($sql);  		} +		// Remove the group from the teampage, only if unselected and we are editing a group, +		// which is currently displayed. +		if (!$group_teampage && $group_id && $current_teampage != \phpbb\groupposition\teampage::GROUP_DISABLED) +		{ +			try +			{ +				$teampage->delete_group($group_id); +			} +			catch (\phpbb\groupposition\exception $exception) +			{ +				trigger_error($user->lang($exception->getMessage())); +			} +		} +  		if (!$group_id)  		{  			$group_id = $db->sql_nextid(); -			if (isset($sql_ary['group_avatar_type']) && $sql_ary['group_avatar_type'] == AVATAR_UPLOAD) +			if (isset($sql_ary['group_avatar_type']) && $sql_ary['group_avatar_type'] == 'avatar.driver.upload')  			{  				group_correct_avatar($group_id, $sql_ary['group_avatar']);  			}  		} +		try +		{ +			if ($group_teampage && $current_teampage == \phpbb\groupposition\teampage::GROUP_DISABLED) +			{ +				$teampage->add_group($group_id); +			} + +			if ($group_teampage) +			{ +				if ($current_teampage == \phpbb\groupposition\teampage::GROUP_DISABLED) +				{ +					$teampage->add_group($group_id); +				} +			} +			else if ($group_id && ($current_teampage != \phpbb\groupposition\teampage::GROUP_DISABLED)) +			{ +				$teampage->delete_group($group_id); +			} +		} +		catch (\phpbb\groupposition\exception $exception) +		{ +			trigger_error($user->lang($exception->getMessage())); +		} +		unset($teampage); +  		// Set user attributes  		$sql_ary = array();  		if (sizeof($group_attributes)) @@ -2648,7 +2416,7 @@ function avatar_remove_db($avatar_name)  	$sql = 'UPDATE ' . USERS_TABLE . "  		SET user_avatar = '', -		user_avatar_type = 0 +		user_avatar_type = ''  		WHERE user_avatar = '" . $db->sql_escape($avatar_name) . '\'';  	$db->sql_query($sql);  } @@ -2659,7 +2427,7 @@ function avatar_remove_db($avatar_name)  */  function group_delete($group_id, $group_name = false)  { -	global $db, $phpbb_root_path, $phpEx; +	global $db, $cache, $auth, $user, $phpbb_root_path, $phpEx, $phpbb_dispatcher, $phpbb_container;  	if (!$group_name)  	{ @@ -2700,6 +2468,33 @@ function group_delete($group_id, $group_name = false)  	}  	while ($start); +	// Delete group from legend and teampage +	try +	{ +		$legend = $phpbb_container->get('groupposition.legend'); +		$legend->delete_group($group_id); +		unset($legend); +	} +	catch (\phpbb\groupposition\exception $exception) +	{ +		// The group we want to delete does not exist. +		// No reason to worry, we just continue the deleting process. +		//trigger_error($user->lang($exception->getMessage())); +	} + +	try +	{ +		$teampage = $phpbb_container->get('groupposition.teampage'); +		$teampage->delete_group($group_id); +		unset($teampage); +	} +	catch (\phpbb\groupposition\exception $exception) +	{ +		// The group we want to delete does not exist. +		// No reason to worry, we just continue the deleting process. +		//trigger_error($user->lang($exception->getMessage())); +	} +  	// Delete group  	$sql = 'DELETE FROM ' . GROUPS_TABLE . "  		WHERE group_id = $group_id"; @@ -2710,13 +2505,24 @@ function group_delete($group_id, $group_name = false)  		WHERE group_id = $group_id";  	$db->sql_query($sql); +	/** +	* Event after a group is deleted +	* +	* @event core.delete_group_after +	* @var	int		group_id	ID of the deleted group +	* @var	string	group_name	Name of the deleted group +	* @since 3.1-A1 +	*/ +	$vars = array('group_id', 'group_name'); +	extract($phpbb_dispatcher->trigger_event('core.delete_group_after', compact($vars))); +  	// Re-cache moderators -	if (!function_exists('cache_moderators')) +	if (!function_exists('phpbb_cache_moderators'))  	{  		include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);  	} -	cache_moderators(); +	phpbb_cache_moderators($db, $cache, $auth);  	add_log('admin', 'LOG_GROUP_DELETE', $group_name); @@ -2731,7 +2537,7 @@ function group_delete($group_id, $group_name = false)  */  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; +	global $db, $auth, $phpbb_container;  	// We need both username and user_id info  	$result = user_get_id_name($user_id_ary, $username_ary); @@ -2819,6 +2625,20 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false,  	group_update_listings($group_id); +	if ($pending) +	{ +		$phpbb_notifications = $phpbb_container->get('notification_manager'); + +		foreach ($add_id_ary as $user_id) +		{ +			$phpbb_notifications->add_notifications('group_request', array( +				'group_id'		=> $group_id, +				'user_id'		=> $user_id, +				'group_name'	=> $group_name, +			)); +		} +	} +  	// Return false - no error  	return false;  } @@ -2832,7 +2652,7 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false,  */  function group_user_del($group_id, $user_id_ary = false, $username_ary = false, $group_name = false)  { -	global $db, $auth, $config; +	global $db, $auth, $config, $phpbb_dispatcher, $phpbb_container;  	if ($config['coppa_enable'])  	{ @@ -2931,6 +2751,19 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false,  	}  	unset($special_group_data); +	/** +	* Event before users are removed from a group +	* +	* @event core.group_delete_user_before +	* @var	int		group_id		ID of the group from which users are deleted +	* @var	string	group_name		Name of the group +	* @var	array	user_id_ary		IDs of the users which are removed +	* @var	array	username_ary	names of the users which are removed +	* @since 3.1-A1 +	*/ +	$vars = array('group_id', 'group_name', 'user_id_ary', 'username_ary'); +	extract($phpbb_dispatcher->trigger_event('core.group_delete_user_before', compact($vars))); +  	$sql = 'DELETE FROM ' . USER_GROUP_TABLE . "  		WHERE group_id = $group_id  			AND " . $db->sql_in_set('user_id', $user_id_ary); @@ -2953,6 +2786,10 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false,  	group_update_listings($group_id); +	$phpbb_notifications = $phpbb_container->get('notification_manager'); + +	$phpbb_notifications->delete_notifications('group_request', $user_id_ary, $group_id); +  	// Return false - no error  	return false;  } @@ -2989,12 +2826,12 @@ function remove_default_avatar($group_id, $user_ids)  	$sql = 'UPDATE ' . USERS_TABLE . "  		SET user_avatar = '', -			user_avatar_type = 0, +			user_avatar_type = '',  			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); +			AND user_avatar = '" . $db->sql_escape($row['group_avatar']) . "' +			AND " . $db->sql_in_set('user_id', $user_ids);  	$db->sql_query($sql);  } @@ -3031,9 +2868,9 @@ function remove_default_rank($group_id, $user_ids)  	$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); +			AND user_rank <> 0 +			AND user_rank = ' . (int)$row['group_rank'] . ' +			AND ' . $db->sql_in_set('user_id', $user_ids);  	$db->sql_query($sql);  } @@ -3042,7 +2879,7 @@ function remove_default_rank($group_id, $user_ids)  */  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; +	global $db, $auth, $phpbb_root_path, $phpEx, $config, $phpbb_container;  	// We need both username and user_id info  	$result = user_get_id_name($user_id_ary, $username_ary); @@ -3062,7 +2899,8 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna  		case 'demote':  		case 'promote': -			$sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . " +			$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); @@ -3094,11 +2932,10 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna  					AND ' . $db->sql_in_set('ug.user_id', $user_id_ary);  			$result = $db->sql_query($sql); -			$user_id_ary = $email_users = array(); +			$user_id_ary = array();  			while ($row = $db->sql_fetchrow($result))  			{  				$user_id_ary[] = $row['user_id']; -				$email_users[] = $row;  			}  			$db->sql_freeresult($result); @@ -3113,27 +2950,14 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna  					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']); +			$phpbb_notifications = $phpbb_container->get('notification_manager'); -				$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(); +			$phpbb_notifications->add_notifications('group_request_approved', array( +				'user_ids'		=> $user_id_ary, +				'group_id'		=> $group_id, +				'group_name'	=> $group_name, +			)); +			$phpbb_notifications->delete_notifications('group_request', $user_id_ary, $group_id);  			$log = 'LOG_USERS_APPROVED';  		break; @@ -3160,7 +2984,8 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna  				return 'NO_USERS';  			} -			$sql = 'SELECT user_id, group_id FROM ' . USERS_TABLE . ' +			$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); @@ -3248,7 +3073,7 @@ function group_validate_groupname($group_id, $group_name)  */  function group_set_user_default($group_id, $user_id_ary, $group_attributes = false, $update_listing = false)  { -	global $cache, $db; +	global $phpbb_container, $db, $phpbb_dispatcher;  	if (empty($user_id_ary))  	{ @@ -3259,7 +3084,7 @@ function group_set_user_default($group_id, $user_id_ary, $group_attributes = fal  		'group_colour'			=> 'string',  		'group_rank'			=> 'int',  		'group_avatar'			=> 'string', -		'group_avatar_type'		=> 'int', +		'group_avatar_type'		=> 'string',  		'group_avatar_width'	=> 'int',  		'group_avatar_height'	=> 'int',  	); @@ -3294,45 +3119,69 @@ function group_set_user_default($group_id, $user_id_ary, $group_attributes = fal  		}  	} -	// 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'])) +	$updated_sql_ary = $sql_ary; + +	// Before we update the user attributes, we will update the rank for users that don't have a custom rank +	if (isset($sql_ary['user_rank']))  	{ -		// 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); +		$sql = 'UPDATE ' . USERS_TABLE . ' +			SET ' . $db->sql_build_array('UPDATE', array('user_rank' => $sql_ary['user_rank'])) . ' +			WHERE user_rank = 0 +				AND ' . $db->sql_in_set('user_id', $user_id_ary); +		$db->sql_query($sql); +		unset($sql_ary['user_rank']); +	} -		while ($row = $db->sql_fetchrow($result)) +	// Before we update the user attributes, we will update the avatar for users that don't have a custom avatar +	$avatar_options = array('user_avatar', 'user_avatar_type', 'user_avatar_height', 'user_avatar_width'); + +	if (isset($sql_ary['user_avatar'])) +	{ +		$avatar_sql_ary = array(); +		foreach ($avatar_options as $avatar_option)  		{ -			avatar_delete('user', $row); -		} -		$db->sql_freeresult($result); +			if (isset($sql_ary[$avatar_option])) +			{ +				$avatar_sql_ary[$avatar_option] = $sql_ary[$avatar_option]; +				} +			} + +		$sql = 'UPDATE ' . USERS_TABLE . ' +			SET ' . $db->sql_build_array('UPDATE', $avatar_sql_ary) . " +			WHERE user_avatar = '' +				AND " . $db->sql_in_set('user_id', $user_id_ary); +		$db->sql_query($sql);  	} -	else + +	// Remove the avatar options, as we already updated them +	foreach ($avatar_options as $avatar_option)  	{ -		unset($sql_ary['user_avatar_type']); -		unset($sql_ary['user_avatar_height']); -		unset($sql_ary['user_avatar_width']); +		unset($sql_ary[$avatar_option]);  	} -	$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 (!empty($sql_ary)) +	{ +		$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']) . "' +		$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']) . "' +		$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']) . "' +		$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); @@ -3344,13 +3193,30 @@ function group_set_user_default($group_id, $user_id_ary, $group_attributes = fal  		}  	} +	// Make all values available for the event +	$sql_ary = $updated_sql_ary; + +	/** +	* Event when the default group is set for an array of users +	* +	* @event core.user_set_default_group +	* @var	int		group_id			ID of the group +	* @var	array	user_id_ary			IDs of the users +	* @var	array	group_attributes	Group attributes which were changed +	* @var	array	update_listing		Update the list of moderators and foes +	* @var	array	sql_ary				User attributes which were changed +	* @since 3.1-A1 +	*/ +	$vars = array('group_id', 'user_id_ary', 'group_attributes', 'update_listing', 'sql_ary'); +	extract($phpbb_dispatcher->trigger_event('core.user_set_default_group', compact($vars))); +  	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); +	$phpbb_container->get('cache.driver')->destroy('sql', MODERATOR_CACHE_TABLE);  }  /** @@ -3449,7 +3315,7 @@ function group_memberships($group_id_ary = false, $user_id_ary = false, $return_  */  function group_update_listings($group_id)  { -	global $auth; +	global $db, $cache, $auth;  	$hold_ary = $auth->acl_group_raw_data($group_id, array('a_', 'm_')); @@ -3491,22 +3357,22 @@ function group_update_listings($group_id)  	if ($mod_permissions)  	{ -		if (!function_exists('cache_moderators')) +		if (!function_exists('phpbb_cache_moderators'))  		{  			global $phpbb_root_path, $phpEx;  			include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);  		} -		cache_moderators(); +		phpbb_cache_moderators($db, $cache, $auth);  	}  	if ($mod_permissions || $admin_permissions)  	{ -		if (!function_exists('update_foes')) +		if (!function_exists('phpbb_update_foes'))  		{  			global $phpbb_root_path, $phpEx;  			include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);  		} -		update_foes(array($group_id)); +		phpbb_update_foes($db, $auth, array($group_id));  	}  } @@ -3615,5 +3481,3 @@ function phpbb_get_banned_user_ids($user_ids = array())  	return $banned_ids_list;  } - -?>
\ No newline at end of file | 
