diff options
37 files changed, 507 insertions, 53 deletions
| diff --git a/phpBB/adm/style/acp_profile.html b/phpBB/adm/style/acp_profile.html index 07718846cc..cebd2e9632 100644 --- a/phpBB/adm/style/acp_profile.html +++ b/phpBB/adm/style/acp_profile.html @@ -127,6 +127,7 @@  			<!-- ENDIF -->  			</dl>  		<!-- ENDIF --> +		<!-- EVENT acp_profile_step_one_lang_after -->  		</fieldset>  		<fieldset class="quick"> diff --git a/phpBB/adm/style/ajax.js b/phpBB/adm/style/ajax.js index 4ad6b6afa5..7ddd2d3742 100644 --- a/phpBB/adm/style/ajax.js +++ b/phpBB/adm/style/ajax.js @@ -62,7 +62,125 @@ phpbb.addAjaxCallback('row_delete', function(res) {  	}  }); +/** + * Handler for submitting permissions form in chunks + * This call will submit permissions forms in chunks of 5 fieldsets. + */ +function submitPermissions() { +	var $form = $('form#set-permissions'), +		fieldsetList = $form.find('fieldset[id^=perm]'), +		formDataSets = [], +		$submitAllButton = $form.find('input[type=submit][name^=action]')[0], +		$submitButton = $form.find('input[type=submit][data-clicked=true]')[0]; + +	// Set proper start values for handling refresh of page +	var permissionSubmitSize = 0, +		permissionRequestCount = 0, +		forumIds = [], +		permissionSubmitFailed = false; + +	if ($submitAllButton !== $submitButton) { +		fieldsetList = $form.find('fieldset#' + $submitButton.closest('fieldset.permissions').id); +	} + +	$.each(fieldsetList, function (key, value) { +		if (key % 5 === 0) { +			formDataSets[Math.floor(key / 5)] = $form.find('fieldset#' + value.id).serialize(); +		} else { +			formDataSets[Math.floor(key / 5)] += '&' + $form.find('fieldset#' + value.id).serialize(); +		} +	}); + +	permissionSubmitSize = formDataSets.length; + +	// Add each forum ID to forum ID list to preserve selected forums +	$.each($form.find('input[type=hidden][name^=forum_id]'), function (key, value) { +		if (value.name.match(/^forum_id\[([0-9]+)\]$/)) { +			forumIds.push(value.value); +		} +	}); + +	/** +	 * Handler for submitted permissions form chunk +	 * +	 * @param {object} res Object returned by AJAX call +	 */ +	function handlePermissionReturn(res) { +		permissionRequestCount++; +		var $dark = $('#darkenwrapper'); + +		if (res.S_USER_WARNING) { +			phpbb.alert(res.MESSAGE_TITLE, res.MESSAGE_TEXT); +			permissionSubmitFailed = true; +		} else if (!permissionSubmitFailed && res.S_USER_NOTICE) { +			// Display success message at the end of submitting the form +			if (permissionRequestCount >= permissionSubmitSize) { +				var $alert = phpbb.alert(res.MESSAGE_TITLE, res.MESSAGE_TEXT); +				var $alertBoxLink = $alert.find('p.alert_text > a'); + +				// Create form to submit instead of normal "Back to previous page" link +				if ($alertBoxLink) { +					// Remove forum_id[] from URL +					$alertBoxLink.attr('href', $alertBoxLink.attr('href').replace(/(&forum_id\[\]=[0-9]+)/g, '')); +					var previousPageForm = '<form action="' + $alertBoxLink.attr('href') + '" method="post">'; +					$.each(forumIds, function (key, value) { +						previousPageForm += '<input type="text" name="forum_id[]" value="' + value + '" />'; +					}); +					previousPageForm += '</form>'; + +					$alertBoxLink.on('click', function (e) { +						var $previousPageForm = $(previousPageForm); +						$('body').append($previousPageForm); +						e.preventDefault(); +						$previousPageForm.submit(); +					}); +				} + +				// Do not allow closing alert +				$dark.off('click'); +				$alert.find('.alert_close').hide(); + +				if (typeof res.REFRESH_DATA !== 'undefined') { +					setTimeout(function () { +						// Create forum to submit using POST. This will prevent +						// exceeding the maximum length of URLs +						var form = '<form action="' + res.REFRESH_DATA.url.replace(/(&forum_id\[\]=[0-9]+)/g, '') + '" method="post">'; +						$.each(forumIds, function (key, value) { +							form += '<input type="text" name="forum_id[]" value="' + value + '" />'; +						}); +						form += '</form>'; +						$form = $(form); +						$('body').append($form); + +						// Hide the alert even if we refresh the page, in case the user +						// presses the back button. +						$dark.fadeOut(phpbb.alertTime, function () { +							if (typeof $alert !== 'undefined') { +								$alert.hide(); +							} +						}); + +						// Submit form +						$form.submit(); +					}, res.REFRESH_DATA.time * 1000); // Server specifies time in seconds +				} +			} +		} +	} +	// Create AJAX request for each form data set +	$.each(formDataSets, function (key, formData) { +		$.ajax({ +			url: $form.action, +			type: 'POST', +			data: formData + '&' + $submitAllButton.name + '=' + encodeURIComponent($submitAllButton.value) + +				'&creation_time=' + $form.find('input[type=hidden][name=creation_time]')[0].value + +				'&form_token=' + $form.find('input[type=hidden][name=form_token]')[0].value, +			success: handlePermissionReturn, +			error: handlePermissionReturn +		}); +	}); +}  $('[data-ajax]').each(function() {  	var $this = $(this), @@ -83,6 +201,18 @@ $('[data-ajax]').each(function() {  */  $(function() {  	phpbb.resizeTextArea($('textarea:not(.no-auto-resize)'), {minHeight: 75}); + +	var $setPermissionsForm = $('form#set-permissions'); +	if ($setPermissionsForm.length) { +		$setPermissionsForm.on('submit', function (e) { +			submitPermissions(); +			e.preventDefault(); +		}); +		$setPermissionsForm.find('input[type=submit]').click(function() { +			$('input[type=submit]', $(this).parents($('form#set-permissions'))).removeAttr('data-clicked'); +			$(this).attr('data-clicked', true); +		}); +	}  }); diff --git a/phpBB/config/auth.yml b/phpBB/config/auth.yml index 88a90ca2d6..ef06080d38 100644 --- a/phpBB/config/auth.yml +++ b/phpBB/config/auth.yml @@ -62,6 +62,7 @@ services:              - @auth.provider.oauth.service_collection              - %tables.users%              - @service_container +            - @dispatcher              - %core.root_path%              - %core.php_ext%          tags: diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html index eb0fb60de2..56b71006c7 100644 --- a/phpBB/docs/coding-guidelines.html +++ b/phpBB/docs/coding-guidelines.html @@ -1123,9 +1123,6 @@ append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group&amp;  	<ul>  		<li> -			<p>Use <code>sizeof</code> instead of <code>count</code></p> -		</li> -		<li>  			<p>Use <code>strpos</code> instead of <code>strstr</code></p>  		</li>  		<li> diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index 0ebaf8f3e0..71f02c3a42 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -369,6 +369,13 @@ acp_profile_contact_before  * Since: 3.1.6-RC1  * Purpose: Add extra options to custom profile field configuration in the ACP +acp_profile_step_one_lang_after +=== +* Locations: +    + adm/style/acp_profile.html +* Since: 3.1.11-RC1 +* Purpose: Add extra lang specific options to custom profile field step one configuration in the ACP +  acp_prune_forums_append  ===  * Locations: @@ -814,6 +821,14 @@ mcp_forum_actions_after  * Since: 3.1.11-RC1  * Purpose: Add some information after actions fieldset +mcp_forum_actions_append +=== +* Locations: +    + styles/prosilver/template/mcp_forum.html +    + styles/subsilver2/template/mcp_forum.html +* Since: 3.1.11-RC1 +* Purpose: Add additional options to actions select +  mcp_forum_actions_before  ===  * Locations: diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index e004d2e81f..c8f6f426c6 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -1017,7 +1017,7 @@ class acp_board  		$user->timezone = $old_tz;  		return "<select name=\"dateoptions\" id=\"dateoptions\" onchange=\"if (this.value == 'custom') { document.getElementById('" . addslashes($key) . "').value = '" . addslashes($value) . "'; } else { document.getElementById('" . addslashes($key) . "').value = this.value; }\">$dateformat_options</select> -		<input type=\"text\" name=\"config[$key]\" id=\"$key\" value=\"$value\" maxlength=\"30\" />"; +		<input type=\"text\" name=\"config[$key]\" id=\"$key\" value=\"$value\" maxlength=\"64\" />";  	}  	/** diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php index f97711d69d..5a2ded91e2 100644 --- a/phpBB/includes/acp/acp_extensions.php +++ b/phpBB/includes/acp/acp_extensions.php @@ -34,7 +34,7 @@ class acp_extensions  	function main()  	{  		// Start the page -		global $config, $user, $template, $request, $phpbb_extension_manager, $db, $phpbb_root_path, $phpEx, $phpbb_log, $cache; +		global $config, $user, $template, $request, $phpbb_extension_manager, $db, $phpbb_root_path, $phpEx, $phpbb_log, $cache, $phpbb_dispatcher;  		$this->db = $db;  		$this->config = $config; @@ -43,6 +43,7 @@ class acp_extensions  		$this->cache = $cache;  		$this->request = $request;  		$this->log = $phpbb_log; +		$this->phpbb_dispatcher = $phpbb_dispatcher;  		$user->add_lang(array('install', 'acp/extensions', 'migrator')); @@ -55,6 +56,21 @@ class acp_extensions  		$safe_time_limit = (ini_get('max_execution_time') / 2);  		$start_time = time(); +		/** +		* Event to run a specific action on extension +		* +		* @event core.acp_extensions_run_action +		* @var	string	action			Action to run +		* @var	string	u_action		Url we are at +		* @var	string	ext_name		Extension name from request +		* @var	int		safe_time_limit	Safe limit of execution time +		* @var	int		start_time		Start time +		* @since 3.1.11-RC1 +		*/ +		$u_action = $this->u_action; +		$vars = array('action', 'u_action', 'ext_name', 'safe_time_limit', 'start_time'); +		extract($this->phpbb_dispatcher->trigger_event('core.acp_extensions_run_action', compact($vars))); +  		// Cancel action  		if ($request->is_set_post('cancel'))  		{ diff --git a/phpBB/includes/acp/acp_permissions.php b/phpBB/includes/acp/acp_permissions.php index 660afb4e93..62e75a2db7 100644 --- a/phpBB/includes/acp/acp_permissions.php +++ b/phpBB/includes/acp/acp_permissions.php @@ -755,6 +755,7 @@ class acp_permissions  		$this->log_action($mode, 'add', $permission_type, $ug_type, $ug_id, $forum_id); +		meta_refresh(5, $this->u_action);  		trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action));  	} @@ -825,10 +826,12 @@ class acp_permissions  		if ($mode == 'setting_forum_local' || $mode == 'setting_mod_local')  		{ +			meta_refresh(5, $this->u_action . '&forum_id[]=' . implode('&forum_id[]=', $forum_ids));  			trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action . '&forum_id[]=' . implode('&forum_id[]=', $forum_ids)));  		}  		else  		{ +			meta_refresh(5, $this->u_action);  			trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action));  		}  	} @@ -899,10 +902,12 @@ class acp_permissions  		if ($mode == 'setting_forum_local' || $mode == 'setting_mod_local')  		{ +			meta_refresh(5, $this->u_action . '&forum_id[]=' . implode('&forum_id[]=', $forum_id));  			trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action . '&forum_id[]=' . implode('&forum_id[]=', $forum_id)));  		}  		else  		{ +			meta_refresh(5, $this->u_action);  			trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action));  		}  	} diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php index 2012d3c513..9e6cc49522 100644 --- a/phpBB/includes/acp/acp_profile.php +++ b/phpBB/includes/acp/acp_profile.php @@ -752,6 +752,10 @@ class acp_profile  				$s_one_need_edit = true;  			} +			if (!isset($this->type_collection[$row['field_type']])) +			{ +				continue; +			}  			$profile_field = $this->type_collection[$row['field_type']];  			$template->assign_block_vars('fields', array(  				'FIELD_IDENT'		=> $row['field_ident'], diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 008cc02471..cd44800af8 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1929,7 +1929,7 @@ class acp_users  					'S_FORM_ENCTYPE'	=> ' enctype="multipart/form-data"', -					'L_AVATAR_EXPLAIN'	=> sprintf($user->lang['AVATAR_EXPLAIN'], $config['avatar_max_width'], $config['avatar_max_height'], $config['avatar_filesize'] / 1024), +					'L_AVATAR_EXPLAIN'	=> $user->lang(($config['avatar_filesize'] == 0) ? 'AVATAR_EXPLAIN_NO_FILESIZE' : 'AVATAR_EXPLAIN', $config['avatar_max_width'], $config['avatar_max_height'], $config['avatar_filesize'] / 1024),  					'S_AVATARS_ENABLED'		=> ($config['allow_avatar'] && $avatars_enabled),  				)); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index a152d9b620..ba448f3125 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -2776,7 +2776,7 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo  	$u_action .= ((strpos($u_action, '?') === false) ? '?' : '&') . 'confirm_key=' . $confirm_key;  	$template->assign_vars(array( -		'MESSAGE_TITLE'		=> (!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang[$title], +		'MESSAGE_TITLE'		=> (!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang($title, 1),  		'MESSAGE_TEXT'		=> (!isset($user->lang[$title . '_CONFIRM'])) ? $title : $user->lang[$title . '_CONFIRM'],  		'YES_VALUE'			=> $user->lang['YES'], diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php index 8e60804d6e..8858d1a307 100644 --- a/phpBB/includes/functions_content.php +++ b/phpBB/includes/functions_content.php @@ -980,7 +980,7 @@ function bbcode_nl2br($text)  */  function smiley_text($text, $force_option = false)  { -	global $config, $user, $phpbb_path_helper; +	global $config, $user, $phpbb_path_helper, $phpbb_dispatcher;  	if ($force_option || !$config['allow_smilies'] || !$user->optionget('viewsmilies'))  	{ @@ -989,6 +989,16 @@ function smiley_text($text, $force_option = false)  	else  	{  		$root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_path_helper->get_web_root_path(); + +		/** +		* Event to override the root_path for smilies +		* +		* @event core.smiley_text_root_path +		* @var string root_path root_path for smilies +		* @since 3.1.11-RC1 +		*/ +		$vars = array('root_path'); +		extract($phpbb_dispatcher->trigger_event('core.smiley_text_root_path', compact($vars)));  		return preg_replace('#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/(.*?) \/><!\-\- s\1 \-\->#', '<img class="smilies" src="' . $root_path . $config['smilies_path'] . '/\2 />', $text);  	}  } diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php index c571de579e..86c60c31ff 100644 --- a/phpBB/includes/functions_download.php +++ b/phpBB/includes/functions_download.php @@ -677,6 +677,8 @@ function phpbb_download_handle_forum_auth($db, $auth, $topic_id)  */  function phpbb_download_handle_pm_auth($db, $auth, $user_id, $msg_id)  { +	global $phpbb_dispatcher; +  	if (!$auth->acl_get('u_pm_download'))  	{  		send_status_line(403, 'Forbidden'); @@ -685,6 +687,18 @@ function phpbb_download_handle_pm_auth($db, $auth, $user_id, $msg_id)  	$allowed = phpbb_download_check_pm_auth($db, $user_id, $msg_id); +	/** +	* Event to modify PM attachments download auth +	* +	* @event core.modify_pm_attach_download_auth +	* @var	bool	allowed		Whether the user is allowed to download from that PM or not +	* @var	int		msg_id		The id of the PM to download from +	* @var	int		user_id		The user id for auth check +	* @since 3.1.11-RC1 +	*/ +	$vars = array('allowed', 'msg_id', 'user_id'); +	extract($phpbb_dispatcher->trigger_event('core.modify_pm_attach_download_auth', compact($vars))); +  	if (!$allowed)  	{  		send_status_line(403, 'Forbidden'); diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index 9b3ca14101..f141637fb9 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -438,7 +438,7 @@ class messenger  	*/  	function build_header($to, $cc, $bcc)  	{ -		global $config; +		global $config, $phpbb_dispatcher;  		// We could use keys here, but we won't do this for 3.0.x to retain backwards compatibility  		$headers = array(); @@ -470,6 +470,16 @@ class messenger  		$headers[] = 'X-MimeOLE: phpBB3';  		$headers[] = 'X-phpBB-Origin: phpbb://' . str_replace(array('http://', 'https://'), array('', ''), generate_board_url()); +		/** +		* Event to modify email header entries +		* +		* @event core.modify_email_headers +		* @var	array	headers	Array containing email header entries +		* @since 3.1.11-RC1 +		*/ +		$vars = array('headers'); +		extract($phpbb_dispatcher->trigger_event('core.modify_email_headers', compact($vars))); +  		if (sizeof($this->extra_headers))  		{  			$headers = array_merge($headers, $this->extra_headers); diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 4a4d2de0fe..30f5ba91ef 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -119,6 +119,15 @@ function generate_smilies($mode, $forum_id)  		foreach ($smilies as $row)  		{ +			/** +			* Modify smiley root path before populating smiley list +			* +			* @event core.generate_smilies_before +			* @var string  root_path root_path for smilies +			* @since 3.1.11-RC1 +			*/ +			$vars = array('root_path'); +			extract($phpbb_dispatcher->trigger_event('core.generate_smilies_before', compact($vars)));  			$template->assign_block_vars('smiley', array(  				'SMILEY_CODE'	=> $row['code'],  				'A_SMILEY_CODE'	=> addslashes($row['code']), diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 1639eb1a4c..4aad1746d5 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -889,9 +889,16 @@ function update_unread_status($unread, $msg_id, $user_id, $folder_id)  		SET pm_unread = 0  		WHERE msg_id = $msg_id  			AND user_id = $user_id -			AND folder_id = $folder_id"; +			AND folder_id = $folder_id +			AND pm_unread = 1";  	$db->sql_query($sql); +	// If the message is already marked as read, we just skip the rest to avoid negative PM count +	if (!$db->sql_affectedrows()) +	{ +		return; +	} +  	$sql = 'UPDATE ' . USERS_TABLE . "  		SET user_unread_privmsg = user_unread_privmsg - 1  		WHERE user_id = $user_id"; diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index b82abe0c5e..0b39339c7f 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -2279,7 +2279,7 @@ function phpbb_avatar_explanation_string()  {  	global $config, $user; -	return $user->lang('AVATAR_EXPLAIN', +	return $user->lang(($config['avatar_filesize'] == 0) ? 'AVATAR_EXPLAIN_NO_FILESIZE' : 'AVATAR_EXPLAIN',  		$user->lang('PIXELS', (int) $config['avatar_max_width']),  		$user->lang('PIXELS', (int) $config['avatar_max_height']),  		round($config['avatar_filesize'] / 1024)); diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index b2441aed1b..599bd5d918 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -463,7 +463,7 @@ function change_topic_type($action, $topic_ids)  */  function mcp_move_topic($topic_ids)  { -	global $auth, $user, $db, $template, $phpbb_log, $request; +	global $auth, $user, $db, $template, $phpbb_log, $request, $phpbb_dispatcher;  	global $phpEx, $phpbb_root_path;  	// Here we limit the operation to one forum only @@ -625,6 +625,18 @@ function mcp_move_topic($topic_ids)  					'poll_last_vote'		=>	(int) $row['poll_last_vote']  				); +				/** +				* Perform actions before shadow topic is created. +				* +				* @event core.mcp_main_modify_shadow_sql +				* @var	array	shadow	SQL array to be used by $db->sql_build_array +				* @since 3.1.11-RC1 +				*/ +				$vars = array( +					'shadow', +				); +				extract($phpbb_dispatcher->trigger_event('core.mcp_main_modify_shadow_sql', compact($vars))); +  				$db->sql_query('INSERT INTO ' . TOPICS_TABLE . $db->sql_build_array('INSERT', $shadow));  				// Shadow topics only count on new "topics" and not posts... a shadow topic alone has 0 posts @@ -1281,6 +1293,18 @@ function mcp_fork_topic($topic_ids)  				'poll_vote_change'			=> (int) $topic_row['poll_vote_change'],  			); +			/** +			* Perform actions before forked topic is created. +			* +			* @event core.mcp_main_modify_fork_sql +			* @var	array	sql_ary	SQL array to be used by $db->sql_build_array +			* @since 3.1.11-RC1 +			*/ +			$vars = array( +				'sql_ary', +			); +			extract($phpbb_dispatcher->trigger_event('core.mcp_main_modify_fork_sql', compact($vars))); +  			$db->sql_query('INSERT INTO ' . TOPICS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));  			$new_topic_id = $db->sql_nextid();  			$new_topic_id_list[$topic_id] = $new_topic_id; diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 59525c6b16..93ee07b1cf 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -100,6 +100,7 @@ $lang = array_merge($lang, array(  	'AVATAR_DRIVER_UPLOAD_TITLE'	=> 'Upload avatar',  	'AVATAR_DRIVER_UPLOAD_EXPLAIN'	=> 'Upload your own custom avatar.',  	'AVATAR_EXPLAIN'				=> 'Maximum dimensions; width: %1$s, height: %2$s, file size: %3$.2f KiB.', +	'AVATAR_EXPLAIN_NO_FILESIZE'	=> 'Maximum dimensions; width: %1$s, height: %2$s.',  	'AVATAR_FEATURES_DISABLED'		=> 'The avatar functionality is currently disabled.',  	'AVATAR_GALLERY'				=> 'Local gallery',  	'AVATAR_GENERAL_UPLOAD_ERROR'	=> 'Could not upload avatar to %s.', diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php index 9f6345fbba..bd2a414033 100644 --- a/phpBB/phpbb/auth/provider/oauth/oauth.php +++ b/phpBB/phpbb/auth/provider/oauth/oauth.php @@ -98,6 +98,13 @@ class oauth extends \phpbb\auth\provider\base  	protected $phpbb_container;  	/** +	* phpBB event dispatcher +	* +	* @var \phpbb\event\dispatcher_interface +	*/ +	protected $dispatcher; + +	/**  	* phpBB root path  	*  	* @var string @@ -124,10 +131,11 @@ class oauth extends \phpbb\auth\provider\base  	* @param	\phpbb\di\service_collection	$service_providers Contains \phpbb\auth\provider\oauth\service_interface  	* @param	string			$users_table  	* @param	\Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container DI container +	* @param	\phpbb\event\dispatcher_interface $dispatcher phpBB event dispatcher  	* @param	string			$phpbb_root_path  	* @param	string			$php_ext  	*/ -	public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, $phpbb_root_path, $php_ext) +	public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, \phpbb\event\dispatcher_interface $dispatcher, $phpbb_root_path, $php_ext)  	{  		$this->db = $db;  		$this->config = $config; @@ -139,6 +147,7 @@ class oauth extends \phpbb\auth\provider\base  		$this->service_providers = $service_providers;  		$this->users_table = $users_table;  		$this->phpbb_container = $phpbb_container; +		$this->dispatcher = $dispatcher;  		$this->phpbb_root_path = $phpbb_root_path;  		$this->php_ext = $php_ext;  	} @@ -238,6 +247,18 @@ class oauth extends \phpbb\auth\provider\base  			// Update token storage to store the user_id  			$storage->set_user_id($row['user_id']); +			/** +			* Event is triggered after user is successfuly logged in via OAuth. +			* +			* @event core.auth_oauth_login_after +			* @var    array    row    User row +			* @since 3.1.11-RC1 +			*/ +			$vars = array( +				'row', +			); +			extract($this->dispatcher->trigger_event('core.auth_oauth_login_after', compact($vars))); +  			// The user is now authenticated and can be logged in  			return array(  				'status'		=> LOGIN_SUCCESS, @@ -542,6 +563,18 @@ class oauth extends \phpbb\auth\provider\base  		$sql = 'INSERT INTO ' . $this->auth_provider_oauth_token_account_assoc . '  			' . $this->db->sql_build_array('INSERT', $data);  		$this->db->sql_query($sql); + +		/** +		 * Event is triggered after user links account. +		 * +		 * @event core.auth_oauth_link_after +		 * @var    array    data    User row +		 * @since 3.1.11-RC1 +		 */ +		$vars = array( +			'data', +		); +		extract($this->dispatcher->trigger_event('core.auth_oauth_link_after', compact($vars)));  	}  	/** diff --git a/phpBB/phpbb/db/migration/data/v31x/remove_duplicate_migrations.php b/phpBB/phpbb/db/migration/data/v31x/remove_duplicate_migrations.php new file mode 100644 index 0000000000..417d569a09 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/remove_duplicate_migrations.php @@ -0,0 +1,77 @@ +<?php + +/** + * + * 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. + * + */ + +namespace phpbb\db\migration\data\v31x; + +class remove_duplicate_migrations extends \phpbb\db\migration\migration +{ +	static public function depends_on() +	{ +		return array('\phpbb\db\migration\data\v31x\v3110'); +	} + +	public function update_data() +	{ +		return array( +			array('custom', array(array($this, 'deduplicate_entries'))), +		); +	} + +	public function deduplicate_entries() +	{ +		$migration_state = array(); +		$duplicate_migrations = array(); + +		$sql = "SELECT * +			FROM " . $this->table_prefix . 'migrations'; +		$result = $this->db->sql_query($sql); + +		if (!$this->db->get_sql_error_triggered()) +		{ +			while ($migration = $this->db->sql_fetchrow($result)) +			{ +				$migration_state[$migration['migration_name']] = $migration; + +				$migration_state[$migration['migration_name']]['migration_depends_on'] = unserialize($migration['migration_depends_on']); +			} +		} + +		$this->db->sql_freeresult($result); + +		foreach ($migration_state as $name => $migration) +		{ +			$prepended_name = ($name[0] == '\\' ? '' : '\\') . $name; +			$prefixless_name = $name[0] == '\\' ? substr($name, 1) : $name; + +			if ($prepended_name != $name && isset($migration_state[$prepended_name]) && $migration_state[$prepended_name]['migration_depends_on'] == $migration_state[$name]['migration_depends_on']) +			{ +				$duplicate_migrations[] = $name; +				unset($migration_state[$prepended_name]); +			} +			else if ($prefixless_name != $name && isset($migration_state[$prefixless_name]) && $migration_state[$prefixless_name]['migration_depends_on'] == $migration_state[$name]['migration_depends_on']) +			{ +				$duplicate_migrations[] = $prefixless_name; +				unset($migration_state[$prefixless_name]); +			} +		} + +		if (count($duplicate_migrations)) +		{ +			$sql = 'DELETE +				FROM ' . $this->table_prefix . 'migrations +				WHERE '  . $this->db->sql_in_set('migration_name', $duplicate_migrations); +			$this->db->sql_query($sql); +		} +	} +} diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index 4c4c0a8672..45a333ac94 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -201,6 +201,34 @@ class migrator  	}  	/** +	 * Get a valid migration name from the migration state array in case the +	 * supplied name is not in the migration state list. +	 * +	 * @param string $name Migration name +	 * @return string Migration name +	 */ +	protected function get_valid_name($name) +	{ +		// Try falling back to a valid migration name with or without leading backslash +		if (!isset($this->migration_state[$name])) +		{ +			$prepended_name = ($name[0] == '\\' ? '' : '\\') . $name; +			$prefixless_name = $name[0] == '\\' ? substr($name, 1) : $name; + +			if (isset($this->migration_state[$prepended_name])) +			{ +				$name = $prepended_name; +			} +			else if (isset($this->migration_state[$prefixless_name])) +			{ +				$name = $prefixless_name; +			} +		} + +		return $name; +	} + +	/**  	 * Effectively runs a single update step from the next migration to be applied.  	 *  	 * @return null @@ -209,6 +237,8 @@ class migrator  	{  		foreach ($this->migrations as $name)  		{ +			$name = $this->get_valid_name($name); +  			if (!isset($this->migration_state[$name]) ||  				!$this->migration_state[$name]['migration_schema_done'] ||  				!$this->migration_state[$name]['migration_data_done']) @@ -264,6 +294,9 @@ class migrator  		foreach ($state['migration_depends_on'] as $depend)  		{ +			$depend = $this->get_valid_name($depend); + +			// Test all possible namings before throwing exception  			if ($this->unfulfillable($depend) !== false)  			{  				throw new \phpbb\db\migration\exception('MIGRATION_NOT_FULFILLABLE', $name, $depend); @@ -742,6 +775,8 @@ class migrator  	*/  	public function unfulfillable($name)  	{ +		$name = $this->get_valid_name($name); +  		if (isset($this->migration_state[$name]) || isset($this->fulfillable_migrations[$name]))  		{  			return false; @@ -757,6 +792,7 @@ class migrator  		foreach ($depends as $depend)  		{ +			$depend = $this->get_valid_name($depend);  			$unfulfillable = $this->unfulfillable($depend);  			if ($unfulfillable !== false)  			{ diff --git a/phpBB/phpbb/event/kernel_exception_subscriber.php b/phpBB/phpbb/event/kernel_exception_subscriber.php index 9d15f9370e..1ee771cfe7 100644 --- a/phpBB/phpbb/event/kernel_exception_subscriber.php +++ b/phpBB/phpbb/event/kernel_exception_subscriber.php @@ -61,7 +61,7 @@ class kernel_exception_subscriber implements EventSubscriberInterface  		$exception = $event->getException();  		$message = $exception->getMessage(); -		$this->type_caster->set_var($message, $message, 'string', false, false); +		$this->type_caster->set_var($message, $message, 'string', true, false);  		if ($exception instanceof \phpbb\exception\exception_interface)  		{ diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php index 094ff78abe..8f199cd931 100644 --- a/phpBB/phpbb/log/log.php +++ b/phpBB/phpbb/log/log.php @@ -893,9 +893,29 @@ class log implements \phpbb\log\log_interface  		$forum_auth = array('f_read' => array(), 'm_' => array());  		$topic_ids = array_unique($topic_ids); -		$sql = 'SELECT topic_id, forum_id -			FROM ' . TOPICS_TABLE . ' -			WHERE ' . $this->db->sql_in_set('topic_id', array_map('intval', $topic_ids)); +		$sql_ary = array( +			'SELECT'	=> 'topic_id, forum_id', +			'FROM'		=> array( +				TOPICS_TABLE	=> 't', +			), +			'WHERE'		=> $this->db->sql_in_set('topic_id', array_map('intval', $topic_ids)), +		); + +		/** +		* Allow modifying SQL query before topic data is retrieved. +		* +		* @event core.phpbb_log_get_topic_auth_sql_before +		* @var	array	topic_ids	Array with unique topic IDs +		* @var	array	sql_ary		SQL array +		* @since 3.1.11-RC1 +		*/ +		$vars = array( +			'topic_ids', +			'sql_ary', +		); +		extract($this->dispatcher->trigger_event('core.phpbb_log_get_topic_auth_sql_before', compact($vars))); + +		$sql = $this->db->sql_build_query('SELECT', $sql_ary);  		$result = $this->db->sql_query($sql);  		while ($row = $this->db->sql_fetchrow($result)) diff --git a/phpBB/phpbb/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php index cc32984ac6..fc39623c5c 100644 --- a/phpBB/phpbb/notification/type/report_pm.php +++ b/phpBB/phpbb/notification/type/report_pm.php @@ -141,6 +141,8 @@ class report_pm extends \phpbb\notification\type\pm  	*/  	public function get_email_template_variables()  	{ +		$user_data = $this->user_loader->get_user($this->get_data('reporter_id')); +  		return array(  			'AUTHOR_NAME'				=> htmlspecialchars_decode($user_data['username']),  			'SUBJECT'					=> htmlspecialchars_decode(censor_text($this->get_data('message_subject'))), diff --git a/phpBB/phpbb/profilefields/type/type_interface.php b/phpBB/phpbb/profilefields/type/type_interface.php index ec770f9467..93b9e4b893 100644 --- a/phpBB/phpbb/profilefields/type/type_interface.php +++ b/phpBB/phpbb/profilefields/type/type_interface.php @@ -134,6 +134,14 @@ interface type_interface  	public function get_field_ident($field_data);  	/** +	* Get the localized name of the field +	* +	* @param string $field_name		Unlocalized name of this field +	* @return string 	Localized name of the field +	*/ +	public function get_field_name($field_name); + +	/**  	* Get the column type for the database  	*  	* @return string	Returns the database column type diff --git a/phpBB/phpbb/profilefields/type/type_string.php b/phpBB/phpbb/profilefields/type/type_string.php index a8432eaae5..8710c8c603 100644 --- a/phpBB/phpbb/profilefields/type/type_string.php +++ b/phpBB/phpbb/profilefields/type/type_string.php @@ -63,7 +63,7 @@ class type_string extends type_string_common  		$options = array(  			0 => array('TITLE' => $this->user->lang['FIELD_LENGTH'],		'FIELD' => '<input type="number" min="0" max="99999" name="field_length" value="' . $field_data['field_length'] . '" />'),  			1 => array('TITLE' => $this->user->lang['MIN_FIELD_CHARS'],	'FIELD' => '<input type="number" min="0" max="99999" name="field_minlen" value="' . $field_data['field_minlen'] . '" />'), -			2 => array('TITLE' => $this->user->lang['MAX_FIELD_CHARS'],	'FIELD' => '<input type="number" min="0 max="99999"" name="field_maxlen" value="' . $field_data['field_maxlen'] . '" />'), +			2 => array('TITLE' => $this->user->lang['MAX_FIELD_CHARS'],	'FIELD' => '<input type="number" min="0" max="99999" name="field_maxlen" value="' . $field_data['field_maxlen'] . '" />'),  			3 => array('TITLE' => $this->user->lang['FIELD_VALIDATION'],	'FIELD' => '<select name="field_validation">' . $this->validate_options($field_data) . '</select>'),  		); diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index 311da92a95..ec9b53328f 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -132,9 +132,10 @@ phpbb.markNotifications = function($popup, unreadCount) {  	// Update the unread count.  	$('strong', '#notification_list_button').html(unreadCount); -	// Remove the Mark all read link & notification count if there are no unread notifications. +	// Remove the Mark all read link and hide notification count if there are no unread notifications.  	if (!unreadCount) { -		$('#mark_all_notifications, #notification_list_button > strong').remove(); +		$('#mark_all_notifications').remove(); +		$('#notification_list_button > strong').addClass('hidden');  	}  	// Update page title diff --git a/phpBB/styles/prosilver/template/jumpbox.html b/phpBB/styles/prosilver/template/jumpbox.html index 3096d08318..fcd8ddbc1e 100644 --- a/phpBB/styles/prosilver/template/jumpbox.html +++ b/phpBB/styles/prosilver/template/jumpbox.html @@ -1,32 +1,34 @@ -<!-- IF S_VIEWTOPIC --> -	<p class="jumpbox-return"><a href="{U_VIEW_FORUM}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" accesskey="r">{L_RETURN_TO_FORUM}</a></p> -<!-- ELSEIF S_VIEWFORUM --> -	<p class="jumpbox-return"><a href="{U_INDEX}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" accesskey="r">{L_RETURN_TO_INDEX}</a></p> -<!-- ELSEIF SEARCH_TOPIC --> -	<p class="jumpbox-return"><a class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH_TOPIC}" accesskey="r">{L_RETURN_TO_TOPIC}</a></p> -<!-- ELSEIF S_SEARCH_ACTION --> -	<p class="jumpbox-return"><a class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH}" title="{L_SEARCH_ADV}" accesskey="r">{L_GO_TO_SEARCH_ADV}</a></p> -<!-- ENDIF --> +<div class="action-bar actions-jump"> +	<!-- IF S_VIEWTOPIC --> +		<p class="jumpbox-return"><a href="{U_VIEW_FORUM}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" accesskey="r">{L_RETURN_TO_FORUM}</a></p> +	<!-- ELSEIF S_VIEWFORUM --> +		<p class="jumpbox-return"><a href="{U_INDEX}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" accesskey="r">{L_RETURN_TO_INDEX}</a></p> +	<!-- ELSEIF SEARCH_TOPIC --> +		<p class="jumpbox-return"><a class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH_TOPIC}" accesskey="r">{L_RETURN_TO_TOPIC}</a></p> +	<!-- ELSEIF S_SEARCH_ACTION --> +		<p class="jumpbox-return"><a class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH}" title="{L_SEARCH_ADV}" accesskey="r">{L_GO_TO_SEARCH_ADV}</a></p> +	<!-- ENDIF --> -<!-- IF S_DISPLAY_JUMPBOX --> +	<!-- IF S_DISPLAY_JUMPBOX --> -	<div class="dropdown-container dropdown-container-{S_CONTENT_FLOW_END}<!-- IF not S_IN_MCP --> dropdown-up<!-- ENDIF --> dropdown-{S_CONTENT_FLOW_BEGIN} dropdown-button-control" id="jumpbox"> -		<span title="<!-- IF S_IN_MCP and S_MERGE_SELECT -->{L_SELECT_TOPICS_FROM}<!-- ELSEIF S_IN_MCP -->{L_MODERATE_FORUM}<!-- ELSE -->{L_JUMP_TO}<!-- ENDIF -->" class="dropdown-trigger button dropdown-select"> -			<!-- IF S_IN_MCP and S_MERGE_SELECT -->{L_SELECT_TOPICS_FROM}<!-- ELSEIF S_IN_MCP -->{L_MODERATE_FORUM}<!-- ELSE -->{L_JUMP_TO}<!-- ENDIF --> -		</span> -		<div class="dropdown hidden"> -			<div class="pointer"><div class="pointer-inner"></div></div> -			<ul class="dropdown-contents"> -			<!-- BEGIN jumpbox_forums --> -				<!-- IF jumpbox_forums.FORUM_ID neq -1 --> -					<li><!-- BEGIN level -->   <!-- END level --><a href="{jumpbox_forums.LINK}">{jumpbox_forums.FORUM_NAME}</a></li> -				<!-- ENDIF --> -			<!-- END jumpbox_forums --> -			</ul> +		<div class="dropdown-container dropdown-container-{S_CONTENT_FLOW_END}<!-- IF not S_IN_MCP --> dropdown-up<!-- ENDIF --> dropdown-{S_CONTENT_FLOW_BEGIN} dropdown-button-control" id="jumpbox"> +			<span title="<!-- IF S_IN_MCP and S_MERGE_SELECT -->{L_SELECT_TOPICS_FROM}<!-- ELSEIF S_IN_MCP -->{L_MODERATE_FORUM}<!-- ELSE -->{L_JUMP_TO}<!-- ENDIF -->" class="dropdown-trigger button dropdown-select"> +				<!-- IF S_IN_MCP and S_MERGE_SELECT -->{L_SELECT_TOPICS_FROM}<!-- ELSEIF S_IN_MCP -->{L_MODERATE_FORUM}<!-- ELSE -->{L_JUMP_TO}<!-- ENDIF --> +			</span> +			<div class="dropdown hidden"> +				<div class="pointer"><div class="pointer-inner"></div></div> +				<ul class="dropdown-contents"> +				<!-- BEGIN jumpbox_forums --> +					<!-- IF jumpbox_forums.FORUM_ID neq -1 --> +						<li><!-- BEGIN level -->   <!-- END level --><a href="{jumpbox_forums.LINK}">{jumpbox_forums.FORUM_NAME}</a></li> +					<!-- ENDIF --> +				<!-- END jumpbox_forums --> +				</ul> +			</div>  		</div> -	</div> -<!-- ELSE --> -	<br /><br /> -<!-- ENDIF --> +	<!-- ELSE --> +	</br></br> +	<!-- ENDIF --> +</div> diff --git a/phpBB/styles/prosilver/template/mcp_forum.html b/phpBB/styles/prosilver/template/mcp_forum.html index 5858a2c801..4c037f56ae 100644 --- a/phpBB/styles/prosilver/template/mcp_forum.html +++ b/phpBB/styles/prosilver/template/mcp_forum.html @@ -138,6 +138,7 @@  			<option value="make_announce">{L_MAKE_ANNOUNCE}</option>  			<option value="make_global">{L_MAKE_GLOBAL}</option>  		<!-- ENDIF --> +		<!-- EVENT mcp_forum_actions_append -->  	</select>  	<input class="button2" type="submit" value="{L_SUBMIT}" />  	<div><a href="#" onclick="marklist('mcp', 'topic_id_list', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('mcp', 'topic_id_list', false); return false;">{L_UNMARK_ALL}</a></div> diff --git a/phpBB/styles/prosilver/template/navbar_header.html b/phpBB/styles/prosilver/template/navbar_header.html index e5f354a943..bdfb5fb87d 100644 --- a/phpBB/styles/prosilver/template/navbar_header.html +++ b/phpBB/styles/prosilver/template/navbar_header.html @@ -72,12 +72,12 @@  		</li>  		<!-- IF S_DISPLAY_PM -->  			<li class="small-icon icon-pm rightside" data-skip-responsive="true"> -				<a href="{U_PRIVATEMSGS}" role="menuitem"><span>{L_PRIVATE_MESSAGES} </span><!-- IF PRIVATE_MESSAGE_COUNT --><strong class="badge">{PRIVATE_MESSAGE_COUNT}</strong><!-- ENDIF --></a> +				<a href="{U_PRIVATEMSGS}" role="menuitem"><span>{L_PRIVATE_MESSAGES} </span><strong class="badge<!-- IF not PRIVATE_MESSAGE_COUNT --> hidden<!-- ENDIF -->">{PRIVATE_MESSAGE_COUNT}</strong></a>  			</li>  		<!-- ENDIF -->  		<!-- IF S_NOTIFICATIONS_DISPLAY -->  			<li class="small-icon icon-notification dropdown-container dropdown-{S_CONTENT_FLOW_END} rightside" data-skip-responsive="true"> -				<a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification_list_button" class="dropdown-trigger"><span>{L_NOTIFICATIONS} </span><!-- IF NOTIFICATIONS_COUNT --><strong class="badge">{NOTIFICATIONS_COUNT}</strong><!-- ENDIF --></a> +				<a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification_list_button" class="dropdown-trigger"><span>{L_NOTIFICATIONS} </span><strong class="badge<!-- IF not NOTIFICATIONS_COUNT --> hidden<!-- ENDIF -->">{NOTIFICATIONS_COUNT}</strong></a>  				<!-- INCLUDE notification_dropdown.html -->  			</li>  		<!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/posting_attach_body.html b/phpBB/styles/prosilver/template/posting_attach_body.html index 81b2c2bf41..d7922297a7 100644 --- a/phpBB/styles/prosilver/template/posting_attach_body.html +++ b/phpBB/styles/prosilver/template/posting_attach_body.html @@ -7,7 +7,7 @@  	<dl>  		<dt><label for="fileupload">{L_FILENAME}{L_COLON}</label></dt>  		<dd> -			<input type="file" name="fileupload" id="fileupload" maxlength="{FILESIZE}" value="" class="inputbox autowidth" />  +			<input type="file" name="fileupload" id="fileupload" class="inputbox autowidth" />  			<input type="submit" name="add_file" value="{L_ADD_FILE}" class="button2" onclick="upload = true;" />  		</dd>  	</dl> diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 9c2f33f7a9..0ac7a45a23 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -137,7 +137,9 @@ p.right {  }  p.jumpbox-return { -	margin-top: 1em; +	margin-top: 10px; +	margin-bottom: 0; +	float: left;  }  b, strong { @@ -1267,6 +1269,10 @@ ul.linklist:after,  	padding: 4px 6px;  } +.badge.hidden { +	display: none; +} +  /* Navbar specific list items  ----------------------------------------*/ diff --git a/phpBB/styles/subsilver2/template/mcp_forum.html b/phpBB/styles/subsilver2/template/mcp_forum.html index d905910c22..12447b2b1e 100644 --- a/phpBB/styles/subsilver2/template/mcp_forum.html +++ b/phpBB/styles/subsilver2/template/mcp_forum.html @@ -77,6 +77,7 @@  				<option value="make_announce">{L_MAKE_ANNOUNCE}</option>  				<option value="make_global">{L_MAKE_GLOBAL}</option>  			<!-- ENDIF --> +			<!-- EVENT mcp_forum_actions_append -->  		</select>  		<input class="btnmain" type="submit" value="{L_SUBMIT}" />  	</td> diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 780e43e09b..dc656b8fad 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -495,6 +495,28 @@ if ($config['allow_topic_notify'])  	}  } +/** +* Event to modify highlight. +* +* @event core.viewtopic_highlight_modify +* @var	string	highlight			String to be highlighted +* @var	string	highlight_match		Highlight string to be used in preg_replace +* @var	array	topic_data			Topic data +* @var	int		start				Pagination start +* @var	int		total_posts			Number of posts +* @var	string	viewtopic_url		Current viewtopic URL +* @since 3.1.11-RC1 +*/ +$vars = array( +	'highlight', +	'highlight_match', +	'topic_data', +	'start', +	'total_posts', +	'viewtopic_url', +); +extract($phpbb_dispatcher->trigger_event('core.viewtopic_highlight_modify', compact($vars))); +  // Bookmarks  if ($config['allow_bookmarks'] && $user->data['is_registered'] && request_var('bookmark', 0))  { @@ -1294,7 +1316,6 @@ while ($row = $db->sql_fetchrow($result))  				'rank_title'		=> '',  				'rank_image'		=> '',  				'rank_image_src'	=> '', -				'sig'				=> '',  				'pm'				=> '',  				'email'				=> '',  				'jabber'			=> '', diff --git a/tests/functional/notification_test.php b/tests/functional/notification_test.php index d4c61cc062..f21d73817a 100644 --- a/tests/functional/notification_test.php +++ b/tests/functional/notification_test.php @@ -82,6 +82,7 @@ class phpbb_functional_notification_test extends phpbb_functional_test_case  		// Get form token  		$link = $crawler->selectLink($this->lang('NOTIFICATIONS_MARK_ALL_READ'))->link()->getUri();  		$crawler = self::request('GET', substr($link, strpos($link, 'ucp.'))); -		$this->assertCount(0, $crawler->filter('#notification_list_button strong')); +		$this->assertCount(1, $crawler->filter('#notification_list_button strong.badge.hidden')); +		$this->assertEquals("0", $crawler->filter('#notification_list_button strong.badge.hidden')->text());  	}  } diff --git a/tests/functions/user_delete_test.php b/tests/functions/user_delete_test.php index db52dcded7..c224323273 100644 --- a/tests/functions/user_delete_test.php +++ b/tests/functions/user_delete_test.php @@ -71,6 +71,7 @@ class phpbb_functions_user_delete_test extends phpbb_database_test_case  			$oauth_provider_collection,  			'phpbb_users',  			$phpbb_container, +			$phpbb_dispatcher,  			$this->phpbb_root_path,  			$this->php_ext  		); | 
