diff options
Diffstat (limited to 'phpBB/includes/functions_user.php')
| -rw-r--r-- | phpBB/includes/functions_user.php | 589 | 
1 files changed, 383 insertions, 206 deletions
| diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 6682622d94..e1c687551b 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -1,9 +1,13 @@  <?php  /**  * -* @package phpBB3 -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file.  *  */ @@ -40,13 +44,13 @@ function user_get_id_name(&$user_id_ary, &$username_ary, $user_type = false)  	$which_ary = ($user_id_ary) ? 'user_id_ary' : 'username_ary'; -	if ($$which_ary && !is_array($$which_ary)) +	if (${$which_ary} && !is_array(${$which_ary}))  	{ -		$$which_ary = 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); +	$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(); @@ -85,7 +89,7 @@ function user_get_id_name(&$user_id_ary, &$username_ary, $user_type = false)  */  function update_last_username()  { -	global $db; +	global $config, $db;  	// Get latest username  	$sql = 'SELECT user_id, username, user_colour @@ -98,9 +102,9 @@ function update_last_username()  	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); +		$config->set('newest_user_id', $row['user_id'], false); +		$config->set('newest_username', $row['username'], false); +		$config->set('newest_user_colour', $row['user_colour'], false);  	}  } @@ -134,7 +138,7 @@ function user_update_name($old_name, $new_name)  	if ($config['newest_username'] == $old_name)  	{ -		set_config('newest_username', $new_name, true); +		$config->set('newest_username', $new_name, false);  	}  	/** @@ -143,7 +147,7 @@ function user_update_name($old_name, $new_name)  	* @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 +	* @since 3.1.0-a1  	*/  	$vars = array('old_name', 'new_name');  	extract($phpbb_dispatcher->trigger_event('core.update_username', compact($vars))); @@ -157,11 +161,12 @@ function user_update_name($old_name, $new_name)  *  * @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 +* @param array $notifications_data The notifications settings for the new user  * @return the new user's ID.  */ -function user_add($user_row, $cp_data = false) +function user_add($user_row, $cp_data = false, $notifications_data = null)  { -	global $db, $user, $auth, $config, $phpbb_root_path, $phpEx; +	global $db, $config;  	global $phpbb_dispatcher, $phpbb_container;  	if (empty($user_row['username']) || !isset($user_row['group_id']) || !isset($user_row['user_email']) || !isset($user_row['user_type'])) @@ -180,7 +185,6 @@ function user_add($user_row, $cp_data = false)  		'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'], @@ -258,10 +262,13 @@ 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	user_row		Array of user details submited to user_add +	* @var array	cp_data			Array of Custom profile fields submited to user_add  	* @var array	sql_ary		Array of data to be inserted when a user is added -	* @since 3.1-A1 +	* @since 3.1.0-a1 +	* @change 3.1.0-b5  	*/ -	$vars = array('sql_ary'); +	$vars = array('user_row', 'cp_data', '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); @@ -274,6 +281,7 @@ function user_add($user_row, $cp_data = false)  	{  		$cp_data['user_id'] = (int) $user_id; +		/* @var $cp \phpbb\profilefields\manager */  		$cp = $phpbb_container->get('profilefields.manager');  		$sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' .  			$db->sql_build_array('INSERT', $cp->build_insert_sql_array($cp_data)); @@ -306,7 +314,7 @@ function user_add($user_row, $cp_data = false)  		{  			global $phpbb_log; -			// Because these actions only fill the log unneccessarily we skip the add_log() entry. +			// Because these actions only fill the log unnecessarily, we disable it  			$phpbb_log->disable('admin');  			// Add user to "newly registered users" group and set to default group if admin specified so. @@ -327,9 +335,9 @@ function user_add($user_row, $cp_data = false)  	// 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); +		$config->set('newest_user_id', $user_id, false); +		$config->set('newest_username', $user_row['username'], false); +		$config->increment('num_users', 1, false);  		$sql = 'SELECT group_colour  			FROM ' . GROUPS_TABLE . ' @@ -338,19 +346,61 @@ function user_add($user_row, $cp_data = false)  		$row = $db->sql_fetchrow($result);  		$db->sql_freeresult($result); -		set_config('newest_user_colour', $row['group_colour'], true); +		$config->set('newest_user_colour', $row['group_colour'], false); +	} + +	// Use default notifications settings if notifications_data is not set +	if ($notifications_data === null) +	{ +		$notifications_data = array( +			array( +				'item_type'	=> 'notification.type.post', +				'method'	=> 'notification.method.email', +			), +			array( +				'item_type'	=> 'notification.type.topic', +				'method'	=> 'notification.method.email', +			), +		); +	} + +	// Subscribe user to notifications if necessary +	if (!empty($notifications_data)) +	{ +		/* @var $phpbb_notifications \phpbb\notification\manager */ +		$phpbb_notifications = $phpbb_container->get('notification_manager'); +		foreach ($notifications_data as $subscription) +		{ +			$phpbb_notifications->add_subscription($subscription['item_type'], 0, $subscription['method'], $user_id); +		}  	} +	/** +	* Event that returns user id, user detals and user CPF of newly registared user +	* +	* @event core.user_add_after +	* @var int		user_id			User id of newly registared user +	* @var array	user_row		Array of user details submited to user_add +	* @var array	cp_data			Array of Custom profile fields submited to user_add +	* @since 3.1.0-b5 +	*/ +	$vars = array('user_id', 'user_row', 'cp_data'); +	extract($phpbb_dispatcher->trigger_event('core.user_add_after', compact($vars))); +  	return $user_id;  }  /** -* Remove User -* @param $mode Either 'retain' or 'remove' -*/ + * Remove User + * + * @param string	$mode		Either 'retain' or 'remove' + * @param mixed		$user_ids	Either an array of integers or an integer + * @param bool		$retain_username + * @return bool + */  function user_delete($mode, $user_ids, $retain_username = true)  { -	global $cache, $config, $db, $user, $auth, $phpbb_dispatcher; +	global $cache, $config, $db, $user, $phpbb_dispatcher, $phpbb_container;  	global $phpbb_root_path, $phpEx;  	$db->sql_transaction('begin'); @@ -386,7 +436,7 @@ function user_delete($mode, $user_ids, $retain_username = true)  	* @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 +	* @since 3.1.0-a1  	*/  	$vars = array('mode', 'user_ids', 'retain_username');  	extract($phpbb_dispatcher->trigger_event('core.delete_user_before', compact($vars))); @@ -452,6 +502,9 @@ function user_delete($mode, $user_ids, $retain_username = true)  	$num_users_delta = 0; +	// Get auth provider collection in case accounts might need to be unlinked +	$provider_collection = $phpbb_container->get('auth.provider_collection'); +  	// 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; @@ -462,6 +515,38 @@ function user_delete($mode, $user_ids, $retain_username = true)  			avatar_delete('user', $user_row);  		} +		// Unlink accounts +		foreach ($provider_collection as $provider_name => $auth_provider) +		{ +			$provider_data = $auth_provider->get_auth_link_data($user_id); + +			if ($provider_data !== null) +			{ +				$link_data = array( +					'user_id' => $user_id, +					'link_method' => 'user_delete', +				); + +				// BLOCK_VARS might contain hidden fields necessary for unlinking accounts +				if (isset($provider_data['BLOCK_VARS']) && is_array($provider_data['BLOCK_VARS'])) +				{ +					foreach ($provider_data['BLOCK_VARS'] as $provider_service) +					{ +						if (!array_key_exists('HIDDEN_FIELDS', $provider_service)) +						{ +							$provider_service['HIDDEN_FIELDS'] = array(); +						} + +						$auth_provider->unlink_account(array_merge($link_data, $provider_service['HIDDEN_FIELDS'])); +					} +				} +				else +				{ +					$auth_provider->unlink_account($link_data); +				} +			} +		} +  		// Decrement number of users if this user is active  		if ($user_row['user_type'] != USER_INACTIVE && $user_row['user_type'] != USER_IGNORE)  		{ @@ -523,7 +608,7 @@ function user_delete($mode, $user_ids, $retain_username = true)  	if ($num_users_delta != 0)  	{ -		set_config_count('num_users', $num_users_delta, true); +		$config->increment('num_users', $num_users_delta, false);  	}  	// Now do the invariant tasks @@ -537,11 +622,6 @@ function user_delete($mode, $user_ids, $retain_username = true)  			WHERE ' . $db->sql_in_set('poster_id', $user_ids);  		$db->sql_query($sql); -		$sql = 'UPDATE ' . POSTS_TABLE . ' -			SET post_edit_user = ' . ANONYMOUS . ' -			WHERE ' . $db->sql_in_set('post_edit_user', $user_ids); -		$db->sql_query($sql); -  		$sql = 'UPDATE ' . USERS_TABLE . '  			SET user_posts = user_posts + ' . $added_guest_posts . '  			WHERE user_id = ' . ANONYMOUS; @@ -571,6 +651,30 @@ function user_delete($mode, $user_ids, $retain_username = true)  	$cache->destroy('sql', MODERATOR_CACHE_TABLE); +	// Change user_id to anonymous for posts edited by this user +	$sql = 'UPDATE ' . POSTS_TABLE . ' +		SET post_edit_user = ' . ANONYMOUS . ' +		WHERE ' . $db->sql_in_set('post_edit_user', $user_ids); +	$db->sql_query($sql); + +	// Change user_id to anonymous for pms edited by this user +	$sql = 'UPDATE ' . PRIVMSGS_TABLE . ' +		SET message_edit_user = ' . ANONYMOUS . ' +		WHERE ' . $db->sql_in_set('message_edit_user', $user_ids); +	$db->sql_query($sql); + +	// Change user_id to anonymous for posts deleted by this user +	$sql = 'UPDATE ' . POSTS_TABLE . ' +		SET post_delete_user = ' . ANONYMOUS . ' +		WHERE ' . $db->sql_in_set('post_delete_user', $user_ids); +	$db->sql_query($sql); + +	// Change user_id to anonymous for topics deleted by this user +	$sql = 'UPDATE ' . TOPICS_TABLE . ' +		SET topic_delete_user = ' . ANONYMOUS . ' +		WHERE ' . $db->sql_in_set('topic_delete_user', $user_ids); +	$db->sql_query($sql); +  	// Delete user log entries about this user  	$sql = 'DELETE FROM ' . LOG_TABLE . '  		WHERE ' . $db->sql_in_set('reportee_id', $user_ids); @@ -605,6 +709,9 @@ function user_delete($mode, $user_ids, $retain_username = true)  	}  	phpbb_delete_users_pms($user_ids); +	$phpbb_notifications = $phpbb_container->get('notification_manager'); +	$phpbb_notifications->delete_notifications('notification.type.admin_activate_user', $user_ids); +  	$db->sql_transaction('commit');  	/** @@ -615,7 +722,7 @@ function user_delete($mode, $user_ids, $retain_username = true)  	* @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 +	* @since 3.1.0-a1  	*/  	$vars = array('mode', 'user_ids', 'retain_username');  	extract($phpbb_dispatcher->trigger_event('core.delete_user_after', compact($vars))); @@ -636,7 +743,7 @@ function user_delete($mode, $user_ids, $retain_username = true)  */  function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL)  { -	global $config, $db, $user, $auth; +	global $config, $db, $user, $auth, $phpbb_dispatcher;  	$deactivated = $activated = 0;  	$sql_statements = array(); @@ -689,6 +796,21 @@ function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL)  	}  	$db->sql_freeresult($result); +	/** +	* Check or modify activated/deactivated users data before submitting it to the database +	* +	* @event core.user_active_flip_before +	* @var	string	mode			User type changing mode, can be: flip|activate|deactivate +	* @var	int		reason			Reason for changing user type, can be: INACTIVE_REGISTER|INACTIVE_PROFILE|INACTIVE_MANUAL|INACTIVE_REMIND +	* @var	int		activated		The number of users to be activated +	* @var	int		deactivated		The number of users to be deactivated +	* @var	array	user_id_ary		Array with user ids to change user type +	* @var	array	sql_statements	Array with users data to submit to the database, keys: user ids, values: arrays with user data +	* @since 3.1.4-RC1 +	*/ +	$vars = array('mode', 'reason', 'activated', 'deactivated', 'user_id_ary', 'sql_statements'); +	extract($phpbb_dispatcher->trigger_event('core.user_active_flip_before', compact($vars))); +  	if (sizeof($sql_statements))  	{  		foreach ($sql_statements as $user_id => $sql_ary) @@ -702,14 +824,29 @@ function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL)  		$auth->acl_clear_prefetch(array_keys($sql_statements));  	} +	/** +	* Perform additional actions after the users have been activated/deactivated +	* +	* @event core.user_active_flip_after +	* @var	string	mode			User type changing mode, can be: flip|activate|deactivate +	* @var	int		reason			Reason for changing user type, can be: INACTIVE_REGISTER|INACTIVE_PROFILE|INACTIVE_MANUAL|INACTIVE_REMIND +	* @var	int		activated		The number of users to be activated +	* @var	int		deactivated		The number of users to be deactivated +	* @var	array	user_id_ary		Array with user ids to change user type +	* @var	array	sql_statements	Array with users data to submit to the database, keys: user ids, values: arrays with user data +	* @since 3.1.4-RC1 +	*/ +	$vars = array('mode', 'reason', 'activated', 'deactivated', 'user_id_ary', 'sql_statements'); +	extract($phpbb_dispatcher->trigger_event('core.user_active_flip_after', compact($vars))); +  	if ($deactivated)  	{ -		set_config_count('num_users', $deactivated * (-1), true); +		$config->increment('num_users', $deactivated * (-1), false);  	}  	if ($activated)  	{ -		set_config_count('num_users', $activated, true); +		$config->increment('num_users', $activated, false);  	}  	// Update latest username @@ -729,7 +866,7 @@ function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL)  */  function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reason, $ban_give_reason = '')  { -	global $db, $user, $auth, $cache; +	global $db, $user, $cache, $phpbb_log;  	// Delete stale bans  	$sql = 'DELETE FROM ' . BANLIST_TABLE . ' @@ -752,7 +889,7 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas  		else  		{  			$ban_other = explode('-', $ban_len_other); -			if (sizeof($ban_other) == 3 && ((int)$ban_other[0] < 9999) && +			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))  			{  				$ban_end = max($current_time, $user->create_datetime() @@ -878,7 +1015,6 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas  						if ($ip_2_counter == 0 && $ip_2_end == 254)  						{  							$ip_2_counter = 256; -							$ip_2_fragment = 256;  							$banlist_ary[] = "$ip_1_counter.*";  						} @@ -891,7 +1027,6 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas  							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.*";  							} @@ -904,7 +1039,6 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas  								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.*";  								} @@ -1119,14 +1253,23 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas  		// 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); +		// Add to admin log, moderator log and user notes +		$phpbb_log->add('admin', $user->data['user_id'], $user->ip, $log_entry . strtoupper($mode), false, array($ban_reason, $ban_list_log)); +		$phpbb_log->add('mod', $user->data['user_id'], $user->ip, $log_entry . strtoupper($mode), false, array( +			'forum_id' => 0, +			'topic_id' => 0, +			$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); +				$phpbb_log->add('user', $user->data['user_id'], $user->ip, $log_entry . strtoupper($mode), false, array( +					'reportee_id' => $user_id, +					$ban_reason, +					$ban_list_log +				));  			}  		} @@ -1146,7 +1289,7 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas  */  function user_unban($mode, $ban)  { -	global $db, $user, $auth, $cache; +	global $db, $user, $cache, $phpbb_log;  	// Delete stale bans  	$sql = 'DELETE FROM ' . BANLIST_TABLE . ' @@ -1204,13 +1347,20 @@ function user_unban($mode, $ban)  		$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); +		$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_UNBAN_' . strtoupper($mode), false, array($l_unban_list)); +		$phpbb_log->add('mod', $user->data['user_id'], $user->ip, 'LOG_UNBAN_' . strtoupper($mode), false, array( +			'forum_id' => 0, +			'topic_id' => 0, +			$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); +				$phpbb_log->add('user', $user->data['user_id'], $user->ip, 'LOG_UNBAN_' . strtoupper($mode), false, array( +					'reportee_id' => $user_id, +					$l_unban_list +				));  			}  		}  	} @@ -1267,7 +1417,7 @@ function user_ipwhois($ip)  	$match = array();  	// Test for referrals from $whois_host to other whois databases, roll on rwhois -	if (preg_match('#ReferralServer: whois://(.+)#im', $ipwhois, $match)) +	if (preg_match('#ReferralServer:[\x20]*whois://(.+)#im', $ipwhois, $match))  	{  		if (strpos($match[1], ':') !== false)  		{ @@ -1326,9 +1476,18 @@ function validate_data($data, $val_ary)  		{  			$function = array_shift($validate);  			array_unshift($validate, $data[$var]); -			$function_prefix = (function_exists('phpbb_validate_' . $function)) ? 'phpbb_validate_' : 'validate_'; -			if ($result = call_user_func_array($function_prefix . $function, $validate)) +			if (is_array($function)) +			{ +				$result = call_user_func_array(array($function[0], 'validate_' . $function[1]), $validate); +			} +			else +			{ +				$function_prefix = (function_exists('phpbb_validate_' . $function)) ? 'phpbb_validate_' : 'validate_'; +				$result = call_user_func_array($function_prefix . $function, $validate); +			} + +			if ($result)  			{  				// 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); @@ -1520,89 +1679,37 @@ function validate_username($username, $allowed_username = false)  		return 'INVALID_CHARS';  	} -	$mbstring = $pcre = false; - -	// generic UTF-8 character types supported? -	if (phpbb_pcre_utf8_support()) -	{ -		$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]+'; -			} +			$regex = '[\p{Lu}\p{Ll}\p{N}]+';  		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]+'; -			} +			$regex = '[-\]_+ [\p{Lu}\p{Ll}\p{N}]+';  		break;  		case 'USERNAME_ASCII':  		default: -			$pcre = true;  			$regex = '[\x01-\x7F]+';  		break;  	} -	if ($pcre) +	if (!preg_match('#^' . $regex . '$#u', $username))  	{ -		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'; -		} +		return 'INVALID_CHARS';  	}  	$sql = 'SELECT username @@ -1657,35 +1764,10 @@ function validate_password($password)  		return false;  	} -	$pcre = $mbstring = false; - -	// generic UTF-8 character types supported? -	if (phpbb_pcre_utf8_support()) -	{ -		$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; -	} - +	$upp = '\p{Lu}'; +	$low = '\p{Ll}'; +	$num = '\p{N}'; +	$sym = '[^\p{Lu}\p{Ll}\p{N}]';  	$chars = array();  	switch ($config['pass_complex']) @@ -1708,24 +1790,11 @@ function validate_password($password)  			$chars[] = $upp;  	} -	if ($pcre) +	foreach ($chars as $char)  	{ -		foreach ($chars as $char) +		if (!preg_match('#' . $char . '#u', $password))  		{ -			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 'INVALID_CHARS';  		}  	} @@ -1733,25 +1802,21 @@ function validate_password($password)  }  /** -* Check to see if email address is banned or already present in the DB +* Check to see if email address is a valid address and contains a MX record  *  * @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) +function phpbb_validate_email($email, $config = null)  { -	global $config, $db, $user; - -	$email = strtolower($email); -	$allowed_email = ($allowed_email === false) ? strtolower($user->data['user_email']) : strtolower($allowed_email); - -	if ($allowed_email == $email) +	if ($config === null)  	{ -		return false; +		global $config;  	} +	$email = strtolower($email); +  	if (!preg_match('/^' . get_preg_expression('email') . '$/i', $email))  	{  		return 'EMAIL_INVALID'; @@ -1769,6 +1834,35 @@ function validate_email($email, $allowed_email = false)  		}  	} +	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_user_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; +	} + +	$validate_email = phpbb_validate_email($email, $config); +	if ($validate_email) +	{ +		return $validate_email; +	} +  	if (($ban_reason = $user->check_ban(false, false, $email, true)) !== false)  	{  		return ($ban_reason === true) ? 'EMAIL_BANNED' : $ban_reason; @@ -2044,12 +2138,12 @@ function phpbb_style_is_active($style_id)  */  function avatar_delete($mode, $row, $clean_db = false)  { -	global $phpbb_root_path, $config, $db, $user; +	global $phpbb_root_path, $config;  	// 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']))) +		if (strpos($row['user_avatar'], 'g') === 0 || (((int) $row['user_avatar'] !== 0) && ((int) $row['user_avatar'] !== (int) $row['user_id'])))  		{  			return false;  		} @@ -2077,7 +2171,6 @@ function get_avatar_filename($avatar_entry)  {  	global $config; -  	if ($avatar_entry[0] === 'g')  	{  		$avatar_group = true; @@ -2117,7 +2210,10 @@ function phpbb_avatar_explanation_string()  */  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, $phpbb_container; +	global $db, $user, $phpbb_container, $phpbb_log; + +	/** @var \phpbb\group\helper $group_helper */ +	$group_helper = $phpbb_container->get('group_helper');  	$error = array(); @@ -2149,8 +2245,12 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow  		$current_legend = \phpbb\groupposition\legend::GROUP_DISABLED;  		$current_teampage = \phpbb\groupposition\teampage::GROUP_DISABLED; +		/* @var $legend \phpbb\groupposition\legend */  		$legend = $phpbb_container->get('groupposition.legend'); + +		/* @var $teampage \phpbb\groupposition\teampage */  		$teampage = $phpbb_container->get('groupposition.teampage'); +  		if ($group_id)  		{  			try @@ -2222,8 +2322,6 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow  		// 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 @@ -2366,8 +2464,8 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow  			group_set_user_default($group_id, $user_ary, $sql_ary);  		} -		$name = ($type == GROUP_SPECIAL) ? $user->lang['G_' . $name] : $name; -		add_log('admin', $log, $name); +		$name = $group_helper->get_name($name); +		$phpbb_log->add('admin', $user->data['user_id'], $user->ip, $log, false, array($name));  		group_update_listings($group_id);  	} @@ -2383,7 +2481,7 @@ function group_correct_avatar($group_id, $old_entry)  {  	global $config, $db, $phpbb_root_path; -	$group_id		= (int)$group_id; +	$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"; @@ -2405,7 +2503,7 @@ function group_correct_avatar($group_id, $old_entry)  */  function avatar_remove_db($avatar_name)  { -	global $config, $db; +	global $db;  	$sql = 'UPDATE ' . USERS_TABLE . "  		SET user_avatar = '', @@ -2420,7 +2518,7 @@ function avatar_remove_db($avatar_name)  */  function group_delete($group_id, $group_name = false)  { -	global $db, $cache, $auth, $user, $phpbb_root_path, $phpEx, $phpbb_dispatcher, $phpbb_container; +	global $db, $cache, $auth, $user, $phpbb_root_path, $phpEx, $phpbb_dispatcher, $phpbb_container, $phpbb_log;  	if (!$group_name)  	{ @@ -2464,6 +2562,7 @@ function group_delete($group_id, $group_name = false)  	// Delete group from legend and teampage  	try  	{ +		/* @var $legend \phpbb\groupposition\legend */  		$legend = $phpbb_container->get('groupposition.legend');  		$legend->delete_group($group_id);  		unset($legend); @@ -2477,6 +2576,7 @@ function group_delete($group_id, $group_name = false)  	try  	{ +		/* @var $teampage \phpbb\groupposition\teampage */  		$teampage = $phpbb_container->get('groupposition.teampage');  		$teampage->delete_group($group_id);  		unset($teampage); @@ -2504,7 +2604,7 @@ function group_delete($group_id, $group_name = false)  	* @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 +	* @since 3.1.0-a1  	*/  	$vars = array('group_id', 'group_name');  	extract($phpbb_dispatcher->trigger_event('core.delete_group_after', compact($vars))); @@ -2517,7 +2617,7 @@ function group_delete($group_id, $group_name = false)  	phpbb_cache_moderators($db, $cache, $auth); -	add_log('admin', 'LOG_GROUP_DELETE', $group_name); +	$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_GROUP_DELETE', false, array($group_name));  	// Return false - no error  	return false; @@ -2530,7 +2630,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, $phpbb_container; +	global $db, $auth, $user, $phpbb_container, $phpbb_log, $phpbb_dispatcher;  	// We need both username and user_id info  	$result = user_get_id_name($user_id_ary, $username_ary); @@ -2607,6 +2707,26 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false,  	// Clear permissions cache of relevant users  	$auth->acl_clear_prefetch($user_id_ary); +	/** +	* Event after users are added to a group +	* +	* @event core.group_add_user_after +	* @var	int	group_id		ID of the group to which users are added +	* @var	string group_name		Name of the group +	* @var	array	user_id_ary		IDs of the users which are added +	* @var	array	username_ary	names of the users which are added +	* @var	int		pending			Pending setting, 1 if user(s) added are pending +	* @since 3.1.7-RC1 +	*/ +	$vars = array( +		'group_id', +		'group_name', +		'user_id_ary', +		'username_ary', +		'pending', +	); +	extract($phpbb_dispatcher->trigger_event('core.group_add_user_after', compact($vars))); +  	if (!$group_name)  	{  		$group_name = get_group_name($group_id); @@ -2614,17 +2734,18 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false,  	$log = ($leader) ? 'LOG_MODS_ADDED' : (($pending) ? 'LOG_USERS_PENDING' : 'LOG_USERS_ADDED'); -	add_log('admin', $log, $group_name, implode(', ', $username_ary)); +	$phpbb_log->add('admin', $user->data['user_id'], $user->ip, $log, false, array($group_name, implode(', ', $username_ary)));  	group_update_listings($group_id);  	if ($pending)  	{ +		/* @var $phpbb_notifications \phpbb\notification\manager */  		$phpbb_notifications = $phpbb_container->get('notification_manager');  		foreach ($add_id_ary as $user_id)  		{ -			$phpbb_notifications->add_notifications('group_request', array( +			$phpbb_notifications->add_notifications('notification.type.group_request', array(  				'group_id'		=> $group_id,  				'user_id'		=> $user_id,  				'group_name'	=> $group_name, @@ -2645,7 +2766,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, $phpbb_dispatcher, $phpbb_container; +	global $db, $auth, $config, $user, $phpbb_dispatcher, $phpbb_container, $phpbb_log;  	if ($config['coppa_enable'])  	{ @@ -2752,7 +2873,7 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false,  	* @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 +	* @since 3.1.0-a1  	*/  	$vars = array('group_id', 'group_name', 'user_id_ary', 'username_ary');  	extract($phpbb_dispatcher->trigger_event('core.group_delete_user_before', compact($vars))); @@ -2765,6 +2886,19 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false,  	// Clear permissions cache of relevant users  	$auth->acl_clear_prefetch($user_id_ary); +	/** +	* Event after users are removed from a group +	* +	* @event core.group_delete_user_after +	* @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.7-RC1 +	*/ +	$vars = array('group_id', 'group_name', 'user_id_ary', 'username_ary'); +	extract($phpbb_dispatcher->trigger_event('core.group_delete_user_after', compact($vars))); +  	if (!$group_name)  	{  		$group_name = get_group_name($group_id); @@ -2774,14 +2908,15 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false,  	if ($group_name)  	{ -		add_log('admin', $log, $group_name, implode(', ', $username_ary)); +		$phpbb_log->add('admin', $user->data['user_id'], $user->ip, $log, false, array($group_name, implode(', ', $username_ary)));  	}  	group_update_listings($group_id); +	/* @var $phpbb_notifications \phpbb\notification\manager */  	$phpbb_notifications = $phpbb_container->get('notification_manager'); -	$phpbb_notifications->delete_notifications('group_request', $user_id_ary, $group_id); +	$phpbb_notifications->delete_notifications('notification.type.group_request', $user_id_ary, $group_id);  	// Return false - no error  	return false; @@ -2808,7 +2943,7 @@ function remove_default_avatar($group_id, $user_ids)  	$sql = 'SELECT *  		FROM ' . GROUPS_TABLE . ' -		WHERE group_id = ' . (int)$group_id; +		WHERE group_id = ' . (int) $group_id;  	$result = $db->sql_query($sql);  	if (!$row = $db->sql_fetchrow($result))  	{ @@ -2849,7 +2984,7 @@ function remove_default_rank($group_id, $user_ids)  	$sql = 'SELECT *  		FROM ' . GROUPS_TABLE . ' -		WHERE group_id = ' . (int)$group_id; +		WHERE group_id = ' . (int) $group_id;  	$result = $db->sql_query($sql);  	if (!$row = $db->sql_fetchrow($result))  	{ @@ -2860,9 +2995,9 @@ function remove_default_rank($group_id, $user_ids)  	$sql = 'UPDATE ' . USERS_TABLE . '  		SET user_rank = 0 -		WHERE group_id = ' . (int)$group_id . ' +		WHERE group_id = ' . (int) $group_id . '  			AND user_rank <> 0 -			AND user_rank = ' . (int)$row['group_rank'] . ' +			AND user_rank = ' . (int) $row['group_rank'] . '  			AND ' . $db->sql_in_set('user_id', $user_ids);  	$db->sql_query($sql);  } @@ -2872,7 +3007,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, $phpbb_container; +	global $db, $auth, $user, $phpbb_container, $phpbb_log;  	// We need both username and user_id info  	$result = user_get_id_name($user_id_ary, $username_ary); @@ -2943,14 +3078,15 @@ 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); +			/* @var $phpbb_notifications \phpbb\notification\manager */  			$phpbb_notifications = $phpbb_container->get('notification_manager'); -			$phpbb_notifications->add_notifications('group_request_approved', array( +			$phpbb_notifications->add_notifications('notification.type.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); +			$phpbb_notifications->delete_notifications('notification.type.group_request', $user_id_ary, $group_id);  			$log = 'LOG_USERS_APPROVED';  		break; @@ -3006,7 +3142,7 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna  	// Clear permissions cache of relevant users  	$auth->acl_clear_prefetch($user_id_ary); -	add_log('admin', $log, $group_name, implode(', ', $username_ary)); +	$phpbb_log->add('admin', $user->data['user_id'], $user->ip, $log, false, array($group_name, implode(', ', $username_ary)));  	group_update_listings($group_id); @@ -3018,7 +3154,7 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna  */  function group_validate_groupname($group_id, $group_name)  { -	global $config, $db; +	global $db;  	$group_name =  utf8_clean_string($group_name); @@ -3066,7 +3202,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 $phpbb_container, $db, $phpbb_dispatcher; +	global $config, $phpbb_container, $db, $phpbb_dispatcher;  	if (empty($user_id_ary))  	{ @@ -3136,8 +3272,8 @@ function group_set_user_default($group_id, $user_id_ary, $group_attributes = fal  			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) . " @@ -3178,11 +3314,9 @@ function group_set_user_default($group_id, $user_id_ary, $group_attributes = fal  			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); +			$config->set('newest_user_colour', $sql_ary['user_colour'], false);  		}  	} @@ -3198,7 +3332,7 @@ function group_set_user_default($group_id, $user_id_ary, $group_attributes = fal  	* @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 +	* @since 3.1.0-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))); @@ -3217,7 +3351,7 @@ function group_set_user_default($group_id, $user_id_ary, $group_attributes = fal  */  function get_group_name($group_id)  { -	global $db, $user; +	global $db, $phpbb_container;  	$sql = 'SELECT group_name, group_type  		FROM ' . GROUPS_TABLE . ' @@ -3226,12 +3360,15 @@ function get_group_name($group_id)  	$row = $db->sql_fetchrow($result);  	$db->sql_freeresult($result); -	if (!$row || ($row['group_type'] == GROUP_SPECIAL && empty($user->lang))) +	if (!$row)  	{  		return '';  	} -	return ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']; +	/** @var \phpbb\group\helper $group_helper */ +	$group_helper = $phpbb_container->get('group_helper'); + +	return $group_helper->get_name($row['group_name']);  }  /** @@ -3447,9 +3584,12 @@ function remove_newly_registered($user_id, $user_data = false)  *  * @param array $user_ids Array of users' ids to check for banning,  *						leave empty to get complete list of banned ids +* @param bool|int $ban_end Bool True to get users currently banned +* 						Bool False to only get permanently banned users +* 						Int Unix timestamp to get users banned until that time  * @return array	Array of banned users' ids if any, empty array otherwise  */ -function phpbb_get_banned_user_ids($user_ids = array()) +function phpbb_get_banned_user_ids($user_ids = array(), $ban_end = true)  {  	global $db; @@ -3461,9 +3601,26 @@ function phpbb_get_banned_user_ids($user_ids = array())  	$sql = 'SELECT ban_userid  		FROM ' . BANLIST_TABLE . "  		WHERE $sql_user_ids -			AND ban_exclude <> 1 -			AND (ban_end > " . time() . ' +			AND ban_exclude <> 1"; + +	if ($ban_end === true) +	{ +		// Banned currently +		$sql .= " AND (ban_end > " . time() . '  				OR ban_end = 0)'; +	} +	else if ($ban_end === false) +	{ +		// Permanently banned +		$sql .= " AND ban_end = 0"; +	} +	else +	{ +		// Banned until a specified time +		$sql .= " AND (ban_end > " . (int) $ban_end . ' +				OR ban_end = 0)'; +	} +  	$result = $db->sql_query($sql);  	while ($row = $db->sql_fetchrow($result))  	{ @@ -3474,3 +3631,23 @@ function phpbb_get_banned_user_ids($user_ids = array())  	return $banned_ids_list;  } + +/** +* Function for assigning a template var if the zebra module got included +*/ +function phpbb_module_zebra($mode, &$module_row) +{ +	global $template; + +	$template->assign_var('S_ZEBRA_ENABLED', true); + +	if ($mode == 'friends') +	{ +		$template->assign_var('S_ZEBRA_FRIENDS_ENABLED', true); +	} + +	if ($mode == 'foes') +	{ +		$template->assign_var('S_ZEBRA_FOES_ENABLED', true); +	} +} | 
